diff --git a/.changeset/seven-foxes-wonder.md b/.changeset/seven-foxes-wonder.md new file mode 100644 index 00000000..90cebc90 --- /dev/null +++ b/.changeset/seven-foxes-wonder.md @@ -0,0 +1,11 @@ +--- +"slate-angular": minor +--- + +1. In toDOMPoint, when the anchor or focus is on the block-card element and the selection is in the expanded state, the DOM selection is positioned on the cursor before and after, solving the problem that the beforeinput event cannot be triggered when the cursor is a block-card or void element (when the first element of the editor or table cell is a void element, Ctrl + A selects all) (contenteditable='false' is added to the void element) + +2. Fix the problem of positioning the cursor before and after the block-card in toSlatePoint + +1. toDOMPoint 中当 anchor 或者 focus 在 block-card 元素上并且选区是 expanded 状态时,将 DOM 的 selection 定位到前后光标的上,解决光标所在的元素是 block-card 和 void 元素(编辑器或者表格单元格的第一个元素是 void 元素时,Ctrl + A 全选)时无法触发 beforeinput 事件(void 元素上增加了 contenteditable='false') + +2. 修复 toSlatePoint 中对 block-card 前后光标定位的问题 diff --git a/demo/app/images/images.component.ts b/demo/app/images/images.component.ts index 0ba81d94..f2e77ffc 100644 --- a/demo/app/images/images.component.ts +++ b/demo/app/images/images.component.ts @@ -84,7 +84,7 @@ const initialValue = [ }, { type: 'image', - url: 'https://source.unsplash.com/kFrdX5IeQzI', + url: 'https://github.com/images/modules/search/light2x.png', children: [ { text: '' @@ -120,5 +120,9 @@ const withImage = (editor: Editor) => { return element.type === 'image' || isVoid(element); }; + editor.isBlockCard = (element: Element) => { + return element.type === 'image' || isVoid(element); + }; + return editor; }; diff --git a/packages/src/plugins/angular-editor.ts b/packages/src/plugins/angular-editor.ts index 7f455fba..b3ebf51b 100644 --- a/packages/src/plugins/angular-editor.ts +++ b/packages/src/plugins/angular-editor.ts @@ -344,21 +344,31 @@ export const AngularEditor = { /** * Find a native DOM selection point from a Slate point. */ - - toDOMPoint(editor: AngularEditor, point: Point): DOMPoint { + toDOMPoint(editor: AngularEditor, point: Point, options: { range: Range }): DOMPoint { const [node] = Editor.node(editor, point.path); const el = AngularEditor.toDOMNode(editor, node); let domPoint: DOMPoint | undefined; - // block card - const cardTargetAttr = getCardTargetAttribute(el); - if (cardTargetAttr) { - if (point.offset === FAKE_LEFT_BLOCK_CARD_OFFSET) { - const cursorNode = AngularEditor.getCardCursorNode(editor, node, { direction: 'left' }); - return [cursorNode, 1]; - } else { - const cursorNode = AngularEditor.getCardCursorNode(editor, node, { direction: 'right' }); - return [cursorNode, 1]; + const [parentNode] = Editor.parent(editor, point.path); + if (editor.isBlockCard(parentNode) || editor.isBlockCard(node)) { + if (point.offset < 0) { + if (point.offset === FAKE_LEFT_BLOCK_CARD_OFFSET) { + const cursorNode = AngularEditor.getCardCursorNode(editor, node, { direction: 'left' }); + return [cursorNode, 1]; + } else { + const cursorNode = AngularEditor.getCardCursorNode(editor, node, { direction: 'right' }); + return [cursorNode, 1]; + } + } + if (Range.isExpanded(options.range)) { + const [start, end] = Range.edges(options.range); + if (start === point) { + const cursorNode = AngularEditor.getCardCursorNode(editor, parentNode, { direction: 'left' }); + return [cursorNode, 1]; + } else { + const cursorNode = AngularEditor.getCardCursorNode(editor, parentNode, { direction: 'right' }); + return [cursorNode, 1]; + } } } @@ -414,8 +424,8 @@ export const AngularEditor = { toDOMRange(editor: AngularEditor, range: Range): DOMRange { const { anchor, focus } = range; const isBackward = Range.isBackward(range); - const domAnchor = AngularEditor.toDOMPoint(editor, anchor); - const domFocus = Range.isCollapsed(range) ? domAnchor : AngularEditor.toDOMPoint(editor, focus); + const domAnchor = AngularEditor.toDOMPoint(editor, anchor, { range }); + const domFocus = Range.isCollapsed(range) ? domAnchor : AngularEditor.toDOMPoint(editor, focus, { range }); const window = AngularEditor.getWindow(editor); const domRange = window.document.createRange(); @@ -577,24 +587,10 @@ export const AngularEditor = { return { path: blockPath, offset: -2 }; } } - // forward - // and to the end of previous node - if (isCardLeftByTargetAttr(cardTargetAttr) && !isBackward) { - const endPath = blockPath[blockPath.length - 1] <= 0 ? blockPath : Path.previous(blockPath); - return Editor.end(editor, endPath); - } - // to the of current node - if ((isCardCenterByTargetAttr(cardTargetAttr) || isCardRightByTargetAttr(cardTargetAttr)) && !isBackward) { - return Editor.end(editor, blockPath); - } - // backward - // and to the start of next node - if (isCardRightByTargetAttr(cardTargetAttr) && isBackward) { - return Editor.start(editor, Path.next(blockPath)); - } - // and to the start of current node - if ((isCardCenterByTargetAttr(cardTargetAttr) || isCardLeftByTargetAttr(cardTargetAttr)) && isBackward) { + if (isCardLeftByTargetAttr(cardTargetAttr)) { return Editor.start(editor, blockPath); + } else { + return Editor.end(editor, blockPath); } }