prosemirror-view 1.33.9 → 1.33.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/index.cjs +28 -11
- package/dist/index.js +26 -7
- package/package.json +1 -1
- package/src/capturekeys.ts +1 -0
- package/src/domcoords.ts +2 -1
- package/src/index.ts +4 -3
- package/src/input.ts +5 -3
- package/src/selection.ts +10 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 1.33.10 (2024-08-13)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Prevent triple clicks and clicks on atom nodes from dispatching a selection update when the new selection is equal to the current selection.
|
|
6
|
+
|
|
7
|
+
Don't crash when `window.getSelection()` returns null.
|
|
8
|
+
|
|
9
|
+
Create a cursor wrapper when starting a composition with a selection that spans mark boundaries, to avoid odd DOM forms created by Chrome in such a situation.
|
|
10
|
+
|
|
1
11
|
## 1.33.9 (2024-07-18)
|
|
2
12
|
|
|
3
13
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -603,6 +603,7 @@ function endOfTextblockHorizontal(view, state, dir) {
|
|
|
603
603
|
atStart = !offset,
|
|
604
604
|
atEnd = offset == $head.parent.content.size;
|
|
605
605
|
var sel = view.domSelection();
|
|
606
|
+
if (!sel) return $head.pos == $head.start() || $head.pos == $head.end();
|
|
606
607
|
if (!maybeRTL.test($head.parent.textContent) || !sel.modify) return dir == "left" || dir == "backward" ? atStart : atEnd;
|
|
607
608
|
return withFlushedState(view, state, function () {
|
|
608
609
|
var _view$domSelectionRan = view.domSelectionRange(),
|
|
@@ -2214,10 +2215,17 @@ function removeClassOnSelectionChange(view) {
|
|
|
2214
2215
|
function selectCursorWrapper(view) {
|
|
2215
2216
|
var domSel = view.domSelection(),
|
|
2216
2217
|
range = document.createRange();
|
|
2218
|
+
if (!domSel) return;
|
|
2217
2219
|
var node = view.cursorWrapper.dom,
|
|
2218
2220
|
img = node.nodeName == "IMG";
|
|
2219
|
-
if (img) range.
|
|
2220
|
-
|
|
2221
|
+
if (img) range.setStart(node.parentNode, domIndex(node) + 1);else range.setStart(node, 0);
|
|
2222
|
+
var sel = view.state.selection;
|
|
2223
|
+
if (sel.empty) {
|
|
2224
|
+
range.collapse(true);
|
|
2225
|
+
} else {
|
|
2226
|
+
var end = view.domAtPos(sel.to);
|
|
2227
|
+
range.setEnd(end.node, end.offset);
|
|
2228
|
+
}
|
|
2221
2229
|
domSel.removeAllRanges();
|
|
2222
2230
|
domSel.addRange(range);
|
|
2223
2231
|
if (!img && !view.state.selection.visible && ie && ie_version <= 11) {
|
|
@@ -2449,6 +2457,7 @@ function setSelFocus(view, node, offset) {
|
|
|
2449
2457
|
}
|
|
2450
2458
|
}
|
|
2451
2459
|
var sel = view.domSelection();
|
|
2460
|
+
if (!sel) return;
|
|
2452
2461
|
if (selectionCollapsed(sel)) {
|
|
2453
2462
|
var range = document.createRange();
|
|
2454
2463
|
range.setEnd(node, offset);
|
|
@@ -2969,6 +2978,7 @@ function runHandlerOnContext(view, propName, pos, inside, event) {
|
|
|
2969
2978
|
}
|
|
2970
2979
|
function updateSelection(view, selection, origin) {
|
|
2971
2980
|
if (!view.focused) view.focus();
|
|
2981
|
+
if (view.state.selection.eq(selection)) return;
|
|
2972
2982
|
var tr = view.state.tr.setSelection(selection);
|
|
2973
2983
|
if (origin == "pointer") tr.setMeta("pointer", true);
|
|
2974
2984
|
view.dispatch(tr);
|
|
@@ -3187,8 +3197,8 @@ editHandlers.compositionstart = editHandlers.compositionupdate = function (view)
|
|
|
3187
3197
|
if (!view.composing) {
|
|
3188
3198
|
view.domObserver.flush();
|
|
3189
3199
|
var state = view.state,
|
|
3190
|
-
$pos = state.selection.$
|
|
3191
|
-
if (state.selection.
|
|
3200
|
+
$pos = state.selection.$to;
|
|
3201
|
+
if (state.selection instanceof prosemirrorState.TextSelection && (state.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(function (m) {
|
|
3192
3202
|
return m.type.spec.inclusive === false;
|
|
3193
3203
|
}))) {
|
|
3194
3204
|
view.markCursor = view.state.storedMarks || $pos.marks();
|
|
@@ -3202,7 +3212,8 @@ editHandlers.compositionstart = editHandlers.compositionupdate = function (view)
|
|
|
3202
3212
|
var before = offset < 0 ? node.lastChild : node.childNodes[offset - 1];
|
|
3203
3213
|
if (!before) break;
|
|
3204
3214
|
if (before.nodeType == 3) {
|
|
3205
|
-
view.domSelection()
|
|
3215
|
+
var _sel = view.domSelection();
|
|
3216
|
+
if (_sel) _sel.collapse(before, before.nodeValue.length);
|
|
3206
3217
|
break;
|
|
3207
3218
|
} else {
|
|
3208
3219
|
node = before;
|
|
@@ -4562,9 +4573,9 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4562
4573
|
};
|
|
4563
4574
|
} else {
|
|
4564
4575
|
if (parse.sel) {
|
|
4565
|
-
var
|
|
4566
|
-
if (
|
|
4567
|
-
var _tr2 = view.state.tr.setSelection(
|
|
4576
|
+
var _sel2 = resolveSelection(view, view.state.doc, parse.sel);
|
|
4577
|
+
if (_sel2 && !_sel2.eq(view.state.selection)) {
|
|
4578
|
+
var _tr2 = view.state.tr.setSelection(_sel2);
|
|
4568
4579
|
if (compositionID) _tr2.setMeta("composition", compositionID);
|
|
4569
4580
|
view.dispatch(_tr2);
|
|
4570
4581
|
}
|
|
@@ -4641,8 +4652,8 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4641
4652
|
}
|
|
4642
4653
|
if (!tr) tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from));
|
|
4643
4654
|
if (parse.sel) {
|
|
4644
|
-
var
|
|
4645
|
-
if (
|
|
4655
|
+
var _sel3 = resolveSelection(view, tr.doc, parse.sel);
|
|
4656
|
+
if (_sel3 && !(chrome && android && view.composing && _sel3.empty && (change.start != change.endB || view.input.lastAndroidDelete < Date.now() - 100) && (_sel3.head == chFrom || _sel3.head == tr.mapping.map(chTo) - 1) || ie && _sel3.empty && _sel3.head == chFrom)) tr.setSelection(_sel3);
|
|
4646
4657
|
}
|
|
4647
4658
|
if (storedMarks) tr.ensureMarks(storedMarks);
|
|
4648
4659
|
if (compositionID) tr.setMeta("composition", compositionID);
|
|
@@ -5096,6 +5107,12 @@ var EditorView = function () {
|
|
|
5096
5107
|
key: "domSelectionRange",
|
|
5097
5108
|
value: function domSelectionRange() {
|
|
5098
5109
|
var sel = this.domSelection();
|
|
5110
|
+
if (!sel) return {
|
|
5111
|
+
focusNode: null,
|
|
5112
|
+
focusOffset: 0,
|
|
5113
|
+
anchorNode: null,
|
|
5114
|
+
anchorOffset: 0
|
|
5115
|
+
};
|
|
5099
5116
|
return safari && this.root.nodeType === 11 && deepActiveElement(this.dom.ownerDocument) == this.dom && safariShadowSelectionRange(this, sel) || sel;
|
|
5100
5117
|
}
|
|
5101
5118
|
}, {
|
|
@@ -5127,7 +5144,7 @@ function updateCursorWrapper(view) {
|
|
|
5127
5144
|
dom.setAttribute("alt", "");
|
|
5128
5145
|
view.cursorWrapper = {
|
|
5129
5146
|
dom: dom,
|
|
5130
|
-
deco: Decoration.widget(view.state.selection.
|
|
5147
|
+
deco: Decoration.widget(view.state.selection.from, dom, {
|
|
5131
5148
|
raw: true,
|
|
5132
5149
|
marks: view.markCursor
|
|
5133
5150
|
})
|
package/dist/index.js
CHANGED
|
@@ -659,6 +659,8 @@ function endOfTextblockHorizontal(view, state, dir) {
|
|
|
659
659
|
return false;
|
|
660
660
|
let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size;
|
|
661
661
|
let sel = view.domSelection();
|
|
662
|
+
if (!sel)
|
|
663
|
+
return $head.pos == $head.start() || $head.pos == $head.end();
|
|
662
664
|
// If the textblock is all LTR, or the browser doesn't support
|
|
663
665
|
// Selection.modify (Edge), fall back to a primitive approach
|
|
664
666
|
if (!maybeRTL.test($head.parent.textContent) || !sel.modify)
|
|
@@ -2281,12 +2283,21 @@ function removeClassOnSelectionChange(view) {
|
|
|
2281
2283
|
}
|
|
2282
2284
|
function selectCursorWrapper(view) {
|
|
2283
2285
|
let domSel = view.domSelection(), range = document.createRange();
|
|
2286
|
+
if (!domSel)
|
|
2287
|
+
return;
|
|
2284
2288
|
let node = view.cursorWrapper.dom, img = node.nodeName == "IMG";
|
|
2285
2289
|
if (img)
|
|
2286
|
-
range.
|
|
2290
|
+
range.setStart(node.parentNode, domIndex(node) + 1);
|
|
2287
2291
|
else
|
|
2288
|
-
range.
|
|
2289
|
-
|
|
2292
|
+
range.setStart(node, 0);
|
|
2293
|
+
let sel = view.state.selection;
|
|
2294
|
+
if (sel.empty) {
|
|
2295
|
+
range.collapse(true);
|
|
2296
|
+
}
|
|
2297
|
+
else {
|
|
2298
|
+
let end = view.domAtPos(sel.to);
|
|
2299
|
+
range.setEnd(end.node, end.offset);
|
|
2300
|
+
}
|
|
2290
2301
|
domSel.removeAllRanges();
|
|
2291
2302
|
domSel.addRange(range);
|
|
2292
2303
|
// Kludge to kill 'control selection' in IE11 when selecting an
|
|
@@ -2574,6 +2585,8 @@ function setSelFocus(view, node, offset) {
|
|
|
2574
2585
|
}
|
|
2575
2586
|
}
|
|
2576
2587
|
let sel = view.domSelection();
|
|
2588
|
+
if (!sel)
|
|
2589
|
+
return;
|
|
2577
2590
|
if (selectionCollapsed(sel)) {
|
|
2578
2591
|
let range = document.createRange();
|
|
2579
2592
|
range.setEnd(node, offset);
|
|
@@ -3140,6 +3153,8 @@ function runHandlerOnContext(view, propName, pos, inside, event) {
|
|
|
3140
3153
|
function updateSelection(view, selection, origin) {
|
|
3141
3154
|
if (!view.focused)
|
|
3142
3155
|
view.focus();
|
|
3156
|
+
if (view.state.selection.eq(selection))
|
|
3157
|
+
return;
|
|
3143
3158
|
let tr = view.state.tr.setSelection(selection);
|
|
3144
3159
|
if (origin == "pointer")
|
|
3145
3160
|
tr.setMeta("pointer", true);
|
|
@@ -3394,8 +3409,8 @@ const timeoutComposition = android ? 5000 : -1;
|
|
|
3394
3409
|
editHandlers.compositionstart = editHandlers.compositionupdate = view => {
|
|
3395
3410
|
if (!view.composing) {
|
|
3396
3411
|
view.domObserver.flush();
|
|
3397
|
-
let { state } = view, $pos = state.selection.$
|
|
3398
|
-
if (state.selection
|
|
3412
|
+
let { state } = view, $pos = state.selection.$to;
|
|
3413
|
+
if (state.selection instanceof TextSelection &&
|
|
3399
3414
|
(state.storedMarks ||
|
|
3400
3415
|
(!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)))) {
|
|
3401
3416
|
// Need to wrap the cursor in mark nodes different from the ones in the DOM context
|
|
@@ -3415,7 +3430,9 @@ editHandlers.compositionstart = editHandlers.compositionupdate = view => {
|
|
|
3415
3430
|
if (!before)
|
|
3416
3431
|
break;
|
|
3417
3432
|
if (before.nodeType == 3) {
|
|
3418
|
-
view.domSelection()
|
|
3433
|
+
let sel = view.domSelection();
|
|
3434
|
+
if (sel)
|
|
3435
|
+
sel.collapse(before, before.nodeValue.length);
|
|
3419
3436
|
break;
|
|
3420
3437
|
}
|
|
3421
3438
|
else {
|
|
@@ -5646,6 +5663,8 @@ class EditorView {
|
|
|
5646
5663
|
*/
|
|
5647
5664
|
domSelectionRange() {
|
|
5648
5665
|
let sel = this.domSelection();
|
|
5666
|
+
if (!sel)
|
|
5667
|
+
return { focusNode: null, focusOffset: 0, anchorNode: null, anchorOffset: 0 };
|
|
5649
5668
|
return safari && this.root.nodeType === 11 &&
|
|
5650
5669
|
deepActiveElement(this.dom.ownerDocument) == this.dom && safariShadowSelectionRange(this, sel) || sel;
|
|
5651
5670
|
}
|
|
@@ -5683,7 +5702,7 @@ function updateCursorWrapper(view) {
|
|
|
5683
5702
|
dom.className = "ProseMirror-separator";
|
|
5684
5703
|
dom.setAttribute("mark-placeholder", "true");
|
|
5685
5704
|
dom.setAttribute("alt", "");
|
|
5686
|
-
view.cursorWrapper = { dom, deco: Decoration.widget(view.state.selection.
|
|
5705
|
+
view.cursorWrapper = { dom, deco: Decoration.widget(view.state.selection.from, dom, { raw: true, marks: view.markCursor }) };
|
|
5687
5706
|
}
|
|
5688
5707
|
else {
|
|
5689
5708
|
view.cursorWrapper = null;
|
package/package.json
CHANGED
package/src/capturekeys.ts
CHANGED
package/src/domcoords.ts
CHANGED
|
@@ -465,7 +465,8 @@ function endOfTextblockHorizontal(view: EditorView, state: EditorState, dir: "le
|
|
|
465
465
|
let {$head} = state.selection
|
|
466
466
|
if (!$head.parent.isTextblock) return false
|
|
467
467
|
let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size
|
|
468
|
-
let sel = view.domSelection()
|
|
468
|
+
let sel: Selection = view.domSelection()!
|
|
469
|
+
if (!sel) return $head.pos == $head.start() || $head.pos == $head.end()
|
|
469
470
|
// If the textblock is all LTR, or the browser doesn't support
|
|
470
471
|
// Selection.modify (Edge), fall back to a primitive approach
|
|
471
472
|
if (!maybeRTL.test($head.parent.textContent) || !(sel as any).modify)
|
package/src/index.ts
CHANGED
|
@@ -489,13 +489,14 @@ export class EditorView {
|
|
|
489
489
|
/// @internal
|
|
490
490
|
domSelectionRange(): DOMSelectionRange {
|
|
491
491
|
let sel = this.domSelection()
|
|
492
|
+
if (!sel) return {focusNode: null, focusOffset: 0, anchorNode: null, anchorOffset: 0}
|
|
492
493
|
return browser.safari && this.root.nodeType === 11 &&
|
|
493
494
|
deepActiveElement(this.dom.ownerDocument) == this.dom && safariShadowSelectionRange(this, sel) || sel
|
|
494
495
|
}
|
|
495
496
|
|
|
496
497
|
/// @internal
|
|
497
|
-
domSelection(): DOMSelection {
|
|
498
|
-
return (this.root as Document).getSelection()
|
|
498
|
+
domSelection(): DOMSelection | null {
|
|
499
|
+
return (this.root as Document).getSelection()
|
|
499
500
|
}
|
|
500
501
|
}
|
|
501
502
|
|
|
@@ -526,7 +527,7 @@ function updateCursorWrapper(view: EditorView) {
|
|
|
526
527
|
dom.className = "ProseMirror-separator"
|
|
527
528
|
dom.setAttribute("mark-placeholder", "true")
|
|
528
529
|
dom.setAttribute("alt", "")
|
|
529
|
-
view.cursorWrapper = {dom, deco: Decoration.widget(view.state.selection.
|
|
530
|
+
view.cursorWrapper = {dom, deco: Decoration.widget(view.state.selection.from,
|
|
530
531
|
dom, {raw: true, marks: view.markCursor} as any)}
|
|
531
532
|
} else {
|
|
532
533
|
view.cursorWrapper = null
|
package/src/input.ts
CHANGED
|
@@ -183,6 +183,7 @@ function runHandlerOnContext(
|
|
|
183
183
|
|
|
184
184
|
function updateSelection(view: EditorView, selection: Selection, origin: string) {
|
|
185
185
|
if (!view.focused) view.focus()
|
|
186
|
+
if (view.state.selection.eq(selection)) return
|
|
186
187
|
let tr = view.state.tr.setSelection(selection)
|
|
187
188
|
if (origin == "pointer") tr.setMeta("pointer", true)
|
|
188
189
|
view.dispatch(tr)
|
|
@@ -453,8 +454,8 @@ const timeoutComposition = browser.android ? 5000 : -1
|
|
|
453
454
|
editHandlers.compositionstart = editHandlers.compositionupdate = view => {
|
|
454
455
|
if (!view.composing) {
|
|
455
456
|
view.domObserver.flush()
|
|
456
|
-
let {state} = view, $pos = state.selection.$
|
|
457
|
-
if (state.selection
|
|
457
|
+
let {state} = view, $pos = state.selection.$to
|
|
458
|
+
if (state.selection instanceof TextSelection &&
|
|
458
459
|
(state.storedMarks ||
|
|
459
460
|
(!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore!.marks.some(m => m.type.spec.inclusive === false)))) {
|
|
460
461
|
// Need to wrap the cursor in mark nodes different from the ones in the DOM context
|
|
@@ -472,7 +473,8 @@ editHandlers.compositionstart = editHandlers.compositionupdate = view => {
|
|
|
472
473
|
let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]
|
|
473
474
|
if (!before) break
|
|
474
475
|
if (before.nodeType == 3) {
|
|
475
|
-
view.domSelection()
|
|
476
|
+
let sel = view.domSelection()
|
|
477
|
+
if (sel) sel.collapse(before, before.nodeValue!.length)
|
|
476
478
|
break
|
|
477
479
|
} else {
|
|
478
480
|
node = before
|
package/src/selection.ts
CHANGED
|
@@ -136,10 +136,17 @@ function removeClassOnSelectionChange(view: EditorView) {
|
|
|
136
136
|
|
|
137
137
|
function selectCursorWrapper(view: EditorView) {
|
|
138
138
|
let domSel = view.domSelection(), range = document.createRange()
|
|
139
|
+
if (!domSel) return
|
|
139
140
|
let node = view.cursorWrapper!.dom, img = node.nodeName == "IMG"
|
|
140
|
-
if (img) range.
|
|
141
|
-
else range.
|
|
142
|
-
|
|
141
|
+
if (img) range.setStart(node.parentNode!, domIndex(node) + 1)
|
|
142
|
+
else range.setStart(node, 0)
|
|
143
|
+
let sel = view.state.selection
|
|
144
|
+
if (sel.empty) {
|
|
145
|
+
range.collapse(true)
|
|
146
|
+
} else {
|
|
147
|
+
let end = view.domAtPos(sel.to)
|
|
148
|
+
range.setEnd(end.node, end.offset)
|
|
149
|
+
}
|
|
143
150
|
domSel.removeAllRanges()
|
|
144
151
|
domSel.addRange(range)
|
|
145
152
|
// Kludge to kill 'control selection' in IE11 when selecting an
|