From 6d92d2497b417664d18b2f1cffd210ce86920fa3 Mon Sep 17 00:00:00 2001 From: ocavue Date: Wed, 3 Jul 2024 09:45:28 +1000 Subject: [PATCH 1/3] docs: add prosemirror-safari-ime-span --- demo/demo.ts | 3 ++- package.json | 1 + yarn.lock | 28 ++++++++++++++++++---------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/demo/demo.ts b/demo/demo.ts index 3cee56ab..d1f35bf6 100644 --- a/demo/demo.ts +++ b/demo/demo.ts @@ -11,7 +11,7 @@ import { schema as baseSchema } from 'prosemirror-schema-basic'; import { keymap } from 'prosemirror-keymap'; import { exampleSetup, buildMenuItems } from 'prosemirror-example-setup'; import { MenuItem, Dropdown } from 'prosemirror-menu'; - +import { imeSpan } from 'prosemirror-safari-ime-span'; import { addColumnAfter, addColumnBefore, @@ -89,6 +89,7 @@ let state = EditorState.create({ Tab: goToNextCell(1), 'Shift-Tab': goToNextCell(-1), }), + imeSpan, ].concat( exampleSetup({ schema, diff --git a/package.json b/package.json index 1ffec0ec..a06abf1d 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "dependencies": { "prosemirror-keymap": "^1.1.2", "prosemirror-model": "^1.8.1", + "prosemirror-safari-ime-span": "^1.0.1", "prosemirror-state": "^1.3.1", "prosemirror-transform": "^1.2.1", "prosemirror-view": "^1.13.3" diff --git a/yarn.lock b/yarn.lock index 487061e6..d40eb23c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1504,13 +1504,21 @@ prosemirror-menu@^1.0.0, prosemirror-menu@^1.2.2: prosemirror-history "^1.0.0" prosemirror-state "^1.0.0" -prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.19.0, prosemirror-model@^1.8.1: - version "1.19.2" - resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.19.2.tgz#297c9ecfb103154e605f0dbaf3cc72ee32ca0ad5" - integrity sha512-RXl0Waiss4YtJAUY3NzKH0xkJmsZupCIccqcIFoLTIKFlKNbIvFDRl27/kQy1FP8iUAxrjRRfIVvOebnnXJgqQ== +prosemirror-model@^1.0.0, prosemirror-model@^1.19.0, prosemirror-model@^1.20.0, prosemirror-model@^1.8.1: + version "1.21.3" + resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.21.3.tgz#97fa434d670331c1ab25f75964b1bcd7a948ce61" + integrity sha512-nt2Xs/RNGepD9hrrkzXvtCm1mpGJoQfFSPktGa0BF/aav6XsnmVGZ9sTXNWRLupAz5SCLa3EyKlFeK7zJWROKg== dependencies: orderedmap "^2.0.0" +prosemirror-safari-ime-span@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prosemirror-safari-ime-span/-/prosemirror-safari-ime-span-1.0.1.tgz#cd4b09fda12ce07b8b5877a11808c8f141bc88ff" + integrity sha512-4WjIR6d5HfKJ5JP4UK7SOzV7aOMqy8Q3b09IzGoFDPWA2GdeNWls6zxO37g4Ny3DRhoYg0hFaXu7JGpzzUlprw== + dependencies: + prosemirror-state "^1.4.3" + prosemirror-view "^1.33.8" + prosemirror-schema-basic@^1.0.0, prosemirror-schema-basic@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.2.tgz#6695f5175e4628aab179bf62e5568628b9cfe6c7" @@ -1527,7 +1535,7 @@ prosemirror-schema-list@^1.0.0: prosemirror-state "^1.0.0" prosemirror-transform "^1.7.3" -prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1: +prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.4.3.tgz#94aecf3ffd54ec37e87aa7179d13508da181a080" integrity sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q== @@ -1552,12 +1560,12 @@ prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transfor dependencies: prosemirror-model "^1.0.0" -prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0: - version "1.31.4" - resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.31.4.tgz#d9a40363bf517605f77a5cfe6c0106958a7dbe5e" - integrity sha512-nJzH2LpYbonSTYFqQ1BUdEhbd1WPN/rp/K9T9qxBEYpgg3jK3BvEUCR45Ymc9IHpO0m3nBJwPm19RBxZdoBVuw== +prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.33.8: + version "1.33.8" + resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.33.8.tgz#cfd76dff421730cbca0b6ea40ce36994daaeda41" + integrity sha512-4PhMr/ufz2cdvFgpUAnZfs+0xij3RsFysreeG9V/utpwX7AJtYCDVyuRxzWoMJIEf4C7wVihuBNMPpFLPCiLQw== dependencies: - prosemirror-model "^1.16.0" + prosemirror-model "^1.20.0" prosemirror-state "^1.0.0" prosemirror-transform "^1.1.0" From 0e7cbc2794c76bed7620007d35aa91815fe36a6e Mon Sep 17 00:00:00 2001 From: ocavue Date: Thu, 18 Jul 2024 23:00:29 +1000 Subject: [PATCH 2/3] Try without transaction --- demo/demo.ts | 2 +- src/ime/browser.ts | 12 ++++++++++ src/ime/index.ts | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/ime/browser.ts create mode 100644 src/ime/index.ts diff --git a/demo/demo.ts b/demo/demo.ts index d1f35bf6..9e0fb067 100644 --- a/demo/demo.ts +++ b/demo/demo.ts @@ -11,7 +11,7 @@ import { schema as baseSchema } from 'prosemirror-schema-basic'; import { keymap } from 'prosemirror-keymap'; import { exampleSetup, buildMenuItems } from 'prosemirror-example-setup'; import { MenuItem, Dropdown } from 'prosemirror-menu'; -import { imeSpan } from 'prosemirror-safari-ime-span'; +import { imeSpan } from '../src/ime'; import { addColumnAfter, addColumnBefore, diff --git a/src/ime/browser.ts b/src/ime/browser.ts new file mode 100644 index 00000000..ee437c49 --- /dev/null +++ b/src/ime/browser.ts @@ -0,0 +1,12 @@ +// Copied from https://github.com/prosemirror/prosemirror-view/blob/1.33.8/src/browser.ts + +const nav = typeof navigator != 'undefined' ? navigator : null +const agent = (nav && nav.userAgent) || '' + +const ie_edge = /Edge\/(\d+)/.exec(agent) +const ie_upto10 = /MSIE \d/.exec(agent) +const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent) + +const ie = !!(ie_upto10 || ie_11up || ie_edge) + +export const safari = !ie && !!nav && /Apple Computer/.test(nav.vendor) diff --git a/src/ime/index.ts b/src/ime/index.ts new file mode 100644 index 00000000..765531ae --- /dev/null +++ b/src/ime/index.ts @@ -0,0 +1,55 @@ +import { + Plugin, + PluginKey, + type PluginSpec, + type EditorState, +} from 'prosemirror-state'; +import { Decoration, DecorationSet, type EditorView } from 'prosemirror-view'; + +import { safari } from './browser'; + +const key = new PluginKey('safari-ime-span'); + +let isComposing = false; + +const spec: PluginSpec = { + key, + props: { + decorations: createDecorations, + handleDOMEvents: { + compositionstart: () => { + isComposing = true; + }, + compositionend: () => { + isComposing = false; + }, + }, + }, +}; + +function createDecorations(state: EditorState): DecorationSet | undefined { + const { $from, $to, to } = state.selection; + if (isComposing && $from.sameParent($to)) { + const deco = Decoration.widget(to, createSpan, { + ignoreSelection: true, + key: 'safari-ime-span', + }); + return DecorationSet.create(state.doc, [deco]); + } +} + +function createSpan(view: EditorView): HTMLSpanElement { + const span = view.dom.ownerDocument.createElement('span'); + span.className = 'ProseMirror-safari-ime-span'; + return span; +} + +/** + * A plugin as a workaround for a bug in Safari that causes the composition + * based IME to remove the empty HTML element with CSS `position: relative`. + * + * See also https://github.com/ProseMirror/prosemirror/issues/934 + * + * @public @group Plugins + */ +export const imeSpan = new Plugin(safari ? spec : { key }); From a44a62e02a26a2f548e0451e28462e7b62df0fdb Mon Sep 17 00:00:00 2001 From: ocavue Date: Thu, 18 Jul 2024 23:02:13 +1000 Subject: [PATCH 3/3] format code --- src/ime/browser.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ime/browser.ts b/src/ime/browser.ts index ee437c49..df26c5d1 100644 --- a/src/ime/browser.ts +++ b/src/ime/browser.ts @@ -1,12 +1,12 @@ // Copied from https://github.com/prosemirror/prosemirror-view/blob/1.33.8/src/browser.ts -const nav = typeof navigator != 'undefined' ? navigator : null -const agent = (nav && nav.userAgent) || '' +const nav = typeof navigator != 'undefined' ? navigator : null; +const agent = (nav && nav.userAgent) || ''; -const ie_edge = /Edge\/(\d+)/.exec(agent) -const ie_upto10 = /MSIE \d/.exec(agent) -const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent) +const ie_edge = /Edge\/(\d+)/.exec(agent); +const ie_upto10 = /MSIE \d/.exec(agent); +const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent); -const ie = !!(ie_upto10 || ie_11up || ie_edge) +const ie = !!(ie_upto10 || ie_11up || ie_edge); -export const safari = !ie && !!nav && /Apple Computer/.test(nav.vendor) +export const safari = !ie && !!nav && /Apple Computer/.test(nav.vendor);