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

worktile / slate-angular / 8f51299a-b715-4e55-b528-1442ed2e8276

16 Jul 2025 07:31AM UTC coverage: 48.475% (+0.04%) from 48.44%
8f51299a-b715-4e55-b528-1442ed2e8276

push

circleci

pubuzhixing8
fix(focus): revert focus logic and remove retry and setTimeout #WIK-18473

368 of 934 branches covered (39.4%)

Branch coverage included in aggregate %.

11 of 20 new or added lines in 2 files covered. (55.0%)

951 of 1787 relevant lines covered (53.22%)

44.11 hits per line

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

44.19
/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 { getSelection } from '../utils/dom';
8

9
/**
10
 * An Angular and DOM-specific version of the `Editor` interface.
11
 */
12
export interface AngularEditor extends CustomDOMEditor {
13
    deleteCutData: () => void;
14
    onKeydown: (event: KeyboardEvent) => void;
15
    onClick: (event: MouseEvent) => void;
16
    injector: Injector;
17
    isBlockCard: (node: Node) => boolean;
18
    isExpanded: (node: Element) => boolean;
19
    onError: (errorData: SlateError) => void;
20
    customInsertFragmentData: (data: DataTransfer) => Promise<boolean>;
21
    customInsertTextData: (data: DataTransfer) => Promise<boolean>;
22
}
23

24
export const AngularEditor = {
1✔
25
    ...CustomDOMEditor,
26
    /**
27
     * handle editor error.
28
     */
29

30
    onError(errorData: SlateError) {
31
        if (errorData.nativeError) {
×
32
            throw errorData.nativeError;
×
33
        }
34
    },
35

36
    /**
37
     * onKeydown hook.
38
     */
39
    onKeydown(editor: AngularEditor, data: KeyboardEvent): void {
40
        editor.onKeydown(data);
×
41
    },
42

43
    /**
44
     * onClick hook.
45
     */
46
    onClick(editor: AngularEditor, data: MouseEvent): void {
47
        editor.onClick(data);
×
48
    },
49

50
    deleteCutData(editor: AngularEditor): void {
51
        editor.deleteCutData();
×
52
    },
53

54
    isLeafBlock(editor: AngularEditor, node: Node): boolean {
55
        return Element.isElement(node) && !editor.isInline(node) && Editor.hasInlines(editor, node);
159✔
56
    },
57

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

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

102
        // Return if no dom node is associated with the editor, which means the editor is not yet mounted
103
        // or has been unmounted. This can happen especially, while retrying to focus the editor.
104
        if (!EDITOR_TO_ELEMENT.get(editor)) {
2!
NEW
105
            return;
×
106
        }
107

108
        const el = DOMEditor.toDOMNode(editor, editor);
2✔
109
        const root = DOMEditor.findDocumentOrShadowRoot(editor);
2✔
110
        if (root.activeElement !== el) {
2✔
111
            // Ensure that the DOM selection state is set to the editor's selection
112
            if (editor.selection && root instanceof Document) {
2!
NEW
113
                const domSelection = getSelection(root);
×
NEW
114
                const domRange = DOMEditor.toDOMRange(editor, editor.selection);
×
NEW
115
                domSelection?.removeAllRanges();
×
NEW
116
                domSelection?.addRange(domRange);
×
117
            }
118
            // Create a new selection in the top of the document if missing
119
            if (!editor.selection) {
2✔
120
                Transforms.select(editor, Editor.start(editor, []));
2✔
121
            }
122
            // IS_FOCUSED should be set before calling el.focus() to ensure that
123
            // FocusedContext is updated to the correct value
124
            IS_FOCUSED.set(editor, true);
2✔
125
            el.focus({ preventScroll: true });
2✔
126
        }
127
    }
128
};
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