From 434287a50af160f4a0b5f50b6f7ba06fe8122ef7 Mon Sep 17 00:00:00 2001 From: Abdo Date: Tue, 15 Nov 2022 04:14:18 +0300 Subject: [PATCH] Fix inverted Ctrl+right/left handling in RTL fields (again) (#2191) --- ts/editable/ContentEditable.svelte | 7 ++++++- ts/editable/content-editable.ts | 33 ++++++++++++++++++++++++++++++ ts/editor/base.ts | 1 - 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/ts/editable/ContentEditable.svelte b/ts/editable/ContentEditable.svelte index 645c5d3bc..6bc1f7600 100644 --- a/ts/editable/ContentEditable.svelte +++ b/ts/editable/ContentEditable.svelte @@ -14,7 +14,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import type { MirrorAction } from "../sveltelib/dom-mirror"; import type { SetupInputHandlerAction } from "../sveltelib/input-handler"; import type { ContentEditableAPI } from "./content-editable"; - import { preventBuiltinShortcuts, useFocusHandler } from "./content-editable"; + import { + fixRTLKeyboardNav, + preventBuiltinShortcuts, + useFocusHandler, + } from "./content-editable"; export let resolve: (editable: HTMLElement) => void; @@ -40,6 +44,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use:resolve use:setupFocusHandling use:preventBuiltinShortcuts + use:fixRTLKeyboardNav use:mirrorAction={mirrorOptions} use:inputHandlerAction={{}} on:focus diff --git a/ts/editable/content-editable.ts b/ts/editable/content-editable.ts index b10f70a1a..5df8b3dd8 100644 --- a/ts/editable/content-editable.ts +++ b/ts/editable/content-editable.ts @@ -5,6 +5,7 @@ import type { SelectionLocation } from "../domlib/location"; import { restoreSelection, saveSelection } from "../domlib/location"; import { placeCaretAfterContent } from "../domlib/place-caret"; import { bridgeCommand } from "../lib/bridgecommand"; +import { getSelection } from "../lib/cross-browser"; import { on, preventDefault } from "../lib/events"; import { isApplePlatform } from "../lib/platform"; import { registerShortcut } from "../lib/shortcuts"; @@ -138,6 +139,38 @@ export function preventBuiltinShortcuts(editable: HTMLElement): void { } } +declare global { + interface Selection { + modify(s: string, t: string, u: string): void; + } +} + +// Fix inverted Ctrl+right/left handling in RTL fields +export function fixRTLKeyboardNav(editable: HTMLElement): void { + editable.addEventListener("keydown", (evt: KeyboardEvent) => { + if (window.getComputedStyle(editable).direction === "rtl") { + const selection = getSelection(editable)!; + let granularity = "character"; + let alter = "move"; + if (evt.ctrlKey) { + granularity = "word"; + } + if (evt.shiftKey) { + alter = "extend"; + } + if (evt.code === "ArrowRight") { + selection.modify(alter, "right", granularity); + evt.preventDefault(); + return; + } else if (evt.code === "ArrowLeft") { + selection.modify(alter, "left", granularity); + evt.preventDefault(); + return; + } + } + }); +} + /** API */ export interface ContentEditableAPI { diff --git a/ts/editor/base.ts b/ts/editor/base.ts index 37c5f917e..f46e4be00 100644 --- a/ts/editor/base.ts +++ b/ts/editor/base.ts @@ -11,7 +11,6 @@ import "../sveltelib/export-runtime"; declare global { interface Selection { - modify(s: string, t: string, u: string): void; addRange(r: Range): void; removeAllRanges(): void; getRangeAt(n: number): Range;