diff --git a/.changeset/twenty-geckos-roll.md b/.changeset/twenty-geckos-roll.md new file mode 100644 index 00000000..3bf3fc9a --- /dev/null +++ b/.changeset/twenty-geckos-roll.md @@ -0,0 +1,10 @@ +--- +"slate-angular": patch +--- + +handle triple-click +remove the attribute of editable='false' in void element +refer to: +https://github.com/ianstormtaylor/slate/pull/4588 + + diff --git a/demo/app/components/image/image-component.ts b/demo/app/components/image/image-component.ts index 84445d04..e13688b6 100644 --- a/demo/app/components/image/image-component.ts +++ b/demo/app/components/image/image-component.ts @@ -5,8 +5,7 @@ import { SlateChildren } from '../../../../packages/src/components/children/chil @Component({ selector: 'demo-element-image', - template: ` - `, + template: ` `, host: { class: 'demo-element-image' }, diff --git a/packages/src/components/editable/editable.component.ts b/packages/src/components/editable/editable.component.ts index 6c993b3a..0e31754d 100644 --- a/packages/src/components/editable/editable.component.ts +++ b/packages/src/components/editable/editable.component.ts @@ -68,6 +68,7 @@ import { SlateDefaultLeaf } from '../leaf/default-leaf.component'; import { SLATE_DEFAULT_LEAF_COMPONENT_TOKEN } from '../leaf/token'; import { BaseElementComponent, BaseLeafComponent, BaseTextComponent } from '../../view/base'; import { ListRender } from '../../view/render/list-render'; +import { TRIPLE_CLICK } from '../../utils/constants'; // not correctly clipboardData on beforeinput const forceOnDOMPaste = IS_SAFARI; @@ -859,6 +860,22 @@ export class SlateEditable implements OnInit, OnChanges, OnDestroy, AfterViewChe const startVoid = Editor.void(this.editor, { at: start }); const endVoid = Editor.void(this.editor, { at: end }); + if (event.detail === TRIPLE_CLICK && path.length >= 1) { + let blockPath = path; + if (!(Element.isElement(node) && Editor.isBlock(this.editor, node))) { + const block = Editor.above(this.editor, { + match: n => Element.isElement(n) && Editor.isBlock(this.editor, n), + at: path + }); + + blockPath = block?.[1] ?? path.slice(0, 1); + } + + const range = Editor.range(this.editor, blockPath); + Transforms.select(this.editor, range); + return; + } + if (startVoid && endVoid && Path.equals(startVoid[1], endVoid[1])) { const range = Editor.range(this.editor, start); Transforms.select(this.editor, range); diff --git a/packages/src/plugins/angular-editor.ts b/packages/src/plugins/angular-editor.ts index f324ca6f..1ebdb439 100644 --- a/packages/src/plugins/angular-editor.ts +++ b/packages/src/plugins/angular-editor.ts @@ -685,7 +685,21 @@ export const AngularEditor = { const anchor = AngularEditor.toSlatePoint(editor, [anchorNode, anchorOffset]); const focus = isCollapsed ? anchor : AngularEditor.toSlatePoint(editor, [focusNode, focusOffset]); - return { anchor, focus }; + let range: Range = { anchor: anchor as Point, focus: focus as Point }; + // if the selection is a hanging range that ends in a void + // and the DOM focus is an Element + // (meaning that the selection ends before the element) + // unhang the range to avoid mistakenly including the void + if ( + Range.isExpanded(range) && + Range.isForward(range) && + isDOMElement(focusNode) && + Editor.void(editor, { at: range.focus, mode: 'highest' }) + ) { + range = Editor.unhangRange(editor, range, { voids: true }); + } + + return range; }, isLeafBlock(editor: AngularEditor, node: Node): boolean { diff --git a/packages/src/utils/constants.ts b/packages/src/utils/constants.ts new file mode 100644 index 00000000..83c0d001 --- /dev/null +++ b/packages/src/utils/constants.ts @@ -0,0 +1 @@ +export const TRIPLE_CLICK = 3; diff --git a/packages/src/view/context.ts b/packages/src/view/context.ts index 23a6de33..f161e14c 100644 --- a/packages/src/view/context.ts +++ b/packages/src/view/context.ts @@ -54,7 +54,6 @@ export interface SlateElementAttributes { 'data-slate-node': 'element'; 'data-slate-void'?: boolean; 'data-slate-inline'?: boolean; - contenteditable?: boolean; 'data-slate-key'?: string; dir?: 'rtl'; } diff --git a/packages/src/view/render/list-render.ts b/packages/src/view/render/list-render.ts index 1b183aca..2a7257a2 100644 --- a/packages/src/view/render/list-render.ts +++ b/packages/src/view/render/list-render.ts @@ -183,7 +183,6 @@ export function getContext( } if (isVoid) { elementContext.attributes['data-slate-void'] = true; - elementContext.attributes.contenteditable = false; } return elementContext; } else {