prosemirror-view 1.41.9 → 1.42.0
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 +71 -53
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +38 -14
- package/package.json +1 -1
- package/src/clipboard.ts +14 -3
- package/src/viewdesc.ts +31 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 1.42.0 (2026-07-01)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
The clipboard content parser now inlines simple styles defined in the pasted HTML before parsing it, since some applications output their styling that way.
|
|
6
|
+
|
|
7
|
+
### New features
|
|
8
|
+
|
|
9
|
+
Mark views now also support an `update` method.
|
|
10
|
+
|
|
1
11
|
## 1.41.9 (2026-06-10)
|
|
2
12
|
|
|
3
13
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -1272,7 +1272,7 @@ var MarkViewDesc = function (_ViewDesc3) {
|
|
|
1272
1272
|
var NodeViewDesc = function (_ViewDesc4) {
|
|
1273
1273
|
_inherits(NodeViewDesc, _ViewDesc4);
|
|
1274
1274
|
var _super4 = _createSuper(NodeViewDesc);
|
|
1275
|
-
function NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM
|
|
1275
|
+
function NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM) {
|
|
1276
1276
|
var _this4;
|
|
1277
1277
|
_classCallCheck(this, NodeViewDesc);
|
|
1278
1278
|
_this4 = _super4.call(this, parent, [], dom, contentDOM);
|
|
@@ -1474,23 +1474,23 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1474
1474
|
}
|
|
1475
1475
|
var nodeDOM = dom;
|
|
1476
1476
|
dom = applyOuterDeco(dom, outerDeco, node);
|
|
1477
|
-
if (spec) return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec
|
|
1477
|
+
if (spec) return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec);else if (node.isText) return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM);else return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM);
|
|
1478
1478
|
}
|
|
1479
1479
|
}]);
|
|
1480
1480
|
return NodeViewDesc;
|
|
1481
1481
|
}(ViewDesc);
|
|
1482
1482
|
function docViewDesc(doc, outerDeco, innerDeco, dom, view) {
|
|
1483
1483
|
applyOuterDeco(dom, outerDeco, doc);
|
|
1484
|
-
var docView = new NodeViewDesc(undefined, doc, outerDeco, innerDeco, dom, dom, dom
|
|
1484
|
+
var docView = new NodeViewDesc(undefined, doc, outerDeco, innerDeco, dom, dom, dom);
|
|
1485
1485
|
if (docView.contentDOM) docView.updateChildren(view, 0);
|
|
1486
1486
|
return docView;
|
|
1487
1487
|
}
|
|
1488
1488
|
var TextViewDesc = function (_NodeViewDesc) {
|
|
1489
1489
|
_inherits(TextViewDesc, _NodeViewDesc);
|
|
1490
1490
|
var _super5 = _createSuper(TextViewDesc);
|
|
1491
|
-
function TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM
|
|
1491
|
+
function TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM) {
|
|
1492
1492
|
_classCallCheck(this, TextViewDesc);
|
|
1493
|
-
return _super5.call(this, parent, node, outerDeco, innerDeco, dom, null, nodeDOM
|
|
1493
|
+
return _super5.call(this, parent, node, outerDeco, innerDeco, dom, null, nodeDOM);
|
|
1494
1494
|
}
|
|
1495
1495
|
_createClass(TextViewDesc, [{
|
|
1496
1496
|
key: "parseRule",
|
|
@@ -1542,10 +1542,10 @@ var TextViewDesc = function (_NodeViewDesc) {
|
|
|
1542
1542
|
}
|
|
1543
1543
|
}, {
|
|
1544
1544
|
key: "slice",
|
|
1545
|
-
value: function slice(from, to,
|
|
1545
|
+
value: function slice(from, to, _view) {
|
|
1546
1546
|
var node = this.node.cut(from, to),
|
|
1547
1547
|
dom = document.createTextNode(node.text);
|
|
1548
|
-
return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom
|
|
1548
|
+
return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom);
|
|
1549
1549
|
}
|
|
1550
1550
|
}, {
|
|
1551
1551
|
key: "markDirty",
|
|
@@ -1601,10 +1601,10 @@ var TrailingHackViewDesc = function (_ViewDesc5) {
|
|
|
1601
1601
|
var CustomNodeViewDesc = function (_NodeViewDesc2) {
|
|
1602
1602
|
_inherits(CustomNodeViewDesc, _NodeViewDesc2);
|
|
1603
1603
|
var _super7 = _createSuper(CustomNodeViewDesc);
|
|
1604
|
-
function CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec
|
|
1604
|
+
function CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec) {
|
|
1605
1605
|
var _this7;
|
|
1606
1606
|
_classCallCheck(this, CustomNodeViewDesc);
|
|
1607
|
-
_this7 = _super7.call(this, parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM
|
|
1607
|
+
_this7 = _super7.call(this, parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM);
|
|
1608
1608
|
_this7.spec = spec;
|
|
1609
1609
|
return _this7;
|
|
1610
1610
|
}
|
|
@@ -1810,6 +1810,14 @@ var ViewTreeUpdater = function () {
|
|
|
1810
1810
|
break;
|
|
1811
1811
|
}
|
|
1812
1812
|
}
|
|
1813
|
+
if (found < 0 && this.index < this.top.children.length) {
|
|
1814
|
+
var cur = this.top.children[this.index];
|
|
1815
|
+
if (cur instanceof MarkViewDesc && cur.dirty != NODE_DIRTY && cur.mark.type == marks[depth].type && cur.spec.update && !this.isLocked(cur.dom) && cur.spec.update(marks[depth])) {
|
|
1816
|
+
cur.mark = marks[depth];
|
|
1817
|
+
found = this.index;
|
|
1818
|
+
this.changed = true;
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1813
1821
|
if (found > -1) {
|
|
1814
1822
|
if (found > this.index) {
|
|
1815
1823
|
this.changed = true;
|
|
@@ -2831,9 +2839,8 @@ var wrapMap = {
|
|
|
2831
2839
|
td: ["table", "tbody", "tr"],
|
|
2832
2840
|
th: ["table", "tbody", "tr"]
|
|
2833
2841
|
};
|
|
2834
|
-
var _detachedDoc = null;
|
|
2835
2842
|
function detachedDoc() {
|
|
2836
|
-
return
|
|
2843
|
+
return document.implementation.createHTMLDocument("title");
|
|
2837
2844
|
}
|
|
2838
2845
|
var _policy = null;
|
|
2839
2846
|
function maybeWrapTrusted(html) {
|
|
@@ -2849,7 +2856,8 @@ function maybeWrapTrusted(html) {
|
|
|
2849
2856
|
function readHTML(html) {
|
|
2850
2857
|
var metas = /^(\s*<meta [^>]*>)*/.exec(html);
|
|
2851
2858
|
if (metas) html = html.slice(metas[0].length);
|
|
2852
|
-
var
|
|
2859
|
+
var doc = detachedDoc(),
|
|
2860
|
+
elt = doc.body;
|
|
2853
2861
|
var firstTag = /<([a-z][^>\s]+)/i.exec(html),
|
|
2854
2862
|
wrap;
|
|
2855
2863
|
if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) html = wrap.map(function (n) {
|
|
@@ -2859,6 +2867,16 @@ function readHTML(html) {
|
|
|
2859
2867
|
}).reverse().join("");
|
|
2860
2868
|
elt.innerHTML = maybeWrapTrusted(html);
|
|
2861
2869
|
if (wrap) for (var i = 0; i < wrap.length; i++) elt = elt.querySelector(wrap[i]) || elt;
|
|
2870
|
+
for (var _i6 = 0; _i6 < doc.styleSheets.length; _i6++) {
|
|
2871
|
+
var style = doc.styleSheets[_i6];
|
|
2872
|
+
for (var j = 0; j < style.rules.length; j++) {
|
|
2873
|
+
var rule = style.rules[j];
|
|
2874
|
+
if (rule instanceof CSSStyleRule) {
|
|
2875
|
+
var matches = elt.querySelectorAll(rule.selectorText);
|
|
2876
|
+
for (var k = 0; k < matches.length; k++) matches[k].style.cssText += rule.style.cssText;
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
}
|
|
2862
2880
|
return elt;
|
|
2863
2881
|
}
|
|
2864
2882
|
function restoreReplacedSpaces(dom) {
|
|
@@ -3852,10 +3870,10 @@ var DecorationSet = function () {
|
|
|
3852
3870
|
var span = this.local[i];
|
|
3853
3871
|
if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) result.push(span.copy(span.from + offset, span.to + offset));
|
|
3854
3872
|
}
|
|
3855
|
-
for (var
|
|
3856
|
-
if (this.children[
|
|
3857
|
-
var childOff = this.children[
|
|
3858
|
-
this.children[
|
|
3873
|
+
for (var _i7 = 0; _i7 < this.children.length; _i7 += 3) {
|
|
3874
|
+
if (this.children[_i7] < end && this.children[_i7 + 1] > start) {
|
|
3875
|
+
var childOff = this.children[_i7] + 1;
|
|
3876
|
+
this.children[_i7 + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate);
|
|
3859
3877
|
}
|
|
3860
3878
|
}
|
|
3861
3879
|
}
|
|
@@ -3932,7 +3950,7 @@ var DecorationSet = function () {
|
|
|
3932
3950
|
i -= 3;
|
|
3933
3951
|
}
|
|
3934
3952
|
}
|
|
3935
|
-
if (local.length) for (var
|
|
3953
|
+
if (local.length) for (var _i8 = 0, _span; _i8 < decorations.length; _i8++) if (_span = decorations[_i8]) {
|
|
3936
3954
|
for (var _j2 = 0; _j2 < local.length; _j2++) if (local[_j2].eq(_span, offset)) {
|
|
3937
3955
|
if (local == this.local) local = this.local.slice();
|
|
3938
3956
|
local.splice(_j2--, 1);
|
|
@@ -3953,8 +3971,8 @@ var DecorationSet = function () {
|
|
|
3953
3971
|
}
|
|
3954
3972
|
var start = offset + 1,
|
|
3955
3973
|
end = start + node.content.size;
|
|
3956
|
-
for (var
|
|
3957
|
-
var dec = this.local[
|
|
3974
|
+
for (var _i9 = 0; _i9 < this.local.length; _i9++) {
|
|
3975
|
+
var dec = this.local[_i9];
|
|
3958
3976
|
if (dec.from < end && dec.to > start && dec.type instanceof InlineType) {
|
|
3959
3977
|
var from = Math.max(start, dec.from) - start,
|
|
3960
3978
|
to = Math.min(end, dec.to) - start;
|
|
@@ -3973,7 +3991,7 @@ var DecorationSet = function () {
|
|
|
3973
3991
|
if (this == other) return true;
|
|
3974
3992
|
if (!(other instanceof DecorationSet) || this.local.length != other.local.length || this.children.length != other.children.length) return false;
|
|
3975
3993
|
for (var i = 0; i < this.local.length; i++) if (!this.local[i].eq(other.local[i])) return false;
|
|
3976
|
-
for (var
|
|
3994
|
+
for (var _i10 = 0; _i10 < this.children.length; _i10 += 3) if (this.children[_i10] != other.children[_i10] || this.children[_i10 + 1] != other.children[_i10 + 1] || !this.children[_i10 + 2].eq(other.children[_i10 + 2])) return false;
|
|
3977
3995
|
return true;
|
|
3978
3996
|
}
|
|
3979
3997
|
}, {
|
|
@@ -4090,15 +4108,15 @@ function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, op
|
|
|
4090
4108
|
var moved = 0;
|
|
4091
4109
|
mapping.maps[i].forEach(function (oldStart, oldEnd, newStart, newEnd) {
|
|
4092
4110
|
var dSize = newEnd - newStart - (oldEnd - oldStart);
|
|
4093
|
-
for (var
|
|
4094
|
-
var end = children[
|
|
4111
|
+
for (var _i14 = 0; _i14 < children.length; _i14 += 3) {
|
|
4112
|
+
var end = children[_i14 + 1];
|
|
4095
4113
|
if (end < 0 || oldStart > end + _baseOffset - moved) continue;
|
|
4096
|
-
var start = children[
|
|
4114
|
+
var start = children[_i14] + _baseOffset - moved;
|
|
4097
4115
|
if (oldEnd >= start) {
|
|
4098
|
-
children[
|
|
4116
|
+
children[_i14 + 1] = oldStart <= start ? -2 : -1;
|
|
4099
4117
|
} else if (oldStart >= _baseOffset && dSize) {
|
|
4100
|
-
children[
|
|
4101
|
-
children[
|
|
4118
|
+
children[_i14] += dSize;
|
|
4119
|
+
children[_i14 + 1] += dSize;
|
|
4102
4120
|
}
|
|
4103
4121
|
}
|
|
4104
4122
|
moved += dSize;
|
|
@@ -4110,32 +4128,32 @@ function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, op
|
|
|
4110
4128
|
_loop4(baseOffset);
|
|
4111
4129
|
}
|
|
4112
4130
|
var mustRebuild = false;
|
|
4113
|
-
for (var
|
|
4114
|
-
if (children[
|
|
4131
|
+
for (var _i11 = 0; _i11 < children.length; _i11 += 3) if (children[_i11 + 1] < 0) {
|
|
4132
|
+
if (children[_i11 + 1] == -2) {
|
|
4115
4133
|
mustRebuild = true;
|
|
4116
|
-
children[
|
|
4134
|
+
children[_i11 + 1] = -1;
|
|
4117
4135
|
continue;
|
|
4118
4136
|
}
|
|
4119
|
-
var from = mapping.map(oldChildren[
|
|
4137
|
+
var from = mapping.map(oldChildren[_i11] + oldOffset),
|
|
4120
4138
|
fromLocal = from - offset;
|
|
4121
4139
|
if (fromLocal < 0 || fromLocal >= node.content.size) {
|
|
4122
4140
|
mustRebuild = true;
|
|
4123
4141
|
continue;
|
|
4124
4142
|
}
|
|
4125
|
-
var to = mapping.map(oldChildren[
|
|
4143
|
+
var to = mapping.map(oldChildren[_i11 + 1] + oldOffset, -1),
|
|
4126
4144
|
toLocal = to - offset;
|
|
4127
4145
|
var _node$content$findInd2 = node.content.findIndex(fromLocal),
|
|
4128
4146
|
index = _node$content$findInd2.index,
|
|
4129
4147
|
childOffset = _node$content$findInd2.offset;
|
|
4130
4148
|
var childNode = node.maybeChild(index);
|
|
4131
4149
|
if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) {
|
|
4132
|
-
var mapped = children[
|
|
4150
|
+
var mapped = children[_i11 + 2].mapInner(mapping, childNode, from + 1, oldChildren[_i11] + oldOffset + 1, options);
|
|
4133
4151
|
if (mapped != empty) {
|
|
4134
|
-
children[
|
|
4135
|
-
children[
|
|
4136
|
-
children[
|
|
4152
|
+
children[_i11] = fromLocal;
|
|
4153
|
+
children[_i11 + 1] = toLocal;
|
|
4154
|
+
children[_i11 + 2] = mapped;
|
|
4137
4155
|
} else {
|
|
4138
|
-
children[
|
|
4156
|
+
children[_i11 + 1] = -2;
|
|
4139
4157
|
mustRebuild = true;
|
|
4140
4158
|
}
|
|
4141
4159
|
} else {
|
|
@@ -4146,14 +4164,14 @@ function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, op
|
|
|
4146
4164
|
var decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal, mapping, offset, oldOffset, options);
|
|
4147
4165
|
var built = buildTree(decorations, node, 0, options);
|
|
4148
4166
|
newLocal = built.local;
|
|
4149
|
-
for (var
|
|
4150
|
-
children.splice(
|
|
4151
|
-
|
|
4167
|
+
for (var _i12 = 0; _i12 < children.length; _i12 += 3) if (children[_i12 + 1] < 0) {
|
|
4168
|
+
children.splice(_i12, 3);
|
|
4169
|
+
_i12 -= 3;
|
|
4152
4170
|
}
|
|
4153
|
-
for (var
|
|
4154
|
-
var _from2 = built.children[
|
|
4171
|
+
for (var _i13 = 0, j = 0; _i13 < built.children.length; _i13 += 3) {
|
|
4172
|
+
var _from2 = built.children[_i13];
|
|
4155
4173
|
while (j < children.length && children[j] < _from2) j += 3;
|
|
4156
|
-
children.splice(j, 0, built.children[
|
|
4174
|
+
children.splice(j, 0, built.children[_i13], built.children[_i13 + 1], built.children[_i13 + 2]);
|
|
4157
4175
|
}
|
|
4158
4176
|
}
|
|
4159
4177
|
return new DecorationSet(newLocal.sort(byPos), children);
|
|
@@ -4173,7 +4191,7 @@ function mapAndGatherRemainingDecorations(children, oldChildren, decorations, ma
|
|
|
4173
4191
|
var mapped = set.local[i].map(mapping, offset, oldOffset);
|
|
4174
4192
|
if (mapped) decorations.push(mapped);else if (options.onRemove) options.onRemove(set.local[i].spec);
|
|
4175
4193
|
}
|
|
4176
|
-
for (var
|
|
4194
|
+
for (var _i15 = 0; _i15 < set.children.length; _i15 += 3) gather(set.children[_i15 + 2], set.children[_i15] + oldOffset + 1);
|
|
4177
4195
|
}
|
|
4178
4196
|
for (var i = 0; i < children.length; i += 3) if (children[i + 1] == -1) gather(children[i + 2], oldChildren[i] + oldOffset + 1);
|
|
4179
4197
|
return decorations;
|
|
@@ -4566,8 +4584,8 @@ var DOMObserver = function () {
|
|
|
4566
4584
|
var prev = mut.previousSibling,
|
|
4567
4585
|
next = mut.nextSibling;
|
|
4568
4586
|
if (ie && ie_version <= 11 && mut.addedNodes.length) {
|
|
4569
|
-
for (var
|
|
4570
|
-
var _mut$addedNodes$_i = mut.addedNodes[
|
|
4587
|
+
for (var _i16 = 0; _i16 < mut.addedNodes.length; _i16++) {
|
|
4588
|
+
var _mut$addedNodes$_i = mut.addedNodes[_i16],
|
|
4571
4589
|
previousSibling = _mut$addedNodes$_i.previousSibling,
|
|
4572
4590
|
nextSibling = _mut$addedNodes$_i.nextSibling;
|
|
4573
4591
|
if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling;
|
|
@@ -4933,7 +4951,7 @@ function isMarkChange(cur, prev) {
|
|
|
4933
4951
|
mark,
|
|
4934
4952
|
update;
|
|
4935
4953
|
for (var i = 0; i < prevMarks.length; i++) added = prevMarks[i].removeFromSet(added);
|
|
4936
|
-
for (var
|
|
4954
|
+
for (var _i17 = 0; _i17 < curMarks.length; _i17++) removed = curMarks[_i17].removeFromSet(removed);
|
|
4937
4955
|
if (added.length == 1 && removed.length == 0) {
|
|
4938
4956
|
mark = added[0];
|
|
4939
4957
|
type = "add";
|
|
@@ -4950,7 +4968,7 @@ function isMarkChange(cur, prev) {
|
|
|
4950
4968
|
return null;
|
|
4951
4969
|
}
|
|
4952
4970
|
var updated = [];
|
|
4953
|
-
for (var
|
|
4971
|
+
for (var _i18 = 0; _i18 < prev.childCount; _i18++) updated.push(update(prev.child(_i18)));
|
|
4954
4972
|
if (prosemirrorModel.Fragment.from(updated).eq(cur)) return {
|
|
4955
4973
|
mark: mark,
|
|
4956
4974
|
type: type
|
|
@@ -5187,13 +5205,13 @@ var EditorView = function () {
|
|
|
5187
5205
|
var plugin = this.directPlugins[i];
|
|
5188
5206
|
if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this));
|
|
5189
5207
|
}
|
|
5190
|
-
for (var
|
|
5191
|
-
var _plugin = this.state.plugins[
|
|
5208
|
+
for (var _i19 = 0; _i19 < this.state.plugins.length; _i19++) {
|
|
5209
|
+
var _plugin = this.state.plugins[_i19];
|
|
5192
5210
|
if (_plugin.spec.view) this.pluginViews.push(_plugin.spec.view(this));
|
|
5193
5211
|
}
|
|
5194
5212
|
} else {
|
|
5195
|
-
for (var
|
|
5196
|
-
var pluginView = this.pluginViews[
|
|
5213
|
+
for (var _i20 = 0; _i20 < this.pluginViews.length; _i20++) {
|
|
5214
|
+
var pluginView = this.pluginViews[_i20];
|
|
5197
5215
|
if (pluginView.update) pluginView.update(this, prevState);
|
|
5198
5216
|
}
|
|
5199
5217
|
}
|
|
@@ -5223,8 +5241,8 @@ var EditorView = function () {
|
|
|
5223
5241
|
if (_prop != null && (value = f ? f(_prop) : _prop)) return value;
|
|
5224
5242
|
}
|
|
5225
5243
|
var plugins = this.state.plugins;
|
|
5226
|
-
if (plugins) for (var
|
|
5227
|
-
var _prop2 = plugins[
|
|
5244
|
+
if (plugins) for (var _i21 = 0; _i21 < plugins.length; _i21++) {
|
|
5245
|
+
var _prop2 = plugins[_i21].props[propName];
|
|
5228
5246
|
if (_prop2 != null && (value = f ? f(_prop2) : _prop2)) return value;
|
|
5229
5247
|
}
|
|
5230
5248
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -363,6 +363,14 @@ interface MarkView {
|
|
|
363
363
|
*/
|
|
364
364
|
contentDOM?: HTMLElement | null;
|
|
365
365
|
/**
|
|
366
|
+
When given, this is called when the view is updating itself. It
|
|
367
|
+
will be given a mark (of the same type as the current one). When it
|
|
368
|
+
returns true, the existing DOM is kept and reused (its content is
|
|
369
|
+
still managed by ProseMirror); when it returns false, the mark view
|
|
370
|
+
is rebuilt.
|
|
371
|
+
*/
|
|
372
|
+
update?: (mark: Mark) => boolean;
|
|
373
|
+
/**
|
|
366
374
|
Called when a [mutation](https://prosemirror.net/docs/ref/#view.ViewMutationRecord) happens within the
|
|
367
375
|
view. Return false if the editor should re-read the selection or re-parse
|
|
368
376
|
the range around the mutation, true if it can safely be ignored.
|
package/dist/index.d.ts
CHANGED
|
@@ -363,6 +363,14 @@ interface MarkView {
|
|
|
363
363
|
*/
|
|
364
364
|
contentDOM?: HTMLElement | null;
|
|
365
365
|
/**
|
|
366
|
+
When given, this is called when the view is updating itself. It
|
|
367
|
+
will be given a mark (of the same type as the current one). When it
|
|
368
|
+
returns true, the existing DOM is kept and reused (its content is
|
|
369
|
+
still managed by ProseMirror); when it returns false, the mark view
|
|
370
|
+
is rebuilt.
|
|
371
|
+
*/
|
|
372
|
+
update?: (mark: Mark) => boolean;
|
|
373
|
+
/**
|
|
366
374
|
Called when a [mutation](https://prosemirror.net/docs/ref/#view.ViewMutationRecord) happens within the
|
|
367
375
|
view. Return false if the editor should re-read the selection or re-parse
|
|
368
376
|
the range around the mutation, true if it can safely be ignored.
|
package/dist/index.js
CHANGED
|
@@ -1273,7 +1273,7 @@ class MarkViewDesc extends ViewDesc {
|
|
|
1273
1273
|
// correspond to an actual node in the document. Unlike mark descs,
|
|
1274
1274
|
// they populate their child array themselves.
|
|
1275
1275
|
class NodeViewDesc extends ViewDesc {
|
|
1276
|
-
constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM
|
|
1276
|
+
constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM) {
|
|
1277
1277
|
super(parent, [], dom, contentDOM);
|
|
1278
1278
|
this.node = node;
|
|
1279
1279
|
this.outerDeco = outerDeco;
|
|
@@ -1319,11 +1319,11 @@ class NodeViewDesc extends ViewDesc {
|
|
|
1319
1319
|
let nodeDOM = dom;
|
|
1320
1320
|
dom = applyOuterDeco(dom, outerDeco, node);
|
|
1321
1321
|
if (spec)
|
|
1322
|
-
return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec
|
|
1322
|
+
return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec);
|
|
1323
1323
|
else if (node.isText)
|
|
1324
|
-
return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM
|
|
1324
|
+
return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM);
|
|
1325
1325
|
else
|
|
1326
|
-
return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM
|
|
1326
|
+
return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM);
|
|
1327
1327
|
}
|
|
1328
1328
|
parseRule() {
|
|
1329
1329
|
// Experimental kludge to allow opt-in re-parsing of nodes
|
|
@@ -1507,14 +1507,14 @@ class NodeViewDesc extends ViewDesc {
|
|
|
1507
1507
|
// and used by the view class.
|
|
1508
1508
|
function docViewDesc(doc, outerDeco, innerDeco, dom, view) {
|
|
1509
1509
|
applyOuterDeco(dom, outerDeco, doc);
|
|
1510
|
-
let docView = new NodeViewDesc(undefined, doc, outerDeco, innerDeco, dom, dom, dom
|
|
1510
|
+
let docView = new NodeViewDesc(undefined, doc, outerDeco, innerDeco, dom, dom, dom);
|
|
1511
1511
|
if (docView.contentDOM)
|
|
1512
1512
|
docView.updateChildren(view, 0);
|
|
1513
1513
|
return docView;
|
|
1514
1514
|
}
|
|
1515
1515
|
class TextViewDesc extends NodeViewDesc {
|
|
1516
|
-
constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM
|
|
1517
|
-
super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM
|
|
1516
|
+
constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM) {
|
|
1517
|
+
super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM);
|
|
1518
1518
|
}
|
|
1519
1519
|
parseRule() {
|
|
1520
1520
|
let skip = this.nodeDOM.parentNode;
|
|
@@ -1554,9 +1554,9 @@ class TextViewDesc extends NodeViewDesc {
|
|
|
1554
1554
|
ignoreMutation(mutation) {
|
|
1555
1555
|
return mutation.type != "characterData" && mutation.type != "selection";
|
|
1556
1556
|
}
|
|
1557
|
-
slice(from, to,
|
|
1557
|
+
slice(from, to, _view) {
|
|
1558
1558
|
let node = this.node.cut(from, to), dom = document.createTextNode(node.text);
|
|
1559
|
-
return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom
|
|
1559
|
+
return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom);
|
|
1560
1560
|
}
|
|
1561
1561
|
markDirty(from, to) {
|
|
1562
1562
|
super.markDirty(from, to);
|
|
@@ -1578,8 +1578,8 @@ class TrailingHackViewDesc extends ViewDesc {
|
|
|
1578
1578
|
// extra checks only have to be made for nodes that are actually
|
|
1579
1579
|
// customized.
|
|
1580
1580
|
class CustomNodeViewDesc extends NodeViewDesc {
|
|
1581
|
-
constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec
|
|
1582
|
-
super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM
|
|
1581
|
+
constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec) {
|
|
1582
|
+
super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM);
|
|
1583
1583
|
this.spec = spec;
|
|
1584
1584
|
}
|
|
1585
1585
|
// A custom `update` method gets to decide whether the update goes
|
|
@@ -1816,6 +1816,19 @@ class ViewTreeUpdater {
|
|
|
1816
1816
|
break;
|
|
1817
1817
|
}
|
|
1818
1818
|
}
|
|
1819
|
+
// When nothing matches, try to update the mark view at this position
|
|
1820
|
+
// in place, so a custom mark view can adapt to a changed mark without
|
|
1821
|
+
// re-creating its DOM.
|
|
1822
|
+
if (found < 0 && this.index < this.top.children.length) {
|
|
1823
|
+
let cur = this.top.children[this.index];
|
|
1824
|
+
if (cur instanceof MarkViewDesc && cur.dirty != NODE_DIRTY &&
|
|
1825
|
+
cur.mark.type == marks[depth].type && cur.spec.update &&
|
|
1826
|
+
!this.isLocked(cur.dom) && cur.spec.update(marks[depth])) {
|
|
1827
|
+
cur.mark = marks[depth];
|
|
1828
|
+
found = this.index;
|
|
1829
|
+
this.changed = true;
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1819
1832
|
if (found > -1) {
|
|
1820
1833
|
if (found > this.index) {
|
|
1821
1834
|
this.changed = true;
|
|
@@ -2984,9 +2997,8 @@ const wrapMap = {
|
|
|
2984
2997
|
td: ["table", "tbody", "tr"],
|
|
2985
2998
|
th: ["table", "tbody", "tr"]
|
|
2986
2999
|
};
|
|
2987
|
-
let _detachedDoc = null;
|
|
2988
3000
|
function detachedDoc() {
|
|
2989
|
-
return
|
|
3001
|
+
return document.implementation.createHTMLDocument("title");
|
|
2990
3002
|
}
|
|
2991
3003
|
let _policy = null;
|
|
2992
3004
|
function maybeWrapTrusted(html) {
|
|
@@ -3004,7 +3016,7 @@ function readHTML(html) {
|
|
|
3004
3016
|
let metas = /^(\s*<meta [^>]*>)*/.exec(html);
|
|
3005
3017
|
if (metas)
|
|
3006
3018
|
html = html.slice(metas[0].length);
|
|
3007
|
-
let
|
|
3019
|
+
let doc = detachedDoc(), elt = doc.body;
|
|
3008
3020
|
let firstTag = /<([a-z][^>\s]+)/i.exec(html), wrap;
|
|
3009
3021
|
if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()])
|
|
3010
3022
|
html = wrap.map(n => "<" + n + ">").join("") + html + wrap.map(n => "</" + n + ">").reverse().join("");
|
|
@@ -3012,6 +3024,18 @@ function readHTML(html) {
|
|
|
3012
3024
|
if (wrap)
|
|
3013
3025
|
for (let i = 0; i < wrap.length; i++)
|
|
3014
3026
|
elt = elt.querySelector(wrap[i]) || elt;
|
|
3027
|
+
// Inline styles defined in the pasted content, so that parse rules pick them up
|
|
3028
|
+
for (let i = 0; i < doc.styleSheets.length; i++) {
|
|
3029
|
+
let style = doc.styleSheets[i];
|
|
3030
|
+
for (let j = 0; j < style.rules.length; j++) {
|
|
3031
|
+
let rule = style.rules[j];
|
|
3032
|
+
if (rule instanceof CSSStyleRule) {
|
|
3033
|
+
let matches = elt.querySelectorAll(rule.selectorText);
|
|
3034
|
+
for (let k = 0; k < matches.length; k++)
|
|
3035
|
+
matches[k].style.cssText += rule.style.cssText;
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3015
3039
|
return elt;
|
|
3016
3040
|
}
|
|
3017
3041
|
// Webkit browsers do some hard-to-predict replacement of regular
|
package/package.json
CHANGED
package/src/clipboard.ts
CHANGED
|
@@ -203,9 +203,8 @@ const wrapMap: {[node: string]: string[]} = {
|
|
|
203
203
|
th: ["table", "tbody", "tr"]
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
let _detachedDoc: Document | null = null
|
|
207
206
|
function detachedDoc() {
|
|
208
|
-
return
|
|
207
|
+
return document.implementation.createHTMLDocument("title")
|
|
209
208
|
}
|
|
210
209
|
|
|
211
210
|
let _policy: any = null
|
|
@@ -224,12 +223,24 @@ function maybeWrapTrusted(html: string): string {
|
|
|
224
223
|
function readHTML(html: string) {
|
|
225
224
|
let metas = /^(\s*<meta [^>]*>)*/.exec(html)
|
|
226
225
|
if (metas) html = html.slice(metas[0].length)
|
|
227
|
-
let
|
|
226
|
+
let doc = detachedDoc(), elt = doc.body
|
|
228
227
|
let firstTag = /<([a-z][^>\s]+)/i.exec(html), wrap
|
|
229
228
|
if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()])
|
|
230
229
|
html = wrap.map(n => "<" + n + ">").join("") + html + wrap.map(n => "</" + n + ">").reverse().join("")
|
|
231
230
|
elt.innerHTML = maybeWrapTrusted(html)
|
|
232
231
|
if (wrap) for (let i = 0; i < wrap.length; i++) elt = elt.querySelector(wrap[i]) || elt
|
|
232
|
+
// Inline styles defined in the pasted content, so that parse rules pick them up
|
|
233
|
+
for (let i = 0; i < doc.styleSheets.length; i++) {
|
|
234
|
+
let style = doc.styleSheets[i]
|
|
235
|
+
for (let j = 0; j < style.rules.length; j++) {
|
|
236
|
+
let rule = style.rules[j]
|
|
237
|
+
if (rule instanceof CSSStyleRule) {
|
|
238
|
+
let matches = elt.querySelectorAll(rule.selectorText)
|
|
239
|
+
for (let k = 0; k < matches.length; k++)
|
|
240
|
+
(matches[k] as HTMLElement).style.cssText += rule.style.cssText
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
233
244
|
return elt
|
|
234
245
|
}
|
|
235
246
|
|
package/src/viewdesc.ts
CHANGED
|
@@ -105,6 +105,13 @@ export interface MarkView {
|
|
|
105
105
|
/// present, the `dom` property is used as the content DOM.
|
|
106
106
|
contentDOM?: HTMLElement | null
|
|
107
107
|
|
|
108
|
+
/// When given, this is called when the view is updating itself. It
|
|
109
|
+
/// will be given a mark (of the same type as the current one). When it
|
|
110
|
+
/// returns true, the existing DOM is kept and reused (its content is
|
|
111
|
+
/// still managed by ProseMirror); when it returns false, the mark view
|
|
112
|
+
/// is rebuilt.
|
|
113
|
+
update?: (mark: Mark) => boolean
|
|
114
|
+
|
|
108
115
|
/// Called when a [mutation](#view.ViewMutationRecord) happens within the
|
|
109
116
|
/// view. Return false if the editor should re-read the selection or re-parse
|
|
110
117
|
/// the range around the mutation, true if it can safely be ignored.
|
|
@@ -610,7 +617,7 @@ class CompositionViewDesc extends ViewDesc {
|
|
|
610
617
|
// some cases they will be split more often than would appear
|
|
611
618
|
// necessary.
|
|
612
619
|
class MarkViewDesc extends ViewDesc {
|
|
613
|
-
constructor(parent: ViewDesc,
|
|
620
|
+
constructor(parent: ViewDesc, public mark: Mark, dom: HTMLElement, contentDOM: HTMLElement, readonly spec: MarkView) {
|
|
614
621
|
super(parent, [], dom, contentDOM)
|
|
615
622
|
}
|
|
616
623
|
|
|
@@ -672,8 +679,6 @@ export class NodeViewDesc extends ViewDesc {
|
|
|
672
679
|
dom: DOMNode,
|
|
673
680
|
contentDOM: HTMLElement | null,
|
|
674
681
|
readonly nodeDOM: DOMNode,
|
|
675
|
-
view: EditorView,
|
|
676
|
-
pos: number
|
|
677
682
|
) {
|
|
678
683
|
super(parent, [], dom, contentDOM)
|
|
679
684
|
}
|
|
@@ -715,11 +720,11 @@ export class NodeViewDesc extends ViewDesc {
|
|
|
715
720
|
|
|
716
721
|
if (spec)
|
|
717
722
|
return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom as HTMLElement, contentDOM || null,
|
|
718
|
-
nodeDOM as HTMLElement, spec
|
|
723
|
+
nodeDOM as HTMLElement, spec)
|
|
719
724
|
else if (node.isText)
|
|
720
|
-
return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM
|
|
725
|
+
return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM)
|
|
721
726
|
else
|
|
722
|
-
return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM
|
|
727
|
+
return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM)
|
|
723
728
|
}
|
|
724
729
|
|
|
725
730
|
parseRule() {
|
|
@@ -906,15 +911,15 @@ export class NodeViewDesc extends ViewDesc {
|
|
|
906
911
|
export function docViewDesc(doc: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource,
|
|
907
912
|
dom: HTMLElement, view: EditorView): NodeViewDesc {
|
|
908
913
|
applyOuterDeco(dom, outerDeco, doc)
|
|
909
|
-
let docView = new NodeViewDesc(undefined, doc, outerDeco, innerDeco, dom, dom, dom
|
|
914
|
+
let docView = new NodeViewDesc(undefined, doc, outerDeco, innerDeco, dom, dom, dom)
|
|
910
915
|
if (docView.contentDOM) docView.updateChildren(view, 0)
|
|
911
916
|
return docView
|
|
912
917
|
}
|
|
913
918
|
|
|
914
919
|
class TextViewDesc extends NodeViewDesc {
|
|
915
920
|
constructor(parent: ViewDesc | undefined, node: Node, outerDeco: readonly Decoration[],
|
|
916
|
-
innerDeco: DecorationSource, dom: DOMNode, nodeDOM: DOMNode
|
|
917
|
-
super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM
|
|
921
|
+
innerDeco: DecorationSource, dom: DOMNode, nodeDOM: DOMNode) {
|
|
922
|
+
super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM)
|
|
918
923
|
}
|
|
919
924
|
|
|
920
925
|
parseRule() {
|
|
@@ -955,9 +960,9 @@ class TextViewDesc extends NodeViewDesc {
|
|
|
955
960
|
return mutation.type != "characterData" && mutation.type != "selection"
|
|
956
961
|
}
|
|
957
962
|
|
|
958
|
-
slice(from: number, to: number,
|
|
963
|
+
slice(from: number, to: number, _view?: EditorView) {
|
|
959
964
|
let node = this.node.cut(from, to), dom = document.createTextNode(node.text!)
|
|
960
|
-
return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom
|
|
965
|
+
return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom)
|
|
961
966
|
}
|
|
962
967
|
|
|
963
968
|
markDirty(from: number, to: number) {
|
|
@@ -985,9 +990,8 @@ class TrailingHackViewDesc extends ViewDesc {
|
|
|
985
990
|
// customized.
|
|
986
991
|
class CustomNodeViewDesc extends NodeViewDesc {
|
|
987
992
|
constructor(parent: ViewDesc | undefined, node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource,
|
|
988
|
-
dom: HTMLElement, contentDOM: HTMLElement | null, nodeDOM: HTMLElement, readonly spec: NodeView
|
|
989
|
-
|
|
990
|
-
super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos)
|
|
993
|
+
dom: HTMLElement, contentDOM: HTMLElement | null, nodeDOM: HTMLElement, readonly spec: NodeView) {
|
|
994
|
+
super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM)
|
|
991
995
|
}
|
|
992
996
|
|
|
993
997
|
// A custom `update` method gets to decide whether the update goes
|
|
@@ -1220,6 +1224,19 @@ class ViewTreeUpdater {
|
|
|
1220
1224
|
let next = this.top.children[i]
|
|
1221
1225
|
if (next.matchesMark(marks[depth]) && !this.isLocked(next.dom)) { found = i; break }
|
|
1222
1226
|
}
|
|
1227
|
+
// When nothing matches, try to update the mark view at this position
|
|
1228
|
+
// in place, so a custom mark view can adapt to a changed mark without
|
|
1229
|
+
// re-creating its DOM.
|
|
1230
|
+
if (found < 0 && this.index < this.top.children.length) {
|
|
1231
|
+
let cur = this.top.children[this.index]
|
|
1232
|
+
if (cur instanceof MarkViewDesc && cur.dirty != NODE_DIRTY &&
|
|
1233
|
+
cur.mark.type == marks[depth].type && cur.spec.update &&
|
|
1234
|
+
!this.isLocked(cur.dom) && cur.spec.update(marks[depth])) {
|
|
1235
|
+
cur.mark = marks[depth]
|
|
1236
|
+
found = this.index
|
|
1237
|
+
this.changed = true
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1223
1240
|
if (found > -1) {
|
|
1224
1241
|
if (found > this.index) {
|
|
1225
1242
|
this.changed = true
|