From 0bb04e2951cc6f40e6190a5cda51706b56794732 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Wed, 19 Jan 2022 01:15:53 +0100 Subject: [PATCH] Fix bug when selecting text next to frame by clicking three times (#1604) --- ts/editable/frame-element.ts | 7 +++++-- ts/editable/frame-handle.ts | 7 +++++-- ts/lib/cross-browser.ts | 14 +++++++++----- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/ts/editable/frame-element.ts b/ts/editable/frame-element.ts index 5142528a2..39e8bf448 100644 --- a/ts/editable/frame-element.ts +++ b/ts/editable/frame-element.ts @@ -8,7 +8,7 @@ import { hasBlockAttribute, } from "../lib/dom"; import { on } from "../lib/events"; -import { getSelection } from "../lib/cross-browser"; +import { getSelection, isSelectionCollapsed } from "../lib/cross-browser"; import { moveChildOutOfElement } from "../domlib/move-nodes"; import { placeCaretBefore, placeCaretAfter } from "../domlib/place-caret"; import { @@ -238,7 +238,10 @@ function checkIfInsertingLineBreakAdjacentToBlockFrame() { const selection = getSelection(frame)!; - if (selection.anchorNode === frame.framedElement && selection.isCollapsed) { + if ( + selection.anchorNode === frame.framedElement && + isSelectionCollapsed(selection) + ) { frame.insertLineBreak(selection.anchorOffset); } } diff --git a/ts/editable/frame-handle.ts b/ts/editable/frame-handle.ts index 5a5fca240..1846ca085 100644 --- a/ts/editable/frame-handle.ts +++ b/ts/editable/frame-handle.ts @@ -3,7 +3,7 @@ import { nodeIsText, nodeIsElement, elementIsEmpty } from "../lib/dom"; import { on } from "../lib/events"; -import { getSelection } from "../lib/cross-browser"; +import { getSelection, isSelectionCollapsed } from "../lib/cross-browser"; import { moveChildOutOfElement } from "../domlib/move-nodes"; import { placeCaretAfter } from "../domlib/place-caret"; import type { FrameElement } from "./frame-element"; @@ -277,7 +277,10 @@ export function checkWhetherMovingIntoHandle(): void { for (const handle of handles) { const selection = getSelection(handle)!; - if (selection.anchorNode === handle.firstChild && selection.isCollapsed) { + if ( + selection.anchorNode === handle.firstChild && + isSelectionCollapsed(selection) + ) { handle.notifyMoveIn(selection.anchorOffset); } } diff --git a/ts/lib/cross-browser.ts b/ts/lib/cross-browser.ts index 409f4022c..95a59ff69 100644 --- a/ts/lib/cross-browser.ts +++ b/ts/lib/cross-browser.ts @@ -1,11 +1,6 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -/** - * NOTES: - * - Avoid using selection.isCollapsed: will always return true in shadow root in Gecko - */ - /** * Gecko has no .getSelection on ShadowRoot, only .activeElement */ @@ -29,3 +24,12 @@ export function getRange(selection: Selection): Range | null { return rangeCount === 0 ? null : selection.getRangeAt(rangeCount - 1); } + +/** + * Avoid using selection.isCollapsed: it will always return + * true in shadow root in Gecko + * (this bug seems to also happens in Blink) + */ +export function isSelectionCollapsed(selection: Selection): boolean { + return getRange(selection)!.collapsed; +}