prosemirror-view 1.33.7 → 1.33.9
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 +14 -0
- package/dist/index.cjs +15 -7
- package/dist/index.js +17 -6
- package/package.json +1 -1
- package/src/domobserver.ts +7 -1
- package/src/input.ts +5 -2
- package/src/viewdesc.ts +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 1.33.9 (2024-07-18)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix an issue where dragging an image on Chrome versions before 121 failed to put the image file in the clipboard data.
|
|
6
|
+
|
|
7
|
+
Enable cross-site scripting protection hack when rendering nodes and marks inside the editor.
|
|
8
|
+
|
|
9
|
+
## 1.33.8 (2024-06-11)
|
|
10
|
+
|
|
11
|
+
### Bug fixes
|
|
12
|
+
|
|
13
|
+
When composition happens with the cursor between two text nodes, use the last mutated one to guess which one is being changed.
|
|
14
|
+
|
|
1
15
|
## 1.33.7 (2024-05-31)
|
|
2
16
|
|
|
3
17
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -1216,7 +1216,7 @@ var MarkViewDesc = function (_ViewDesc3) {
|
|
|
1216
1216
|
value: function create(parent, mark, inline, view) {
|
|
1217
1217
|
var custom = view.nodeViews[mark.type.name];
|
|
1218
1218
|
var spec = custom && custom(mark, view, inline);
|
|
1219
|
-
if (!spec || !spec.dom) spec = prosemirrorModel.DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline));
|
|
1219
|
+
if (!spec || !spec.dom) spec = prosemirrorModel.DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline), null, mark.attrs);
|
|
1220
1220
|
return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom);
|
|
1221
1221
|
}
|
|
1222
1222
|
}]);
|
|
@@ -1415,9 +1415,9 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1415
1415
|
if (node.isText) {
|
|
1416
1416
|
if (!dom) dom = document.createTextNode(node.text);else if (dom.nodeType != 3) throw new RangeError("Text must be rendered as a DOM text node");
|
|
1417
1417
|
} else if (!dom) {
|
|
1418
|
-
var
|
|
1419
|
-
dom =
|
|
1420
|
-
contentDOM =
|
|
1418
|
+
var _spec = prosemirrorModel.DOMSerializer.renderSpec(document, node.type.spec.toDOM(node), null, node.attrs);
|
|
1419
|
+
dom = _spec.dom;
|
|
1420
|
+
contentDOM = _spec.contentDOM;
|
|
1421
1421
|
}
|
|
1422
1422
|
if (!contentDOM && !node.isText && dom.nodeName != "BR") {
|
|
1423
1423
|
if (!dom.hasAttribute("contenteditable")) dom.contentEditable = "false";
|
|
@@ -3247,7 +3247,9 @@ function findCompositionNode(view) {
|
|
|
3247
3247
|
var textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset);
|
|
3248
3248
|
var textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset);
|
|
3249
3249
|
if (textBefore && textAfter && textBefore != textAfter) {
|
|
3250
|
-
var descAfter = textAfter.pmViewDesc
|
|
3250
|
+
var descAfter = textAfter.pmViewDesc,
|
|
3251
|
+
lastChanged = view.domObserver.lastChangedTextNode;
|
|
3252
|
+
if (textBefore == lastChanged || textAfter == lastChanged) return lastChanged;
|
|
3251
3253
|
if (!descAfter || !descAfter.isText(textAfter.nodeValue)) {
|
|
3252
3254
|
return textAfter;
|
|
3253
3255
|
} else if (view.input.compositionNode == textAfter) {
|
|
@@ -3378,7 +3380,7 @@ handlers.dragstart = function (view, _event) {
|
|
|
3378
3380
|
dom = _serializeForClipboar2.dom,
|
|
3379
3381
|
text = _serializeForClipboar2.text,
|
|
3380
3382
|
slice = _serializeForClipboar2.slice;
|
|
3381
|
-
event.dataTransfer.clearData();
|
|
3383
|
+
if (!event.dataTransfer.files.length || !chrome || chrome_version > 120) event.dataTransfer.clearData();
|
|
3382
3384
|
event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML);
|
|
3383
3385
|
event.dataTransfer.effectAllowed = "copyMove";
|
|
3384
3386
|
if (!brokenClipboardAPI) event.dataTransfer.setData("text/plain", text);
|
|
@@ -4111,6 +4113,7 @@ var DOMObserver = function () {
|
|
|
4111
4113
|
this.currentSelection = new SelectionState();
|
|
4112
4114
|
this.onCharData = null;
|
|
4113
4115
|
this.suppressingSelectionUpdates = false;
|
|
4116
|
+
this.lastChangedTextNode = null;
|
|
4114
4117
|
this.observer = window.MutationObserver && new window.MutationObserver(function (mutations) {
|
|
4115
4118
|
for (var i = 0; i < mutations.length; i++) _this11.queue.push(mutations[i]);
|
|
4116
4119
|
if (ie && ie_version <= 11 && mutations.some(function (m) {
|
|
@@ -4321,7 +4324,11 @@ var DOMObserver = function () {
|
|
|
4321
4324
|
if (mut.type == "attributes" && (desc == this.view.docView || mut.attributeName == "contenteditable" || mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style"))) return null;
|
|
4322
4325
|
if (!desc || desc.ignoreMutation(mut)) return null;
|
|
4323
4326
|
if (mut.type == "childList") {
|
|
4324
|
-
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
|
+
}
|
|
4325
4332
|
if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target)) return {
|
|
4326
4333
|
from: desc.posBefore,
|
|
4327
4334
|
to: desc.posAfter
|
|
@@ -4351,6 +4358,7 @@ var DOMObserver = function () {
|
|
|
4351
4358
|
to: desc.posAtEnd + desc.border
|
|
4352
4359
|
};
|
|
4353
4360
|
} else {
|
|
4361
|
+
this.lastChangedTextNode = mut.target;
|
|
4354
4362
|
return {
|
|
4355
4363
|
from: desc.posAtStart,
|
|
4356
4364
|
to: desc.posAtEnd,
|
package/dist/index.js
CHANGED
|
@@ -1195,7 +1195,7 @@ class MarkViewDesc extends ViewDesc {
|
|
|
1195
1195
|
let custom = view.nodeViews[mark.type.name];
|
|
1196
1196
|
let spec = custom && custom(mark, view, inline);
|
|
1197
1197
|
if (!spec || !spec.dom)
|
|
1198
|
-
spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline));
|
|
1198
|
+
spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline), null, mark.attrs);
|
|
1199
1199
|
return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom);
|
|
1200
1200
|
}
|
|
1201
1201
|
parseRule() {
|
|
@@ -1267,7 +1267,8 @@ class NodeViewDesc extends ViewDesc {
|
|
|
1267
1267
|
throw new RangeError("Text must be rendered as a DOM text node");
|
|
1268
1268
|
}
|
|
1269
1269
|
else if (!dom) {
|
|
1270
|
-
|
|
1270
|
+
let spec = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node), null, node.attrs);
|
|
1271
|
+
({ dom, contentDOM } = spec);
|
|
1271
1272
|
}
|
|
1272
1273
|
if (!contentDOM && !node.isText && dom.nodeName != "BR") { // Chrome gets confused by <br contenteditable=false>
|
|
1273
1274
|
if (!dom.hasAttribute("contenteditable"))
|
|
@@ -3460,7 +3461,9 @@ function findCompositionNode(view) {
|
|
|
3460
3461
|
let textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset);
|
|
3461
3462
|
let textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset);
|
|
3462
3463
|
if (textBefore && textAfter && textBefore != textAfter) {
|
|
3463
|
-
let descAfter = textAfter.pmViewDesc;
|
|
3464
|
+
let descAfter = textAfter.pmViewDesc, lastChanged = view.domObserver.lastChangedTextNode;
|
|
3465
|
+
if (textBefore == lastChanged || textAfter == lastChanged)
|
|
3466
|
+
return lastChanged;
|
|
3464
3467
|
if (!descAfter || !descAfter.isText(textAfter.nodeValue)) {
|
|
3465
3468
|
return textAfter;
|
|
3466
3469
|
}
|
|
@@ -3629,7 +3632,9 @@ handlers.dragstart = (view, _event) => {
|
|
|
3629
3632
|
}
|
|
3630
3633
|
let draggedSlice = (node || view.state.selection).content();
|
|
3631
3634
|
let { dom, text, slice } = serializeForClipboard(view, draggedSlice);
|
|
3632
|
-
|
|
3635
|
+
// Pre-120 Chrome versions clear files when calling `clearData` (#1472)
|
|
3636
|
+
if (!event.dataTransfer.files.length || !chrome || chrome_version > 120)
|
|
3637
|
+
event.dataTransfer.clearData();
|
|
3633
3638
|
event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML);
|
|
3634
3639
|
// See https://github.com/ProseMirror/prosemirror/issues/1156
|
|
3635
3640
|
event.dataTransfer.effectAllowed = "copyMove";
|
|
@@ -4472,6 +4477,7 @@ class DOMObserver {
|
|
|
4472
4477
|
this.currentSelection = new SelectionState;
|
|
4473
4478
|
this.onCharData = null;
|
|
4474
4479
|
this.suppressingSelectionUpdates = false;
|
|
4480
|
+
this.lastChangedTextNode = null;
|
|
4475
4481
|
this.observer = window.MutationObserver &&
|
|
4476
4482
|
new window.MutationObserver(mutations => {
|
|
4477
4483
|
for (let i = 0; i < mutations.length; i++)
|
|
@@ -4661,8 +4667,12 @@ class DOMObserver {
|
|
|
4661
4667
|
if (!desc || desc.ignoreMutation(mut))
|
|
4662
4668
|
return null;
|
|
4663
4669
|
if (mut.type == "childList") {
|
|
4664
|
-
for (let i = 0; i < mut.addedNodes.length; i++)
|
|
4665
|
-
|
|
4670
|
+
for (let i = 0; i < mut.addedNodes.length; i++) {
|
|
4671
|
+
let node = mut.addedNodes[i];
|
|
4672
|
+
added.push(node);
|
|
4673
|
+
if (node.nodeType == 3)
|
|
4674
|
+
this.lastChangedTextNode = node;
|
|
4675
|
+
}
|
|
4666
4676
|
if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target))
|
|
4667
4677
|
return { from: desc.posBefore, to: desc.posAfter };
|
|
4668
4678
|
let prev = mut.previousSibling, next = mut.nextSibling;
|
|
@@ -4689,6 +4699,7 @@ class DOMObserver {
|
|
|
4689
4699
|
return { from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border };
|
|
4690
4700
|
}
|
|
4691
4701
|
else { // "characterData"
|
|
4702
|
+
this.lastChangedTextNode = mut.target;
|
|
4692
4703
|
return {
|
|
4693
4704
|
from: desc.posAtStart,
|
|
4694
4705
|
to: desc.posAtEnd,
|
package/package.json
CHANGED
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,
|
|
@@ -235,7 +236,11 @@ export class DOMObserver {
|
|
|
235
236
|
if (!desc || desc.ignoreMutation(mut)) return null
|
|
236
237
|
|
|
237
238
|
if (mut.type == "childList") {
|
|
238
|
-
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
|
+
}
|
|
239
244
|
if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target))
|
|
240
245
|
return {from: desc.posBefore, to: desc.posAfter}
|
|
241
246
|
let prev = mut.previousSibling, next = mut.nextSibling
|
|
@@ -258,6 +263,7 @@ export class DOMObserver {
|
|
|
258
263
|
} else if (mut.type == "attributes") {
|
|
259
264
|
return {from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border}
|
|
260
265
|
} else { // "characterData"
|
|
266
|
+
this.lastChangedTextNode = mut.target as Text
|
|
261
267
|
return {
|
|
262
268
|
from: desc.posAtStart,
|
|
263
269
|
to: desc.posAtEnd,
|
package/src/input.ts
CHANGED
|
@@ -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) {
|
|
@@ -676,7 +677,9 @@ handlers.dragstart = (view, _event) => {
|
|
|
676
677
|
}
|
|
677
678
|
let draggedSlice = (node || view.state.selection).content()
|
|
678
679
|
let {dom, text, slice} = serializeForClipboard(view, draggedSlice)
|
|
679
|
-
|
|
680
|
+
// Pre-120 Chrome versions clear files when calling `clearData` (#1472)
|
|
681
|
+
if (!event.dataTransfer.files.length || !browser.chrome || browser.chrome_version > 120)
|
|
682
|
+
event.dataTransfer.clearData()
|
|
680
683
|
event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML)
|
|
681
684
|
// See https://github.com/ProseMirror/prosemirror/issues/1156
|
|
682
685
|
event.dataTransfer.effectAllowed = "copyMove"
|
package/src/viewdesc.ts
CHANGED
|
@@ -572,7 +572,7 @@ class MarkViewDesc extends ViewDesc {
|
|
|
572
572
|
let custom = view.nodeViews[mark.type.name]
|
|
573
573
|
let spec: {dom: HTMLElement, contentDOM?: HTMLElement} = custom && (custom as any)(mark, view, inline)
|
|
574
574
|
if (!spec || !spec.dom)
|
|
575
|
-
spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM!(mark, inline)) as any
|
|
575
|
+
spec = (DOMSerializer.renderSpec as any)(document, mark.type.spec.toDOM!(mark, inline), null, mark.attrs) as any
|
|
576
576
|
return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom as HTMLElement)
|
|
577
577
|
}
|
|
578
578
|
|
|
@@ -647,7 +647,8 @@ export class NodeViewDesc extends ViewDesc {
|
|
|
647
647
|
if (!dom) dom = document.createTextNode(node.text!)
|
|
648
648
|
else if (dom.nodeType != 3) throw new RangeError("Text must be rendered as a DOM text node")
|
|
649
649
|
} else if (!dom) {
|
|
650
|
-
|
|
650
|
+
let spec = (DOMSerializer.renderSpec as any)(document, node.type.spec.toDOM!(node), null, node.attrs)
|
|
651
|
+
;({dom, contentDOM} = spec as {dom: DOMNode, contentDOM?: HTMLElement})
|
|
651
652
|
}
|
|
652
653
|
if (!contentDOM && !node.isText && dom.nodeName != "BR") { // Chrome gets confused by <br contenteditable=false>
|
|
653
654
|
if (!(dom as HTMLElement).hasAttribute("contenteditable")) (dom as HTMLElement).contentEditable = "false"
|