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

worktile / slate-angular / a94e9740-e8bc-460d-88b3-f39ff5a789ab

22 Aug 2024 03:45AM UTC coverage: 46.776% (-0.05%) from 46.828%
a94e9740-e8bc-460d-88b3-f39ff5a789ab

push

circleci

pubuzhixing8
chore: fix ci error

409 of 1075 branches covered (38.05%)

Branch coverage included in aggregate %.

1020 of 1980 relevant lines covered (51.52%)

44.05 hits per line

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

91.67
/packages/src/components/string/string.component.ts
1
import {
2
    AfterViewInit,
3
    ChangeDetectionStrategy,
4
    Component,
5
    ElementRef,
6
    inject,
7
    Input,
8
    OnChanges,
9
    OnInit,
10
    ViewContainerRef
11
} from '@angular/core';
12
import { Node, Text } from 'slate';
13
import { ViewContainerItem } from '../../view/container-item';
14
import { SlateLeafContext, SlateStringContext } from '../../view/context';
15
import { SlateDefaultString } from './default-string.component';
16

17
@Component({
18
    selector: 'span[slateString]',
19
    template: '',
20
    changeDetection: ChangeDetectionStrategy.OnPush,
21
    standalone: true
22
})
23
export class SlateString extends ViewContainerItem<SlateStringContext> implements OnInit, OnChanges, AfterViewInit {
1✔
24
    @Input() context: SlateLeafContext;
25

26
    protected elementRef = inject<any>(ElementRef);
152✔
27

28
    protected viewContainerRef = inject(ViewContainerRef);
152✔
29

30
    ngOnInit(): void {
31
        this.createView();
152✔
32
    }
33

34
    ngOnChanges() {
35
        if (!this.initialized) {
158✔
36
            return;
152✔
37
        }
38
        this.updateView();
6✔
39
    }
40

41
    ngAfterViewInit() {
42
        this.elementRef.nativeElement.remove();
152✔
43
    }
44

45
    // COMPAT: If this is the last text node in an empty block, render a zero-
46
    // width space that will convert into a line break when copying and pasting
47
    // to support expected plain text.
48
    isLineBreakEmptyString() {
49
        return (
315✔
50
            this.context.leaf.text === '' &&
378✔
51
            this.context.parent.children[this.context.parent.children.length - 1] === this.context.text &&
52
            !this.viewContext.editor.isInline(this.context.parent) &&
53
            // [list-render] performance optimization: reduce the number of calls to the `Editor.string(editor, path)` method
54
            isEmpty(this.viewContext.editor, this.context.parent)
55
        );
56
    }
57

58
    // COMPAT: If the text is empty, it's because it's on the edge of an inline
59
    // node, so we render a zero-width space so that the selection can be
60
    // inserted next to it still.
61
    isEmptyText() {
62
        return this.context.leaf.text === '';
147✔
63
    }
64

65
    // COMPAT: Browsers will collapse trailing new lines at the end of blocks,
66
    // so we need to add an extra trailing new lines to prevent that.
67
    isCompatibleString() {
68
        return this.context.isLast && this.context.leaf.text.slice(-1) === '\n';
147✔
69
    }
70

71
    // COMPAT: Render text inside void nodes with a zero-width space.
72
    // So the node can contain selection but the text is not visible.
73
    isVoid() {
74
        return this.viewContext.editor.isVoid(this.context.parent);
158✔
75
    }
76

77
    getViewType() {
78
        if (this.isVoid()) {
158✔
79
            return this.viewContext.templateComponent.voidStringTemplate;
1✔
80
        }
81

82
        if (this.isLineBreakEmptyString()) {
157✔
83
            return SlateDefaultString;
10✔
84
        }
85

86
        if (this.isEmptyText()) {
147!
87
            return this.viewContext.templateComponent.emptyTextTemplate;
×
88
        }
89

90
        if (this.isCompatibleString()) {
147!
91
            return this.viewContext.templateComponent.compatibleStringTemplate;
×
92
        }
93

94
        return SlateDefaultString;
147✔
95
    }
96

97
    getType(): SlateStringContext['type'] {
98
        if (this.isLineBreakEmptyString()) {
158✔
99
            return 'lineBreakEmptyString';
10✔
100
        }
101
        return 'string';
148✔
102
    }
103

104
    getContext(): SlateStringContext {
105
        const stringType = this.getType();
158✔
106
        return {
158✔
107
            text: this.context.leaf.text,
108
            elementStringLength: Node.string(this.context.parent).length,
109
            type: stringType
110
        };
111
    }
112

113
    memoizedContext(prev: SlateStringContext, next: SlateStringContext): boolean {
114
        return false;
6✔
115
    }
116
}
117

118
/**
119
 * TODO: remove when bump slate
120
 * copy from slate
121
 * @param editor
122
 * @param element
123
 * @returns
124
 */
125
export const isEmpty = (editor, element) => {
1✔
126
    const { children } = element;
21✔
127
    const [first] = children;
21✔
128
    return children.length === 0 || (children.length === 1 && Text.isText(first) && first.text === '' && !editor.isVoid(element));
21✔
129
};
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

© 2025 Coveralls, Inc