• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

worktile / slate-angular / 62ba9eda-73c7-4559-9959-adfb60d29862

03 Dec 2025 03:19AM UTC coverage: 46.809% (-0.4%) from 47.176%
62ba9eda-73c7-4559-9959-adfb60d29862

push

circleci

pubuzhixing8
fix: unit testing

369 of 997 branches covered (37.01%)

Branch coverage included in aggregate %.

1010 of 1949 relevant lines covered (51.82%)

32.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.19
/packages/src/view/render/utils.ts
1
import { Descendant } from 'slate';
2
import { ComponentRef, EmbeddedViewRef, ViewContainerRef } from '@angular/core';
3
import { ViewType } from '../../types/view';
4
import { isComponentType, isFlavourType, isTemplateRef } from '../../utils/view';
5
import { SlateElementContext, SlateLeafContext, SlateTextContext, SlateViewContext } from '../context';
6
import { BlockCardRef, FlavourRef } from '../flavour/ref';
7

8
export function createEmbeddedViewOrComponentOrFlavour(
9
    viewType: ViewType,
10
    context: any,
11
    viewContext: SlateViewContext,
12
    viewContainerRef: ViewContainerRef
13
) {
14
    if (isFlavourType(viewType)) {
497✔
15
        const flavourRef = new FlavourRef();
495✔
16
        flavourRef.instance = new (viewType as any)();
495✔
17
        flavourRef.instance.context = context;
495✔
18
        flavourRef.instance.viewContext = viewContext;
495✔
19
        flavourRef.instance.viewContainerRef = viewContainerRef;
495✔
20
        flavourRef.instance.onInit();
495✔
21
        return flavourRef;
495✔
22
    }
23
    if (isTemplateRef(viewType)) {
2!
24
        const embeddedViewContext = {
×
25
            context,
26
            viewContext
27
        };
28
        const embeddedViewRef = viewContainerRef.createEmbeddedView<any>(viewType, embeddedViewContext);
×
29
        embeddedViewRef.detectChanges();
×
30
        return embeddedViewRef;
×
31
    }
32
    if (isComponentType(viewType)) {
2✔
33
        const componentRef = viewContainerRef.createComponent(viewType, {
2✔
34
            injector: viewContainerRef.injector
35
        }) as ComponentRef<any>;
36
        componentRef.instance.viewContext = viewContext;
2✔
37
        componentRef.instance.context = context;
2✔
38
        componentRef.changeDetectorRef.detectChanges();
2✔
39
        return componentRef;
2✔
40
    }
41
}
42

43
export function updateContext(
44
    view: EmbeddedViewRef<any> | ComponentRef<any> | FlavourRef,
45
    newContext: SlateElementContext | SlateTextContext | SlateLeafContext,
46
    viewContext: SlateViewContext
47
) {
48
    if (view instanceof FlavourRef) {
32✔
49
        view.instance.context = newContext;
31✔
50
        return;
31✔
51
    }
52
    if (view instanceof ComponentRef) {
1!
53
        view.instance.context = newContext;
1✔
54
    } else {
55
        view.context.context = newContext;
×
56
        view.context.viewContext = viewContext;
×
57
        view.detectChanges();
×
58
    }
59
}
60

61
export function mount(
62
    views: (EmbeddedViewRef<any> | ComponentRef<any> | FlavourRef)[],
63
    blockCards: (BlockCardRef | null)[] | null,
64
    outletParent: HTMLElement,
65
    outletElement: HTMLElement | null
66
) {
67
    if (views.length > 0) {
368✔
68
        const fragment = document.createDocumentFragment();
368✔
69
        views.forEach((view, index) => {
368✔
70
            const blockCard = blockCards ? blockCards[index] : undefined;
488✔
71
            fragment.append(...getRootNodes(view, blockCard));
488✔
72
        });
73
        if (outletElement) {
368✔
74
            outletElement.parentElement.insertBefore(fragment, outletElement);
2✔
75
            outletElement.remove();
2✔
76
        } else {
77
            outletParent.prepend(fragment);
366✔
78
        }
79
    }
80
}
81

82
export function getRootNodes(ref: EmbeddedViewRef<any> | ComponentRef<any> | FlavourRef, blockCard?: BlockCardRef): HTMLElement[] {
83
    if (blockCard) {
548✔
84
        return [blockCard.instance.nativeElement];
1✔
85
    }
86
    if (ref instanceof FlavourRef) {
547✔
87
        return [ref.instance.nativeElement];
544✔
88
    }
89
    if (ref instanceof ComponentRef) {
3!
90
        ((ref.hostView as any).rootNodes as (HTMLElement | any)[]).forEach(ele => {
3✔
91
            if (!(ele instanceof HTMLElement)) {
6✔
92
                ele.remove();
3✔
93
            }
94
        });
95
        return [ref.instance.nativeElement];
3✔
96
    } else {
97
        const result: HTMLElement[] = [];
×
98
        ref.rootNodes.forEach(rootNode => {
×
99
            const isHTMLElement = rootNode instanceof HTMLElement;
×
100
            const isSlateNodeOfLeaf =
101
                isHTMLElement && (rootNode.hasAttribute('data-slate-node') || rootNode.hasAttribute('data-slate-leaf'));
×
102
            if (isSlateNodeOfLeaf && result.every(item => !item.contains(rootNode))) {
×
103
                result.push(rootNode);
×
104
            }
105
            if (!isHTMLElement) {
×
106
                rootNode.remove();
×
107
            }
108
        });
109
        return result;
×
110
    }
111
}
112

113
export function mountOnItemChange(
114
    index: number,
115
    item: Descendant,
116
    views: (EmbeddedViewRef<any> | ComponentRef<any>)[],
117
    blockCards: (BlockCardRef | null)[] | null,
118
    outletParent: HTMLElement,
119
    firstRootNode: HTMLElement | null,
120
    viewContext: SlateViewContext
121
) {
122
    const view = views[index];
16✔
123
    let rootNodes = getRootNodes(view);
16✔
124
    if (blockCards) {
16✔
125
        const isBlockCard = viewContext.editor.isBlockCard(item);
14✔
126
        if (isBlockCard) {
14!
127
            const blockCard = blockCards[index];
×
128
            rootNodes = [blockCard.instance.nativeElement];
×
129
        }
130
    }
131
    if (index === 0) {
16✔
132
        if (firstRootNode) {
7!
133
            rootNodes.forEach(rootNode => {
7✔
134
                firstRootNode.insertAdjacentElement('beforebegin', rootNode);
7✔
135
            });
136
        } else {
137
            outletParent.prepend(...rootNodes);
×
138
        }
139
    } else {
140
        const previousView = views[index - 1];
9✔
141
        const blockCard = blockCards ? blockCards[index - 1] : null;
9✔
142
        const previousRootNodes = getRootNodes(previousView, blockCard);
9✔
143
        let previousRootNode = previousRootNodes[previousRootNodes.length - 1];
9✔
144
        rootNodes.forEach(rootNode => {
9✔
145
            previousRootNode.insertAdjacentElement('afterend', rootNode);
9✔
146
            previousRootNode = rootNode;
9✔
147
        });
148
    }
149
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc