prosemirror-view 1.33.6 → 1.33.8
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 +16 -0
- package/dist/index.cjs +48 -11
- package/dist/index.js +40 -14
- package/package.json +1 -1
- package/src/domcoords.ts +5 -4
- package/src/domobserver.ts +25 -4
- package/src/input.ts +3 -2
- package/src/viewdesc.ts +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## 1.33.8 (2024-06-11)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
When composition happens with the cursor between two text nodes, use the last mutated one to guess which one is being changed.
|
|
6
|
+
|
|
7
|
+
## 1.33.7 (2024-05-31)
|
|
8
|
+
|
|
9
|
+
### Bug fixes
|
|
10
|
+
|
|
11
|
+
Ignore stray `<br>` nodes added to parent list elements when backspacing near uneditable content in Firefox.
|
|
12
|
+
|
|
13
|
+
Fix a crash where the editor tried to call `removeAttribute` on a text node.
|
|
14
|
+
|
|
15
|
+
Fix an issue where coordinates near nested blocks could inappropriately be assigned to be inside those blocks.
|
|
16
|
+
|
|
1
17
|
## 1.33.6 (2024-04-30)
|
|
2
18
|
|
|
3
19
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
4
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
3
7
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
4
8
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
5
9
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
@@ -387,11 +391,11 @@ function posFromCaret(view, node, offset, coords) {
|
|
|
387
391
|
if (cur == view.dom) break;
|
|
388
392
|
var desc = view.docView.nearestDesc(cur, true);
|
|
389
393
|
if (!desc) return null;
|
|
390
|
-
if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent
|
|
394
|
+
if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM)) {
|
|
391
395
|
var rect = desc.dom.getBoundingClientRect();
|
|
392
|
-
if (desc.node.isBlock && desc.parent
|
|
396
|
+
if (desc.node.isBlock && desc.parent) {
|
|
397
|
+
if (!sawBlock && rect.left > coords.left || rect.top > coords.top) outsideBlock = desc.posBefore;else if (!sawBlock && rect.right < coords.left || rect.bottom < coords.top) outsideBlock = desc.posAfter;
|
|
393
398
|
sawBlock = true;
|
|
394
|
-
if (rect.left > coords.left || rect.top > coords.top) outsideBlock = desc.posBefore;else if (rect.right < coords.left || rect.bottom < coords.top) outsideBlock = desc.posAfter;
|
|
395
399
|
}
|
|
396
400
|
if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) {
|
|
397
401
|
var before = desc.node.isBlock ? coords.top < (rect.top + rect.bottom) / 2 : coords.left < (rect.left + rect.right) / 2;
|
|
@@ -1387,8 +1391,10 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1387
1391
|
}, {
|
|
1388
1392
|
key: "deselectNode",
|
|
1389
1393
|
value: function deselectNode() {
|
|
1390
|
-
if (this.nodeDOM.nodeType == 1)
|
|
1391
|
-
|
|
1394
|
+
if (this.nodeDOM.nodeType == 1) {
|
|
1395
|
+
this.nodeDOM.classList.remove("ProseMirror-selectednode");
|
|
1396
|
+
if (this.contentDOM || !this.node.type.spec.draggable) this.dom.removeAttribute("draggable");
|
|
1397
|
+
}
|
|
1392
1398
|
}
|
|
1393
1399
|
}, {
|
|
1394
1400
|
key: "domAtom",
|
|
@@ -3085,7 +3091,7 @@ var MouseDown = function () {
|
|
|
3085
3091
|
}
|
|
3086
3092
|
var target = flushed ? null : event.target;
|
|
3087
3093
|
var targetDesc = target ? view.docView.nearestDesc(target, true) : null;
|
|
3088
|
-
this.target = targetDesc ? targetDesc.dom : null;
|
|
3094
|
+
this.target = targetDesc && targetDesc.dom.nodeType == 1 ? targetDesc.dom : null;
|
|
3089
3095
|
var selection = view.state.selection;
|
|
3090
3096
|
if (event.button == 0 && targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || selection instanceof prosemirrorState.NodeSelection && selection.from <= targetPos && selection.to > targetPos) this.mightDrag = {
|
|
3091
3097
|
node: targetNode,
|
|
@@ -3241,7 +3247,9 @@ function findCompositionNode(view) {
|
|
|
3241
3247
|
var textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset);
|
|
3242
3248
|
var textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset);
|
|
3243
3249
|
if (textBefore && textAfter && textBefore != textAfter) {
|
|
3244
|
-
var descAfter = textAfter.pmViewDesc
|
|
3250
|
+
var descAfter = textAfter.pmViewDesc,
|
|
3251
|
+
lastChanged = view.domObserver.lastChangedTextNode;
|
|
3252
|
+
if (textBefore == lastChanged || textAfter == lastChanged) return lastChanged;
|
|
3245
3253
|
if (!descAfter || !descAfter.isText(textAfter.nodeValue)) {
|
|
3246
3254
|
return textAfter;
|
|
3247
3255
|
} else if (view.input.compositionNode == textAfter) {
|
|
@@ -4105,6 +4113,7 @@ var DOMObserver = function () {
|
|
|
4105
4113
|
this.currentSelection = new SelectionState();
|
|
4106
4114
|
this.onCharData = null;
|
|
4107
4115
|
this.suppressingSelectionUpdates = false;
|
|
4116
|
+
this.lastChangedTextNode = null;
|
|
4108
4117
|
this.observer = window.MutationObserver && new window.MutationObserver(function (mutations) {
|
|
4109
4118
|
for (var i = 0; i < mutations.length; i++) _this11.queue.push(mutations[i]);
|
|
4110
4119
|
if (ie && ie_version <= 11 && mutations.some(function (m) {
|
|
@@ -4265,14 +4274,30 @@ var DOMObserver = function () {
|
|
|
4265
4274
|
}
|
|
4266
4275
|
}
|
|
4267
4276
|
}
|
|
4268
|
-
if (gecko && added.length
|
|
4277
|
+
if (gecko && added.length) {
|
|
4269
4278
|
var brs = added.filter(function (n) {
|
|
4270
4279
|
return n.nodeName == "BR";
|
|
4271
4280
|
});
|
|
4272
4281
|
if (brs.length == 2) {
|
|
4273
|
-
var
|
|
4274
|
-
|
|
4282
|
+
var _brs = _slicedToArray(brs, 2),
|
|
4283
|
+
a = _brs[0],
|
|
4284
|
+
b = _brs[1];
|
|
4275
4285
|
if (a.parentNode && a.parentNode.parentNode == b.parentNode) b.remove();else a.remove();
|
|
4286
|
+
} else {
|
|
4287
|
+
var focusNode = this.currentSelection.focusNode;
|
|
4288
|
+
var _iterator3 = _createForOfIteratorHelper(brs),
|
|
4289
|
+
_step3;
|
|
4290
|
+
try {
|
|
4291
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
4292
|
+
var br = _step3.value;
|
|
4293
|
+
var parent = br.parentNode;
|
|
4294
|
+
if (parent && parent.nodeName == "LI" && (!focusNode || blockParent(view, focusNode) != parent)) br.remove();
|
|
4295
|
+
}
|
|
4296
|
+
} catch (err) {
|
|
4297
|
+
_iterator3.e(err);
|
|
4298
|
+
} finally {
|
|
4299
|
+
_iterator3.f();
|
|
4300
|
+
}
|
|
4276
4301
|
}
|
|
4277
4302
|
}
|
|
4278
4303
|
var readSel = null;
|
|
@@ -4299,7 +4324,11 @@ var DOMObserver = function () {
|
|
|
4299
4324
|
if (mut.type == "attributes" && (desc == this.view.docView || mut.attributeName == "contenteditable" || mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style"))) return null;
|
|
4300
4325
|
if (!desc || desc.ignoreMutation(mut)) return null;
|
|
4301
4326
|
if (mut.type == "childList") {
|
|
4302
|
-
for (var i = 0; i < mut.addedNodes.length; i++)
|
|
4327
|
+
for (var i = 0; i < mut.addedNodes.length; i++) {
|
|
4328
|
+
var node = mut.addedNodes[i];
|
|
4329
|
+
added.push(node);
|
|
4330
|
+
if (node.nodeType == 3) this.lastChangedTextNode = node;
|
|
4331
|
+
}
|
|
4303
4332
|
if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target)) return {
|
|
4304
4333
|
from: desc.posBefore,
|
|
4305
4334
|
to: desc.posAfter
|
|
@@ -4329,6 +4358,7 @@ var DOMObserver = function () {
|
|
|
4329
4358
|
to: desc.posAtEnd + desc.border
|
|
4330
4359
|
};
|
|
4331
4360
|
} else {
|
|
4361
|
+
this.lastChangedTextNode = mut.target;
|
|
4332
4362
|
return {
|
|
4333
4363
|
from: desc.posAtStart,
|
|
4334
4364
|
to: desc.posAtEnd,
|
|
@@ -4387,6 +4417,13 @@ function safariShadowSelectionRange(view, selection) {
|
|
|
4387
4417
|
view.dom.removeEventListener("beforeinput", read, true);
|
|
4388
4418
|
return found ? rangeToSelectionRange(view, found) : null;
|
|
4389
4419
|
}
|
|
4420
|
+
function blockParent(view, node) {
|
|
4421
|
+
for (var p = node.parentNode; p && p != view.dom; p = p.parentNode) {
|
|
4422
|
+
var desc = view.docView.nearestDesc(p, true);
|
|
4423
|
+
if (desc && desc.node.isBlock) return p;
|
|
4424
|
+
}
|
|
4425
|
+
return null;
|
|
4426
|
+
}
|
|
4390
4427
|
function parseBetween(view, from_, to_) {
|
|
4391
4428
|
var _view$docView$parseRa = view.docView.parseRange(from_, to_),
|
|
4392
4429
|
parent = _view$docView$parseRa.node,
|
package/dist/index.js
CHANGED
|
@@ -396,14 +396,15 @@ function posFromCaret(view, node, offset, coords) {
|
|
|
396
396
|
let desc = view.docView.nearestDesc(cur, true);
|
|
397
397
|
if (!desc)
|
|
398
398
|
return null;
|
|
399
|
-
if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent
|
|
399
|
+
if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM)) {
|
|
400
400
|
let rect = desc.dom.getBoundingClientRect();
|
|
401
|
-
if (desc.node.isBlock && desc.parent
|
|
402
|
-
|
|
403
|
-
if (rect.left > coords.left || rect.top > coords.top)
|
|
401
|
+
if (desc.node.isBlock && desc.parent) {
|
|
402
|
+
// Only apply the horizontal test to the innermost block. Vertical for any parent.
|
|
403
|
+
if (!sawBlock && rect.left > coords.left || rect.top > coords.top)
|
|
404
404
|
outsideBlock = desc.posBefore;
|
|
405
|
-
else if (rect.right < coords.left || rect.bottom < coords.top)
|
|
405
|
+
else if (!sawBlock && rect.right < coords.left || rect.bottom < coords.top)
|
|
406
406
|
outsideBlock = desc.posAfter;
|
|
407
|
+
sawBlock = true;
|
|
407
408
|
}
|
|
408
409
|
if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) {
|
|
409
410
|
// If we are inside a leaf, return the side of the leaf closer to the coords
|
|
@@ -1452,10 +1453,11 @@ class NodeViewDesc extends ViewDesc {
|
|
|
1452
1453
|
}
|
|
1453
1454
|
// Remove selected node marking from this node.
|
|
1454
1455
|
deselectNode() {
|
|
1455
|
-
if (this.nodeDOM.nodeType == 1)
|
|
1456
|
+
if (this.nodeDOM.nodeType == 1) {
|
|
1456
1457
|
this.nodeDOM.classList.remove("ProseMirror-selectednode");
|
|
1457
|
-
|
|
1458
|
-
|
|
1458
|
+
if (this.contentDOM || !this.node.type.spec.draggable)
|
|
1459
|
+
this.dom.removeAttribute("draggable");
|
|
1460
|
+
}
|
|
1459
1461
|
}
|
|
1460
1462
|
get domAtom() { return this.node.isAtom; }
|
|
1461
1463
|
}
|
|
@@ -3270,7 +3272,7 @@ class MouseDown {
|
|
|
3270
3272
|
}
|
|
3271
3273
|
const target = flushed ? null : event.target;
|
|
3272
3274
|
const targetDesc = target ? view.docView.nearestDesc(target, true) : null;
|
|
3273
|
-
this.target = targetDesc ? targetDesc.dom : null;
|
|
3275
|
+
this.target = targetDesc && targetDesc.dom.nodeType == 1 ? targetDesc.dom : null;
|
|
3274
3276
|
let { selection } = view.state;
|
|
3275
3277
|
if (event.button == 0 &&
|
|
3276
3278
|
targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
|
|
@@ -3458,7 +3460,9 @@ function findCompositionNode(view) {
|
|
|
3458
3460
|
let textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset);
|
|
3459
3461
|
let textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset);
|
|
3460
3462
|
if (textBefore && textAfter && textBefore != textAfter) {
|
|
3461
|
-
let descAfter = textAfter.pmViewDesc;
|
|
3463
|
+
let descAfter = textAfter.pmViewDesc, lastChanged = view.domObserver.lastChangedTextNode;
|
|
3464
|
+
if (textBefore == lastChanged || textAfter == lastChanged)
|
|
3465
|
+
return lastChanged;
|
|
3462
3466
|
if (!descAfter || !descAfter.isText(textAfter.nodeValue)) {
|
|
3463
3467
|
return textAfter;
|
|
3464
3468
|
}
|
|
@@ -4470,6 +4474,7 @@ class DOMObserver {
|
|
|
4470
4474
|
this.currentSelection = new SelectionState;
|
|
4471
4475
|
this.onCharData = null;
|
|
4472
4476
|
this.suppressingSelectionUpdates = false;
|
|
4477
|
+
this.lastChangedTextNode = null;
|
|
4473
4478
|
this.observer = window.MutationObserver &&
|
|
4474
4479
|
new window.MutationObserver(mutations => {
|
|
4475
4480
|
for (let i = 0; i < mutations.length; i++)
|
|
@@ -4602,15 +4607,23 @@ class DOMObserver {
|
|
|
4602
4607
|
}
|
|
4603
4608
|
}
|
|
4604
4609
|
}
|
|
4605
|
-
if (gecko && added.length
|
|
4610
|
+
if (gecko && added.length) {
|
|
4606
4611
|
let brs = added.filter(n => n.nodeName == "BR");
|
|
4607
4612
|
if (brs.length == 2) {
|
|
4608
|
-
let a
|
|
4613
|
+
let [a, b] = brs;
|
|
4609
4614
|
if (a.parentNode && a.parentNode.parentNode == b.parentNode)
|
|
4610
4615
|
b.remove();
|
|
4611
4616
|
else
|
|
4612
4617
|
a.remove();
|
|
4613
4618
|
}
|
|
4619
|
+
else {
|
|
4620
|
+
let { focusNode } = this.currentSelection;
|
|
4621
|
+
for (let br of brs) {
|
|
4622
|
+
let parent = br.parentNode;
|
|
4623
|
+
if (parent && parent.nodeName == "LI" && (!focusNode || blockParent(view, focusNode) != parent))
|
|
4624
|
+
br.remove();
|
|
4625
|
+
}
|
|
4626
|
+
}
|
|
4614
4627
|
}
|
|
4615
4628
|
let readSel = null;
|
|
4616
4629
|
// If it looks like the browser has reset the selection to the
|
|
@@ -4651,8 +4664,12 @@ class DOMObserver {
|
|
|
4651
4664
|
if (!desc || desc.ignoreMutation(mut))
|
|
4652
4665
|
return null;
|
|
4653
4666
|
if (mut.type == "childList") {
|
|
4654
|
-
for (let i = 0; i < mut.addedNodes.length; i++)
|
|
4655
|
-
|
|
4667
|
+
for (let i = 0; i < mut.addedNodes.length; i++) {
|
|
4668
|
+
let node = mut.addedNodes[i];
|
|
4669
|
+
added.push(node);
|
|
4670
|
+
if (node.nodeType == 3)
|
|
4671
|
+
this.lastChangedTextNode = node;
|
|
4672
|
+
}
|
|
4656
4673
|
if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target))
|
|
4657
4674
|
return { from: desc.posBefore, to: desc.posAfter };
|
|
4658
4675
|
let prev = mut.previousSibling, next = mut.nextSibling;
|
|
@@ -4679,6 +4696,7 @@ class DOMObserver {
|
|
|
4679
4696
|
return { from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border };
|
|
4680
4697
|
}
|
|
4681
4698
|
else { // "characterData"
|
|
4699
|
+
this.lastChangedTextNode = mut.target;
|
|
4682
4700
|
return {
|
|
4683
4701
|
from: desc.posAtStart,
|
|
4684
4702
|
to: desc.posAtEnd,
|
|
@@ -4740,6 +4758,14 @@ function safariShadowSelectionRange(view, selection) {
|
|
|
4740
4758
|
view.dom.removeEventListener("beforeinput", read, true);
|
|
4741
4759
|
return found ? rangeToSelectionRange(view, found) : null;
|
|
4742
4760
|
}
|
|
4761
|
+
function blockParent(view, node) {
|
|
4762
|
+
for (let p = node.parentNode; p && p != view.dom; p = p.parentNode) {
|
|
4763
|
+
let desc = view.docView.nearestDesc(p, true);
|
|
4764
|
+
if (desc && desc.node.isBlock)
|
|
4765
|
+
return p;
|
|
4766
|
+
}
|
|
4767
|
+
return null;
|
|
4768
|
+
}
|
|
4743
4769
|
|
|
4744
4770
|
// Note that all referencing and parsing is done with the
|
|
4745
4771
|
// start-of-operation selection and document, since that's the one
|
package/package.json
CHANGED
package/src/domcoords.ts
CHANGED
|
@@ -227,12 +227,13 @@ function posFromCaret(view: EditorView, node: Node, offset: number, coords: {top
|
|
|
227
227
|
if (cur == view.dom) break
|
|
228
228
|
let desc = view.docView.nearestDesc(cur, true)
|
|
229
229
|
if (!desc) return null
|
|
230
|
-
if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent
|
|
230
|
+
if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM)) {
|
|
231
231
|
let rect = (desc.dom as HTMLElement).getBoundingClientRect()
|
|
232
|
-
if (desc.node.isBlock && desc.parent
|
|
232
|
+
if (desc.node.isBlock && desc.parent) {
|
|
233
|
+
// Only apply the horizontal test to the innermost block. Vertical for any parent.
|
|
234
|
+
if (!sawBlock && rect.left > coords.left || rect.top > coords.top) outsideBlock = desc.posBefore
|
|
235
|
+
else if (!sawBlock && rect.right < coords.left || rect.bottom < coords.top) outsideBlock = desc.posAfter
|
|
233
236
|
sawBlock = true
|
|
234
|
-
if (rect.left > coords.left || rect.top > coords.top) outsideBlock = desc.posBefore
|
|
235
|
-
else if (rect.right < coords.left || rect.bottom < coords.top) outsideBlock = desc.posAfter
|
|
236
237
|
}
|
|
237
238
|
if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) {
|
|
238
239
|
// If we are inside a leaf, return the side of the leaf closer to the coords
|
package/src/domobserver.ts
CHANGED
|
@@ -43,6 +43,7 @@ export class DOMObserver {
|
|
|
43
43
|
currentSelection = new SelectionState
|
|
44
44
|
onCharData: ((e: Event) => void) | null = null
|
|
45
45
|
suppressingSelectionUpdates = false
|
|
46
|
+
lastChangedTextNode: Text | null = null
|
|
46
47
|
|
|
47
48
|
constructor(
|
|
48
49
|
readonly view: EditorView,
|
|
@@ -183,12 +184,19 @@ export class DOMObserver {
|
|
|
183
184
|
}
|
|
184
185
|
}
|
|
185
186
|
|
|
186
|
-
if (browser.gecko && added.length
|
|
187
|
-
let brs = added.filter(n => n.nodeName == "BR")
|
|
187
|
+
if (browser.gecko && added.length) {
|
|
188
|
+
let brs = added.filter(n => n.nodeName == "BR") as HTMLElement[]
|
|
188
189
|
if (brs.length == 2) {
|
|
189
|
-
let a
|
|
190
|
+
let [a, b] = brs
|
|
190
191
|
if (a.parentNode && a.parentNode.parentNode == b.parentNode) b.remove()
|
|
191
192
|
else a.remove()
|
|
193
|
+
} else {
|
|
194
|
+
let {focusNode} = this.currentSelection
|
|
195
|
+
for (let br of brs) {
|
|
196
|
+
let parent = br.parentNode
|
|
197
|
+
if (parent && parent.nodeName == "LI" && (!focusNode || blockParent(view, focusNode) != parent))
|
|
198
|
+
br.remove()
|
|
199
|
+
}
|
|
192
200
|
}
|
|
193
201
|
}
|
|
194
202
|
|
|
@@ -228,7 +236,11 @@ export class DOMObserver {
|
|
|
228
236
|
if (!desc || desc.ignoreMutation(mut)) return null
|
|
229
237
|
|
|
230
238
|
if (mut.type == "childList") {
|
|
231
|
-
for (let i = 0; i < mut.addedNodes.length; i++)
|
|
239
|
+
for (let i = 0; i < mut.addedNodes.length; i++) {
|
|
240
|
+
let node = mut.addedNodes[i]
|
|
241
|
+
added.push(node)
|
|
242
|
+
if (node.nodeType == 3) this.lastChangedTextNode = node as Text
|
|
243
|
+
}
|
|
232
244
|
if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target))
|
|
233
245
|
return {from: desc.posBefore, to: desc.posAfter}
|
|
234
246
|
let prev = mut.previousSibling, next = mut.nextSibling
|
|
@@ -251,6 +263,7 @@ export class DOMObserver {
|
|
|
251
263
|
} else if (mut.type == "attributes") {
|
|
252
264
|
return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border}
|
|
253
265
|
} else { // "characterData"
|
|
266
|
+
this.lastChangedTextNode = mut.target as Text
|
|
254
267
|
return {
|
|
255
268
|
from: desc.posAtStart,
|
|
256
269
|
to: desc.posAtEnd,
|
|
@@ -317,3 +330,11 @@ export function safariShadowSelectionRange(view: EditorView, selection: DOMSelec
|
|
|
317
330
|
|
|
318
331
|
return found ? rangeToSelectionRange(view, found) : null
|
|
319
332
|
}
|
|
333
|
+
|
|
334
|
+
function blockParent(view: EditorView, node: DOMNode): Node | null {
|
|
335
|
+
for (let p = node.parentNode; p && p != view.dom; p = p.parentNode) {
|
|
336
|
+
let desc = view.docView.nearestDesc(p, true)
|
|
337
|
+
if (desc && desc.node.isBlock) return p
|
|
338
|
+
}
|
|
339
|
+
return null
|
|
340
|
+
}
|
package/src/input.ts
CHANGED
|
@@ -326,7 +326,7 @@ class MouseDown {
|
|
|
326
326
|
|
|
327
327
|
const target = flushed ? null : event.target as HTMLElement
|
|
328
328
|
const targetDesc = target ? view.docView.nearestDesc(target, true) : null
|
|
329
|
-
this.target = targetDesc ? targetDesc.dom as HTMLElement : null
|
|
329
|
+
this.target = targetDesc && targetDesc.dom.nodeType == 1 ? targetDesc.dom as HTMLElement : null
|
|
330
330
|
|
|
331
331
|
let {selection} = view.state
|
|
332
332
|
if (event.button == 0 &&
|
|
@@ -517,7 +517,8 @@ export function findCompositionNode(view: EditorView) {
|
|
|
517
517
|
let textBefore = textNodeBefore(sel.focusNode, sel.focusOffset)
|
|
518
518
|
let textAfter = textNodeAfter(sel.focusNode, sel.focusOffset)
|
|
519
519
|
if (textBefore && textAfter && textBefore != textAfter) {
|
|
520
|
-
let descAfter = textAfter.pmViewDesc
|
|
520
|
+
let descAfter = textAfter.pmViewDesc, lastChanged = view.domObserver.lastChangedTextNode
|
|
521
|
+
if (textBefore == lastChanged || textAfter == lastChanged) return lastChanged
|
|
521
522
|
if (!descAfter || !descAfter.isText(textAfter.nodeValue!)) {
|
|
522
523
|
return textAfter
|
|
523
524
|
} else if (view.input.compositionNode == textAfter) {
|
package/src/viewdesc.ts
CHANGED
|
@@ -834,8 +834,10 @@ export class NodeViewDesc extends ViewDesc {
|
|
|
834
834
|
|
|
835
835
|
// Remove selected node marking from this node.
|
|
836
836
|
deselectNode() {
|
|
837
|
-
if (this.nodeDOM.nodeType == 1)
|
|
838
|
-
|
|
837
|
+
if (this.nodeDOM.nodeType == 1) {
|
|
838
|
+
;(this.nodeDOM as HTMLElement).classList.remove("ProseMirror-selectednode")
|
|
839
|
+
if (this.contentDOM || !this.node.type.spec.draggable) (this.dom as HTMLElement).removeAttribute("draggable")
|
|
840
|
+
}
|
|
839
841
|
}
|
|
840
842
|
|
|
841
843
|
get domAtom() { return this.node.isAtom }
|