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

worktile / slate-angular / 9cbfe276-6a5c-4ac1-a622-9e7e046f79d4

02 Feb 2026 08:51AM UTC coverage: 35.546% (-0.1%) from 35.651%
9cbfe276-6a5c-4ac1-a622-9e7e046f79d4

push

circleci

pubuzhixing8
fix(virtual-scroll): support calc business top in scrollToElement

405 of 1353 branches covered (29.93%)

Branch coverage included in aggregate %.

6 of 32 new or added lines in 3 files covered. (18.75%)

1 existing line in 1 file now uncovered.

1121 of 2940 relevant lines covered (38.13%)

22.81 hits per line

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

38.89
/packages/src/plugins/angular-editor.ts
1
import { Editor, Node, Path, Transforms, Element } from 'slate';
2
import { Injector } from '@angular/core';
3
import { SlateError } from '../types/error';
4
import { FAKE_LEFT_BLOCK_CARD_OFFSET, FAKE_RIGHT_BLOCK_CARD_OFFSET } from '../utils/block-card';
5
import { CustomDOMEditor } from './with-dom';
6
import { DOMEditor, EDITOR_TO_ELEMENT, IS_FOCUSED } from 'slate-dom';
7
import { ClipboardData } from '../types/clipboard';
8
import { EDITOR_TO_VIRTUAL_SCROLL_CONFIG } from '../utils/virtual-scroll';
9

10
/**
11
 * An Angular and DOM-specific version of the `Editor` interface.
12
 */
13
export interface AngularEditor extends CustomDOMEditor {
14
    deleteCutData: () => void;
15
    selectAll: () => void;
16
    isVisible: (element: Element) => boolean;
17
    getAllVisibleStates: () => boolean[];
18
    onKeydown: (event: KeyboardEvent) => void;
19
    onClick: (event: MouseEvent) => void;
20
    injector: Injector;
21
    isBlockCard: (node: Node) => boolean;
22
    isExpanded: (node: Element) => boolean;
23
    getRoughHeight: (node: Element, defaultHeight?: number) => number;
24
    onError: (errorData: SlateError) => void;
25
    customInsertFragmentData: (data: DataTransfer, clipboardData: ClipboardData | null) => Promise<boolean>;
26
    customInsertTextData: (data: DataTransfer) => Promise<boolean>;
27
}
28

29
export const AngularEditor = {
1✔
30
    ...CustomDOMEditor,
31
    /**
32
     * handle editor error.
33
     */
34

35
    onError(errorData: SlateError) {
36
        if (errorData.nativeError) {
×
37
            throw errorData.nativeError;
×
38
        }
39
    },
40

41
    /**
42
     * onKeydown hook.
43
     */
44
    onKeydown(editor: AngularEditor, data: KeyboardEvent): void {
45
        editor.onKeydown(data);
×
46
    },
47

48
    /**
49
     * onClick hook.
50
     */
51
    onClick(editor: AngularEditor, data: MouseEvent): void {
52
        editor.onClick(data);
×
53
    },
54

55
    deleteCutData(editor: AngularEditor): void {
56
        editor.deleteCutData();
×
57
    },
58

59
    isLeafBlock(editor: AngularEditor, node: Node): boolean {
60
        return Element.isElement(node) && !editor.isInline(node) && Editor.hasInlines(editor, node);
159✔
61
    },
62

63
    /**
64
     * move native selection to card-left or card-right
65
     * @param editor
66
     * @param blockCardNode
67
     * @param options
68
     */
69
    moveBlockCard(
70
        editor: AngularEditor,
71
        blockCardNode: Node,
72
        options: {
73
            direction: 'left' | 'right';
74
        }
75
    ) {
76
        const cursorNode = AngularEditor.getCardCursorNode(editor, blockCardNode, options);
×
77
        const window = AngularEditor.getWindow(editor);
×
78
        const domSelection = window.getSelection();
×
79
        domSelection.setBaseAndExtent(cursorNode, 1, cursorNode, 1);
×
80
    },
81

82
    /**
83
     * move slate selection to card-left or card-right
84
     * @param editor
85
     * @param path
86
     * @param options
87
     */
88
    moveBlockCardCursor(
89
        editor: AngularEditor,
90
        path: Path,
91
        options: {
92
            direction: 'left' | 'right';
93
        }
94
    ) {
95
        const cursor = {
×
96
            path,
97
            offset: options.direction === 'left' ? FAKE_LEFT_BLOCK_CARD_OFFSET : FAKE_RIGHT_BLOCK_CARD_OFFSET
×
98
        };
99
        Transforms.select(editor, { anchor: cursor, focus: cursor });
×
100
    },
101
    focus: (editor, options = { retries: 5 }) => {
2✔
102
        // Return if already focused
103
        if (IS_FOCUSED.get(editor)) {
2!
104
            return;
×
105
        }
106

107
        // Return if no dom node is associated with the editor, which means the editor is not yet mounted
108
        // or has been unmounted. This can happen especially, while retrying to focus the editor.
109
        if (!EDITOR_TO_ELEMENT.get(editor)) {
2!
110
            return;
×
111
        }
112

113
        IS_FOCUSED.set(editor, true);
2✔
114
        const el = DOMEditor.toDOMNode(editor, editor);
2✔
115
        const root = DOMEditor.findDocumentOrShadowRoot(editor);
2✔
116
        if (root.activeElement !== el) {
2✔
117
            // IS_FOCUSED should be set before calling el.focus() to ensure that
118
            // FocusedContext is updated to the correct value
119
            el.focus({ preventScroll: true });
2✔
120
        }
121
    },
122
    isEnabledVirtualScroll(editor: AngularEditor): boolean {
NEW
123
        const config = EDITOR_TO_VIRTUAL_SCROLL_CONFIG.get(editor);
×
NEW
124
        return config?.enabled || false;
×
125
    }
126
};
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