@ni/spright-components 6.23.0 → 6.23.1
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/dist/all-components-bundle.js +1799 -1583
- package/dist/all-components-bundle.js.map +1 -1
- package/dist/all-components-bundle.min.js +3786 -3754
- package/dist/all-components-bundle.min.js.map +1 -1
- package/package.json +4 -4
|
@@ -29797,7 +29797,6 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
29797
29797
|
if (!type)
|
|
29798
29798
|
throw new RangeError(`There is no mark type ${json.type} in this schema`);
|
|
29799
29799
|
let mark = type.create(json.attrs);
|
|
29800
|
-
type.checkAttrs(mark.attrs);
|
|
29801
29800
|
return mark;
|
|
29802
29801
|
}
|
|
29803
29802
|
/**
|
|
@@ -30777,11 +30776,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
30777
30776
|
*/
|
|
30778
30777
|
check() {
|
|
30779
30778
|
this.type.checkContent(this.content);
|
|
30780
|
-
this.type.
|
|
30779
|
+
checkAttrs(this.type.attrs, this.attrs, "node", this.type.name);
|
|
30781
30780
|
let copy = Mark$1.none;
|
|
30782
30781
|
for (let i = 0; i < this.marks.length; i++) {
|
|
30783
30782
|
let mark = this.marks[i];
|
|
30784
|
-
mark.type.
|
|
30783
|
+
checkAttrs(mark.type.attrs, mark.attrs, "mark", mark.type.name);
|
|
30785
30784
|
copy = mark.addToSet(copy);
|
|
30786
30785
|
}
|
|
30787
30786
|
if (!Mark$1.sameSet(copy, this.marks))
|
|
@@ -30822,7 +30821,6 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
30822
30821
|
}
|
|
30823
30822
|
let content = Fragment.fromJSON(schema, json.content);
|
|
30824
30823
|
let node = schema.nodeType(json.type).create(json.attrs, content, marks);
|
|
30825
|
-
node.type.checkAttrs(node.attrs);
|
|
30826
30824
|
return node;
|
|
30827
30825
|
}
|
|
30828
30826
|
};
|
|
@@ -30872,6 +30870,15 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
30872
30870
|
str = marks[i].type.name + "(" + str + ")";
|
|
30873
30871
|
return str;
|
|
30874
30872
|
}
|
|
30873
|
+
function checkAttrs(attrs, values, type, name) {
|
|
30874
|
+
for (let attr in values)
|
|
30875
|
+
if (!(attr in attrs))
|
|
30876
|
+
throw new RangeError(`Unsupported attribute ${attr} for ${type} of type ${name}`);
|
|
30877
|
+
for (let attr in attrs) {
|
|
30878
|
+
if (attrs[attr].validate)
|
|
30879
|
+
attrs[attr].validate(values[attr]);
|
|
30880
|
+
}
|
|
30881
|
+
}
|
|
30875
30882
|
|
|
30876
30883
|
/**
|
|
30877
30884
|
Instances of this class represent a match state of a node type's
|
|
@@ -31326,27 +31333,21 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
31326
31333
|
function computeAttrs(attrs, value) {
|
|
31327
31334
|
let built = Object.create(null);
|
|
31328
31335
|
for (let name in attrs) {
|
|
31336
|
+
let attr = attrs[name];
|
|
31329
31337
|
let given = value && value[name];
|
|
31330
31338
|
if (given === undefined) {
|
|
31331
|
-
let attr = attrs[name];
|
|
31332
31339
|
if (attr.hasDefault)
|
|
31333
31340
|
given = attr.default;
|
|
31334
31341
|
else
|
|
31335
31342
|
throw new RangeError("No value supplied for attribute " + name);
|
|
31336
31343
|
}
|
|
31344
|
+
else if (attr.validate) {
|
|
31345
|
+
attr.validate(given);
|
|
31346
|
+
}
|
|
31337
31347
|
built[name] = given;
|
|
31338
31348
|
}
|
|
31339
31349
|
return built;
|
|
31340
31350
|
}
|
|
31341
|
-
function checkAttrs(attrs, values, type, name) {
|
|
31342
|
-
for (let attr in values)
|
|
31343
|
-
if (!(attr in attrs))
|
|
31344
|
-
throw new RangeError(`Unsupported attribute ${attr} for ${type} of type ${name}`);
|
|
31345
|
-
for (let attr in attrs) {
|
|
31346
|
-
if (attrs[attr].validate)
|
|
31347
|
-
attrs[attr].validate(values[attr]);
|
|
31348
|
-
}
|
|
31349
|
-
}
|
|
31350
31351
|
function initAttrs(typeName, attrs) {
|
|
31351
31352
|
let result = Object.create(null);
|
|
31352
31353
|
if (attrs)
|
|
@@ -31518,11 +31519,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
31518
31519
|
throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`);
|
|
31519
31520
|
}
|
|
31520
31521
|
/**
|
|
31521
|
-
@internal
|
|
31522
|
+
@internal no longer useful, but called by old prosemirror-view versions
|
|
31522
31523
|
*/
|
|
31523
|
-
checkAttrs(attrs) {
|
|
31524
|
-
checkAttrs(this.attrs, attrs, "node", this.name);
|
|
31525
|
-
}
|
|
31524
|
+
checkAttrs(attrs) { }
|
|
31526
31525
|
/**
|
|
31527
31526
|
Check whether the given mark type is allowed in this node.
|
|
31528
31527
|
*/
|
|
@@ -31669,12 +31668,6 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
31669
31668
|
return set[i];
|
|
31670
31669
|
}
|
|
31671
31670
|
/**
|
|
31672
|
-
@internal
|
|
31673
|
-
*/
|
|
31674
|
-
checkAttrs(attrs) {
|
|
31675
|
-
checkAttrs(this.attrs, attrs, "mark", this.name);
|
|
31676
|
-
}
|
|
31677
|
-
/**
|
|
31678
31671
|
Queries whether a given mark type is
|
|
31679
31672
|
[excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one.
|
|
31680
31673
|
*/
|
|
@@ -32865,9 +32858,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
32865
32858
|
if (simple)
|
|
32866
32859
|
return result;
|
|
32867
32860
|
let recover = pos == (assoc < 0 ? start : end) ? null : makeRecover(i / 3, pos - start);
|
|
32868
|
-
let del =
|
|
32869
|
-
if (
|
|
32870
|
-
del |=
|
|
32861
|
+
let del = 0;
|
|
32862
|
+
if (oldSize) {
|
|
32863
|
+
del |= pos == start ? DEL_AFTER : pos == end ? DEL_BEFORE : DEL_ACROSS;
|
|
32864
|
+
if (assoc < 0 ? pos != start : pos != end)
|
|
32865
|
+
del |= DEL_SIDE;
|
|
32866
|
+
}
|
|
32871
32867
|
return new MapResult(result, del, recover);
|
|
32872
32868
|
}
|
|
32873
32869
|
diff += newSize - oldSize;
|
|
@@ -36805,15 +36801,15 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36805
36801
|
return true;
|
|
36806
36802
|
if (off == (dir < 0 ? 0 : nodeSize(node))) {
|
|
36807
36803
|
let parent = node.parentNode;
|
|
36808
|
-
if (!parent || parent
|
|
36804
|
+
if (!parent || !isElt(parent) || hasBlockDesc(node) || atomElements.test(node.nodeName) ||
|
|
36809
36805
|
node.contentEditable == "false")
|
|
36810
36806
|
return false;
|
|
36811
36807
|
off = domIndex(node) + (dir < 0 ? 0 : 1);
|
|
36812
36808
|
node = parent;
|
|
36813
36809
|
}
|
|
36814
|
-
else if (node
|
|
36810
|
+
else if (isElt(node)) {
|
|
36815
36811
|
let child = node.childNodes[off + (dir < 0 ? -1 : 0)];
|
|
36816
|
-
if (child
|
|
36812
|
+
if (isElt(child) && child.contentEditable == "false") {
|
|
36817
36813
|
if ((_a = child.pmViewDesc) === null || _a === void 0 ? void 0 : _a.ignoreForSelection)
|
|
36818
36814
|
off += dir;
|
|
36819
36815
|
else
|
|
@@ -36832,11 +36828,16 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36832
36828
|
function nodeSize(node) {
|
|
36833
36829
|
return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
|
|
36834
36830
|
}
|
|
36831
|
+
function isElt(node) { return node.nodeType == 1; }
|
|
36832
|
+
function isText(node) { return node.nodeType == 3; }
|
|
36833
|
+
function contains(parent, child) {
|
|
36834
|
+
return child ? parent.contains(isElt(child) ? child : child.parentNode) : false;
|
|
36835
|
+
}
|
|
36835
36836
|
function textNodeBefore$1(node, offset) {
|
|
36836
36837
|
for (;;) {
|
|
36837
|
-
if (node
|
|
36838
|
+
if (isText(node) && offset)
|
|
36838
36839
|
return node;
|
|
36839
|
-
if (node
|
|
36840
|
+
if (isElt(node) && offset > 0) {
|
|
36840
36841
|
if (node.contentEditable == "false")
|
|
36841
36842
|
return null;
|
|
36842
36843
|
node = node.childNodes[offset - 1];
|
|
@@ -36853,9 +36854,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36853
36854
|
}
|
|
36854
36855
|
function textNodeAfter$1(node, offset) {
|
|
36855
36856
|
for (;;) {
|
|
36856
|
-
if (node
|
|
36857
|
+
if (isText(node) && offset < node.nodeValue.length)
|
|
36857
36858
|
return node;
|
|
36858
|
-
if (node
|
|
36859
|
+
if (isElt(node) && offset < node.childNodes.length) {
|
|
36859
36860
|
if (node.contentEditable == "false")
|
|
36860
36861
|
return null;
|
|
36861
36862
|
node = node.childNodes[offset];
|
|
@@ -36979,13 +36980,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36979
36980
|
for (let parent = startDOM || view.dom;;) {
|
|
36980
36981
|
if (!parent)
|
|
36981
36982
|
break;
|
|
36982
|
-
if (parent
|
|
36983
|
+
if (!isElt(parent)) {
|
|
36983
36984
|
parent = parentNode(parent);
|
|
36984
36985
|
continue;
|
|
36985
36986
|
}
|
|
36986
|
-
let
|
|
36987
|
-
let
|
|
36988
|
-
let bounding = atTop ? windowRect(doc) : clientRect(elt);
|
|
36987
|
+
let atTop = parent == doc.body;
|
|
36988
|
+
let bounding = atTop ? windowRect(doc) : clientRect(parent);
|
|
36989
36989
|
let moveX = 0, moveY = 0;
|
|
36990
36990
|
if (rect.top < bounding.top + getSide$1(scrollThreshold, "top"))
|
|
36991
36991
|
moveY = -(bounding.top - rect.top + getSide$1(scrollMargin, "top"));
|
|
@@ -37002,12 +37002,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37002
37002
|
doc.defaultView.scrollBy(moveX, moveY);
|
|
37003
37003
|
}
|
|
37004
37004
|
else {
|
|
37005
|
-
let startX =
|
|
37005
|
+
let startX = parent.scrollLeft, startY = parent.scrollTop;
|
|
37006
37006
|
if (moveY)
|
|
37007
|
-
|
|
37007
|
+
parent.scrollTop += moveY;
|
|
37008
37008
|
if (moveX)
|
|
37009
|
-
|
|
37010
|
-
let dX =
|
|
37009
|
+
parent.scrollLeft += moveX;
|
|
37010
|
+
let dX = parent.scrollLeft - startX, dY = parent.scrollTop - startY;
|
|
37011
37011
|
rect = { left: rect.left - dX, top: rect.top - dY, right: rect.right - dX, bottom: rect.bottom - dY };
|
|
37012
37012
|
}
|
|
37013
37013
|
}
|
|
@@ -37082,14 +37082,15 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37082
37082
|
}
|
|
37083
37083
|
}
|
|
37084
37084
|
function findOffsetInNode(node, coords) {
|
|
37085
|
-
let closest
|
|
37085
|
+
let closest;
|
|
37086
|
+
let dxClosest = 2e8, coordsClosest, offset = 0;
|
|
37086
37087
|
let rowBot = coords.top, rowTop = coords.top;
|
|
37087
37088
|
let firstBelow, coordsBelow;
|
|
37088
37089
|
for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {
|
|
37089
37090
|
let rects;
|
|
37090
|
-
if (child
|
|
37091
|
+
if (isElt(child))
|
|
37091
37092
|
rects = child.getClientRects();
|
|
37092
|
-
else if (child
|
|
37093
|
+
else if (isText(child))
|
|
37093
37094
|
rects = textRange(child).getClientRects();
|
|
37094
37095
|
else
|
|
37095
37096
|
continue;
|
|
@@ -37103,11 +37104,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37103
37104
|
if (dx < dxClosest) {
|
|
37104
37105
|
closest = child;
|
|
37105
37106
|
dxClosest = dx;
|
|
37106
|
-
coordsClosest = dx && closest
|
|
37107
|
+
coordsClosest = dx && isText(closest) ? {
|
|
37107
37108
|
left: rect.right < coords.left ? rect.right : rect.left,
|
|
37108
37109
|
top: coords.top
|
|
37109
37110
|
} : coords;
|
|
37110
|
-
if (child
|
|
37111
|
+
if (isElt(child) && dx)
|
|
37111
37112
|
offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);
|
|
37112
37113
|
continue;
|
|
37113
37114
|
}
|
|
@@ -37126,9 +37127,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37126
37127
|
coordsClosest = coordsBelow;
|
|
37127
37128
|
dxClosest = 0;
|
|
37128
37129
|
}
|
|
37129
|
-
if (closest && closest
|
|
37130
|
+
if (closest && isText(closest))
|
|
37130
37131
|
return findOffsetInText(closest, coordsClosest);
|
|
37131
|
-
if (!closest ||
|
|
37132
|
+
if (!closest || dxClosest)
|
|
37132
37133
|
return { node, offset };
|
|
37133
37134
|
return findOffsetInNode(closest, coordsClosest);
|
|
37134
37135
|
}
|
|
@@ -37161,7 +37162,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37161
37162
|
}
|
|
37162
37163
|
function posFromElement(view, elt, coords) {
|
|
37163
37164
|
let { node, offset } = findOffsetInNode(elt, coords), bias = -1;
|
|
37164
|
-
if (node
|
|
37165
|
+
if (isElt(node) && !node.firstChild) {
|
|
37165
37166
|
let rect = node.getBoundingClientRect();
|
|
37166
37167
|
bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1;
|
|
37167
37168
|
}
|
|
@@ -37181,7 +37182,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37181
37182
|
let desc = view.docView.nearestDesc(cur, true), rect;
|
|
37182
37183
|
if (!desc)
|
|
37183
37184
|
return null;
|
|
37184
|
-
if (desc.dom
|
|
37185
|
+
if (isElt(desc.dom) && (desc.node.isBlock && desc.parent || !desc.contentDOM) &&
|
|
37185
37186
|
// Ignore elements with zero-size bounding rectangles
|
|
37186
37187
|
((rect = desc.dom.getBoundingClientRect()).width || rect.height)) {
|
|
37187
37188
|
if (desc.node.isBlock && desc.parent && !/^T(R|BODY|HEAD|FOOT)$/.test(desc.dom.nodeName)) {
|
|
@@ -37208,7 +37209,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37208
37209
|
if (len && box.top < box.bottom) {
|
|
37209
37210
|
for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) {
|
|
37210
37211
|
let child = element.childNodes[i];
|
|
37211
|
-
if (child
|
|
37212
|
+
if (isElt(child)) {
|
|
37212
37213
|
let rects = child.getClientRects();
|
|
37213
37214
|
for (let j = 0; j < rects.length; j++) {
|
|
37214
37215
|
let rect = rects[j];
|
|
@@ -37231,7 +37232,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37231
37232
|
let elt = (view.root.elementFromPoint ? view.root : doc)
|
|
37232
37233
|
.elementFromPoint(coords.left, coords.top);
|
|
37233
37234
|
let pos;
|
|
37234
|
-
if (!elt || !view.dom.contains(elt
|
|
37235
|
+
if (!elt || !view.dom.contains(elt)) {
|
|
37235
37236
|
let box = view.dom.getBoundingClientRect();
|
|
37236
37237
|
if (!inRect(coords, box))
|
|
37237
37238
|
return null;
|
|
@@ -37247,7 +37248,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37247
37248
|
}
|
|
37248
37249
|
elt = targetKludge(elt, coords);
|
|
37249
37250
|
if (node) {
|
|
37250
|
-
if (gecko && node
|
|
37251
|
+
if (gecko && isElt(node)) {
|
|
37251
37252
|
// Firefox will sometimes return offsets into <input> nodes, which
|
|
37252
37253
|
// have no actual children, from caretPositionFromPoint (#953)
|
|
37253
37254
|
offset = Math.min(offset, node.childNodes.length);
|
|
@@ -37262,18 +37263,18 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37262
37263
|
}
|
|
37263
37264
|
let prev;
|
|
37264
37265
|
// When clicking above the right side of an uneditable node, Chrome will report a cursor position after that node.
|
|
37265
|
-
if (webkit && offset && node
|
|
37266
|
+
if (webkit && offset && isElt(node) && isElt(prev = node.childNodes[offset - 1]) &&
|
|
37266
37267
|
prev.contentEditable == "false" && prev.getBoundingClientRect().top >= coords.top)
|
|
37267
37268
|
offset--;
|
|
37268
37269
|
// Suspiciously specific kludge to work around caret*FromPoint
|
|
37269
37270
|
// never returning a position at the end of the document
|
|
37270
|
-
if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild
|
|
37271
|
+
if (node == view.dom && offset == node.childNodes.length - 1 && isElt(node.lastChild) &&
|
|
37271
37272
|
coords.top > node.lastChild.getBoundingClientRect().bottom)
|
|
37272
37273
|
pos = view.state.doc.content.size;
|
|
37273
37274
|
// Ignore positions directly after a BR, since caret*FromPoint
|
|
37274
37275
|
// 'round up' positions that would be more accurately placed
|
|
37275
37276
|
// before the BR node.
|
|
37276
|
-
else if (offset == 0 || node
|
|
37277
|
+
else if (offset == 0 || !isElt(node) || node.childNodes[offset - 1].nodeName != "BR")
|
|
37277
37278
|
pos = posFromCaret(view, node, offset, coords);
|
|
37278
37279
|
}
|
|
37279
37280
|
if (pos == null)
|
|
@@ -37299,7 +37300,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37299
37300
|
function coordsAtPos(view, pos, side) {
|
|
37300
37301
|
let { node, offset, atom } = view.docView.domFromPos(pos, side < 0 ? -1 : 1);
|
|
37301
37302
|
let supportEmptyRange = webkit || gecko;
|
|
37302
|
-
if (node
|
|
37303
|
+
if (isText(node)) {
|
|
37303
37304
|
// These browsers support querying empty text ranges. Prefer that in
|
|
37304
37305
|
// bidi context or when at the end of a node.
|
|
37305
37306
|
if (supportEmptyRange && (BIDI.test(node.nodeValue) || (side < 0 ? !offset : offset == node.nodeValue.length))) {
|
|
@@ -37341,12 +37342,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37341
37342
|
if (!$dom.parent.inlineContent) {
|
|
37342
37343
|
if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
|
|
37343
37344
|
let before = node.childNodes[offset - 1];
|
|
37344
|
-
if (before
|
|
37345
|
+
if (isElt(before))
|
|
37345
37346
|
return flattenH(before.getBoundingClientRect(), false);
|
|
37346
37347
|
}
|
|
37347
37348
|
if (atom == null && offset < nodeSize(node)) {
|
|
37348
37349
|
let after = node.childNodes[offset];
|
|
37349
|
-
if (after
|
|
37350
|
+
if (isElt(after))
|
|
37350
37351
|
return flattenH(after.getBoundingClientRect(), true);
|
|
37351
37352
|
}
|
|
37352
37353
|
return flattenH(node.getBoundingClientRect(), side >= 0);
|
|
@@ -37354,10 +37355,10 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37354
37355
|
// Inline, not in text node (this is not Bidi-safe)
|
|
37355
37356
|
if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
|
|
37356
37357
|
let before = node.childNodes[offset - 1];
|
|
37357
|
-
let target = before
|
|
37358
|
+
let target = isText(before) ? textRange(before, nodeSize(before) - (supportEmptyRange ? 0 : 1))
|
|
37358
37359
|
// BR nodes tend to only return the rectangle before them.
|
|
37359
37360
|
// Only use them if they are the last element in their parent
|
|
37360
|
-
: before
|
|
37361
|
+
: isElt(before) && (before.nodeName != "BR" || !before.nextSibling) ? before : null;
|
|
37361
37362
|
if (target)
|
|
37362
37363
|
return flattenV(singleRect(target, 1), false);
|
|
37363
37364
|
}
|
|
@@ -37365,13 +37366,13 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37365
37366
|
let after = node.childNodes[offset];
|
|
37366
37367
|
while (after.pmViewDesc && after.pmViewDesc.ignoreForCoords)
|
|
37367
37368
|
after = after.nextSibling;
|
|
37368
|
-
let target = !after ? null : after
|
|
37369
|
-
: after
|
|
37369
|
+
let target = !after ? null : isText(after) ? textRange(after, 0, (supportEmptyRange ? 0 : 1))
|
|
37370
|
+
: isElt(after) ? after : null;
|
|
37370
37371
|
if (target)
|
|
37371
37372
|
return flattenV(singleRect(target, -1), true);
|
|
37372
37373
|
}
|
|
37373
37374
|
// All else failed, just try to get a rectangle for the target node
|
|
37374
|
-
return flattenV(singleRect(node
|
|
37375
|
+
return flattenV(singleRect(isText(node) ? textRange(node) : node, -side), side >= 0);
|
|
37375
37376
|
}
|
|
37376
37377
|
function flattenV(rect, left) {
|
|
37377
37378
|
if (rect.width == 0)
|
|
@@ -37421,9 +37422,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37421
37422
|
let coords = coordsAtPos(view, $pos.pos, 1);
|
|
37422
37423
|
for (let child = dom.firstChild; child; child = child.nextSibling) {
|
|
37423
37424
|
let boxes;
|
|
37424
|
-
if (child
|
|
37425
|
+
if (isElt(child))
|
|
37425
37426
|
boxes = child.getClientRects();
|
|
37426
|
-
else if (child
|
|
37427
|
+
else if (isText(child))
|
|
37427
37428
|
boxes = textRange(child, 0, child.nodeValue.length).getClientRects();
|
|
37428
37429
|
else
|
|
37429
37430
|
continue;
|
|
@@ -37463,8 +37464,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37463
37464
|
sel.modify("move", dir, "character");
|
|
37464
37465
|
let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom;
|
|
37465
37466
|
let { focusNode: newNode, focusOffset: newOff } = view.domSelectionRange();
|
|
37466
|
-
let result = newNode && !
|
|
37467
|
-
(oldNode == newNode && oldOff == newOff);
|
|
37467
|
+
let result = newNode && !contains(parentDOM, newNode) || (oldNode == newNode && oldOff == newOff);
|
|
37468
37468
|
// Restore the previous selection
|
|
37469
37469
|
try {
|
|
37470
37470
|
sel.collapse(anchorNode, anchorOffset);
|
|
@@ -37572,7 +37572,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37572
37572
|
localPosFromDOM(dom, offset, bias) {
|
|
37573
37573
|
// If the DOM position is in the content, use the child desc after
|
|
37574
37574
|
// it to figure out a position.
|
|
37575
|
-
if (this.contentDOM && this.contentDOM
|
|
37575
|
+
if (this.contentDOM && contains(this.contentDOM, dom)) {
|
|
37576
37576
|
if (bias < 0) {
|
|
37577
37577
|
let domBefore, desc;
|
|
37578
37578
|
if (dom == this.contentDOM) {
|
|
@@ -37610,7 +37610,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37610
37610
|
atEnd = offset > domIndex(this.contentDOM);
|
|
37611
37611
|
}
|
|
37612
37612
|
else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
|
|
37613
|
-
atEnd = dom.compareDocumentPosition(this.contentDOM) &
|
|
37613
|
+
atEnd = !!(dom.compareDocumentPosition(this.contentDOM) & 4);
|
|
37614
37614
|
}
|
|
37615
37615
|
else if (this.dom.firstChild) {
|
|
37616
37616
|
if (offset == 0)
|
|
@@ -37640,7 +37640,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37640
37640
|
if (desc && (!onlyNodes || desc.node)) {
|
|
37641
37641
|
// If dom is outside of this desc's nodeDOM, don't count it.
|
|
37642
37642
|
if (first && (nodeDOM = desc.nodeDOM) &&
|
|
37643
|
-
!(nodeDOM
|
|
37643
|
+
!(isElt(nodeDOM) ? contains(nodeDOM, dom) : nodeDOM == dom))
|
|
37644
37644
|
first = false;
|
|
37645
37645
|
else
|
|
37646
37646
|
return desc;
|
|
@@ -37690,7 +37690,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37690
37690
|
let i = 0, offset = 0;
|
|
37691
37691
|
for (let curPos = 0; i < this.children.length; i++) {
|
|
37692
37692
|
let child = this.children[i], end = curPos + child.size;
|
|
37693
|
-
if (end > pos
|
|
37693
|
+
if (end > pos) {
|
|
37694
37694
|
offset = pos - curPos;
|
|
37695
37695
|
break;
|
|
37696
37696
|
}
|
|
@@ -37700,7 +37700,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37700
37700
|
if (offset)
|
|
37701
37701
|
return this.children[i].domFromPos(offset - this.children[i].border, side);
|
|
37702
37702
|
// Go back if there were any zero-length widgets with side >= 0 before this point
|
|
37703
|
-
for (
|
|
37703
|
+
for (; i > 0; i--) {
|
|
37704
|
+
let prev = this.children[i - 1];
|
|
37705
|
+
if (prev.size || !(prev instanceof BufferHackViewDesc || prev instanceof WidgetViewDesc && prev.side >= 0))
|
|
37706
|
+
break;
|
|
37707
|
+
}
|
|
37704
37708
|
// Scan towards the first useable node
|
|
37705
37709
|
if (side <= 0) {
|
|
37706
37710
|
let prev, enter = true;
|
|
@@ -37777,7 +37781,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37777
37781
|
}
|
|
37778
37782
|
domAfterPos(pos) {
|
|
37779
37783
|
let { node, offset } = this.domFromPos(pos, 0);
|
|
37780
|
-
if (node
|
|
37784
|
+
if (!isElt(node) || offset == node.childNodes.length)
|
|
37781
37785
|
throw new RangeError("No node after pos " + pos);
|
|
37782
37786
|
return node.childNodes[offset];
|
|
37783
37787
|
}
|
|
@@ -37806,7 +37810,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37806
37810
|
// reported position in such situations (#1092).
|
|
37807
37811
|
if ((gecko || safari) && anchor == head) {
|
|
37808
37812
|
let { node, offset } = anchorDOM;
|
|
37809
|
-
if (node
|
|
37813
|
+
if (isText(node)) {
|
|
37810
37814
|
brKludge = !!(offset && node.nodeValue[offset - 1] == "\n");
|
|
37811
37815
|
// Issue #1128
|
|
37812
37816
|
if (brKludge && offset == node.nodeValue.length) {
|
|
@@ -37829,7 +37833,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37829
37833
|
}
|
|
37830
37834
|
// Firefox can act strangely when the selection is in front of an
|
|
37831
37835
|
// uneditable node. See #1163 and https://bugzilla.mozilla.org/show_bug.cgi?id=1709536
|
|
37832
|
-
if (gecko && selRange.focusNode && selRange.focusNode != headDOM.node && selRange.focusNode
|
|
37836
|
+
if (gecko && selRange.focusNode && selRange.focusNode != headDOM.node && isElt(selRange.focusNode)) {
|
|
37833
37837
|
let after = selRange.focusNode.childNodes[selRange.focusOffset];
|
|
37834
37838
|
if (after && after.contentEditable == "false")
|
|
37835
37839
|
force = true;
|
|
@@ -37928,14 +37932,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37928
37932
|
return self.parent.posBeforeChild(self);
|
|
37929
37933
|
});
|
|
37930
37934
|
if (!widget.type.spec.raw) {
|
|
37931
|
-
|
|
37932
|
-
|
|
37933
|
-
|
|
37934
|
-
|
|
37935
|
-
|
|
37936
|
-
|
|
37937
|
-
dom.contentEditable = "false";
|
|
37938
|
-
dom.classList.add("ProseMirror-widget");
|
|
37935
|
+
let elt = isElt(dom) ? dom : document.createElement("span");
|
|
37936
|
+
if (elt != dom)
|
|
37937
|
+
elt.appendChild(dom);
|
|
37938
|
+
if (!elt.hasAttribute("contenteditable"))
|
|
37939
|
+
elt.contentEditable = "false";
|
|
37940
|
+
elt.classList.add("ProseMirror-widget");
|
|
37939
37941
|
}
|
|
37940
37942
|
super(parent, [], dom, null);
|
|
37941
37943
|
this.widget = widget;
|
|
@@ -38071,7 +38073,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38071
38073
|
if (node.isText) {
|
|
38072
38074
|
if (!dom)
|
|
38073
38075
|
dom = document.createTextNode(node.text);
|
|
38074
|
-
else if (dom
|
|
38076
|
+
else if (!isText(dom))
|
|
38075
38077
|
throw new RangeError("Text must be rendered as a DOM text node");
|
|
38076
38078
|
}
|
|
38077
38079
|
else if (!dom) {
|
|
@@ -38123,7 +38125,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38123
38125
|
}
|
|
38124
38126
|
if (!rule.contentElement) {
|
|
38125
38127
|
let found = addedNodes &&
|
|
38126
|
-
addedNodes.find(n => n
|
|
38128
|
+
addedNodes.find(n => isElt(n) && addedNodes.indexOf(n.parentNode) < 0 && this.dom.contains(n));
|
|
38127
38129
|
if (found)
|
|
38128
38130
|
rule.contentElement = found;
|
|
38129
38131
|
else
|
|
@@ -38148,6 +38150,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38148
38150
|
let localComposition = composition && composition.pos > -1 ? composition : null;
|
|
38149
38151
|
let compositionInChild = composition && composition.pos < 0;
|
|
38150
38152
|
let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
|
|
38153
|
+
let addBuffers = this.node.inlineContent, atBufferPos = addBuffers && this.node.isBlock;
|
|
38151
38154
|
iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => {
|
|
38152
38155
|
if (widget.spec.marks)
|
|
38153
38156
|
updater.syncToMarks(widget.spec.marks, inline, view, i);
|
|
@@ -38159,6 +38162,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38159
38162
|
}, (child, outerDeco, innerDeco, i) => {
|
|
38160
38163
|
// Make sure the wrapping mark descs match the node's marks.
|
|
38161
38164
|
updater.syncToMarks(child.marks, inline, view, i);
|
|
38165
|
+
if (atBufferPos && child.isAtom && !child.isText)
|
|
38166
|
+
updater.addHackNode("IMG", updater.top);
|
|
38162
38167
|
// Try several strategies for drawing this node
|
|
38163
38168
|
let compIndex;
|
|
38164
38169
|
if (updater.findNodeMatch(child, outerDeco, innerDeco, i)) ;
|
|
@@ -38172,6 +38177,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38172
38177
|
updater.addNode(child, outerDeco, innerDeco, view, off);
|
|
38173
38178
|
}
|
|
38174
38179
|
off += child.nodeSize;
|
|
38180
|
+
if (addBuffers)
|
|
38181
|
+
atBufferPos = child.isAtom && !child.isText;
|
|
38175
38182
|
});
|
|
38176
38183
|
// Drop all remaining descs after the current position.
|
|
38177
38184
|
updater.syncToMarks([], inline, view, 0);
|
|
@@ -38250,7 +38257,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38250
38257
|
updateOuterDeco(outerDeco) {
|
|
38251
38258
|
if (sameOuterDeco(outerDeco, this.outerDeco))
|
|
38252
38259
|
return;
|
|
38253
|
-
let needsWrap = this.nodeDOM
|
|
38260
|
+
let needsWrap = !isElt(this.nodeDOM);
|
|
38254
38261
|
let oldDOM = this.dom;
|
|
38255
38262
|
this.dom = patchOuterDeco(this.dom, this.nodeDOM, computeOuterDeco(this.outerDeco, this.node, needsWrap), computeOuterDeco(outerDeco, this.node, needsWrap));
|
|
38256
38263
|
if (this.dom != oldDOM) {
|
|
@@ -38261,7 +38268,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38261
38268
|
}
|
|
38262
38269
|
// Mark this node as being the selected node.
|
|
38263
38270
|
selectNode() {
|
|
38264
|
-
if (this.nodeDOM
|
|
38271
|
+
if (isElt(this.nodeDOM)) {
|
|
38265
38272
|
this.nodeDOM.classList.add("ProseMirror-selectednode");
|
|
38266
38273
|
if (this.contentDOM || !this.node.type.spec.draggable)
|
|
38267
38274
|
this.nodeDOM.draggable = true;
|
|
@@ -38269,7 +38276,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38269
38276
|
}
|
|
38270
38277
|
// Remove selected node marking from this node.
|
|
38271
38278
|
deselectNode() {
|
|
38272
|
-
if (this.nodeDOM
|
|
38279
|
+
if (isElt(this.nodeDOM)) {
|
|
38273
38280
|
this.nodeDOM.classList.remove("ProseMirror-selectednode");
|
|
38274
38281
|
if (this.contentDOM || !this.node.type.spec.draggable)
|
|
38275
38282
|
this.nodeDOM.removeAttribute("draggable");
|
|
@@ -38340,9 +38347,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38340
38347
|
get domAtom() { return false; }
|
|
38341
38348
|
isText(text) { return this.node.text == text; }
|
|
38342
38349
|
}
|
|
38343
|
-
// A dummy desc used to tag
|
|
38350
|
+
// A dummy desc used to tag extra BR or IMG nodes created to work
|
|
38344
38351
|
// around contentEditable terribleness.
|
|
38345
|
-
class
|
|
38352
|
+
class BufferHackViewDesc extends ViewDesc {
|
|
38346
38353
|
parseRule() { return { ignore: true }; }
|
|
38347
38354
|
matchesHack(nodeName) { return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName; }
|
|
38348
38355
|
get domAtom() { return true; }
|
|
@@ -38515,7 +38522,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38515
38522
|
}
|
|
38516
38523
|
}
|
|
38517
38524
|
function applyOuterDeco(dom, deco, node) {
|
|
38518
|
-
return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom
|
|
38525
|
+
return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, !isElt(dom)));
|
|
38519
38526
|
}
|
|
38520
38527
|
function sameOuterDeco(a, b) {
|
|
38521
38528
|
if (a.length != b.length)
|
|
@@ -38778,7 +38785,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38778
38785
|
}
|
|
38779
38786
|
if (nodeName == "BR")
|
|
38780
38787
|
dom.className = "ProseMirror-trailingBreak";
|
|
38781
|
-
let hack = new
|
|
38788
|
+
let hack = new BufferHackViewDesc(this.top, [], dom, null);
|
|
38782
38789
|
if (parent != this.top)
|
|
38783
38790
|
parent.children.push(hack);
|
|
38784
38791
|
else
|
|
@@ -38787,7 +38794,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38787
38794
|
}
|
|
38788
38795
|
}
|
|
38789
38796
|
isLocked(node) {
|
|
38790
|
-
return this.lock && (node == this.lock || node
|
|
38797
|
+
return this.lock && (node == this.lock || isElt(node) && node.contains(this.lock.parentNode));
|
|
38791
38798
|
}
|
|
38792
38799
|
}
|
|
38793
38800
|
// Iterate from the end of the fragment and array of descs to find
|
|
@@ -38989,12 +38996,27 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38989
38996
|
anchor = head;
|
|
38990
38997
|
while (nearestDesc && !nearestDesc.node)
|
|
38991
38998
|
nearestDesc = nearestDesc.parent;
|
|
38992
|
-
|
|
38993
|
-
|
|
38994
|
-
|
|
38999
|
+
if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) &&
|
|
39000
|
+
nearestDesc.parent &&
|
|
39001
|
+
!(nearestDesc.node.isInline && isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) {
|
|
38995
39002
|
let pos = nearestDesc.posBefore;
|
|
38996
39003
|
selection = new NodeSelection(head == pos ? $head : doc.resolve(pos));
|
|
38997
39004
|
}
|
|
39005
|
+
else if (gecko && origin == "key" && head > view.state.selection.to &&
|
|
39006
|
+
isElt(domSel.focusNode) && domSel.focusOffset == domSel.focusNode.childNodes.length &&
|
|
39007
|
+
nearestDesc && nearestDesc.posAtStart > view.state.selection.to) {
|
|
39008
|
+
// Firefox will jump across scrollable wrapper nodes on keyboard
|
|
39009
|
+
// cursor motion (#1594). This tries to detect this situation
|
|
39010
|
+
// and work around it.
|
|
39011
|
+
for (let scan = domSel.focusNode;; scan = scan.parentNode) {
|
|
39012
|
+
if (getComputedStyle(scan).overflow != "visible") {
|
|
39013
|
+
selection = Selection$2.findFrom(doc.resolve(nearestDesc.posAtStart), 1);
|
|
39014
|
+
break;
|
|
39015
|
+
}
|
|
39016
|
+
if (scan == nearestDesc.dom || scan.nextSibling || !scan.parentNode || !isElt(scan.parentNode))
|
|
39017
|
+
break;
|
|
39018
|
+
}
|
|
39019
|
+
}
|
|
38998
39020
|
}
|
|
38999
39021
|
else {
|
|
39000
39022
|
if (domSel instanceof view.dom.ownerDocument.defaultView.Selection && domSel.rangeCount > 1) {
|
|
@@ -39180,8 +39202,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39180
39202
|
// Firefox will raise 'permission denied' errors when accessing
|
|
39181
39203
|
// properties of `sel.anchorNode` when it's in a generated CSS
|
|
39182
39204
|
// element.
|
|
39183
|
-
return view.dom
|
|
39184
|
-
(view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode));
|
|
39205
|
+
return contains(view.dom, sel.anchorNode) && (view.editable || contains(view.dom, sel.focusNode));
|
|
39185
39206
|
}
|
|
39186
39207
|
catch (_) {
|
|
39187
39208
|
return false;
|
|
@@ -39232,15 +39253,14 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39232
39253
|
if (NodeSelection.isSelectable(node)) {
|
|
39233
39254
|
return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head));
|
|
39234
39255
|
}
|
|
39235
|
-
else
|
|
39256
|
+
else {
|
|
39236
39257
|
// Chrome and Safari will introduce extra pointless cursor
|
|
39237
|
-
// positions around inline uneditable nodes,
|
|
39238
|
-
//
|
|
39258
|
+
// positions around inline uneditable nodes (#937), and
|
|
39259
|
+
// Firefox will sometimes just plain refuse to move across
|
|
39260
|
+
// them (#1592), so in this situation we move the cursor
|
|
39261
|
+
// ourselves.
|
|
39239
39262
|
return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize)));
|
|
39240
39263
|
}
|
|
39241
|
-
else {
|
|
39242
|
-
return false;
|
|
39243
|
-
}
|
|
39244
39264
|
}
|
|
39245
39265
|
}
|
|
39246
39266
|
else if (sel instanceof NodeSelection && sel.node.isInline) {
|
|
@@ -39253,12 +39273,10 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39253
39273
|
return false;
|
|
39254
39274
|
}
|
|
39255
39275
|
}
|
|
39256
|
-
function nodeLen(node) {
|
|
39257
|
-
return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
|
|
39258
|
-
}
|
|
39259
39276
|
function isIgnorable(dom, dir) {
|
|
39260
39277
|
let desc = dom.pmViewDesc;
|
|
39261
|
-
return desc
|
|
39278
|
+
return desc ? desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR")
|
|
39279
|
+
: isElt(dom) && dom.contentEditable == "false";
|
|
39262
39280
|
}
|
|
39263
39281
|
function skipIgnoredNodes(view, dir) {
|
|
39264
39282
|
return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view);
|
|
@@ -39274,25 +39292,23 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39274
39292
|
// Gecko will do odd things when the selection is directly in front
|
|
39275
39293
|
// of a non-editable node, so in that case, move it into the next
|
|
39276
39294
|
// node if possible. Issue prosemirror/prosemirror#832.
|
|
39277
|
-
if (gecko && node
|
|
39295
|
+
if (gecko && isElt(node) && offset < nodeSize(node) && isIgnorable(node.childNodes[offset], -1))
|
|
39278
39296
|
force = true;
|
|
39279
39297
|
for (;;) {
|
|
39280
39298
|
if (offset > 0) {
|
|
39281
|
-
if (node
|
|
39299
|
+
if (!isElt(node))
|
|
39282
39300
|
break;
|
|
39301
|
+
let before = node.childNodes[offset - 1];
|
|
39302
|
+
if (isIgnorable(before, -1)) {
|
|
39303
|
+
moveNode = node;
|
|
39304
|
+
moveOffset = --offset;
|
|
39305
|
+
}
|
|
39306
|
+
else if (isText(before)) {
|
|
39307
|
+
node = before;
|
|
39308
|
+
offset = node.nodeValue.length;
|
|
39283
39309
|
}
|
|
39284
39310
|
else {
|
|
39285
|
-
|
|
39286
|
-
if (isIgnorable(before, -1)) {
|
|
39287
|
-
moveNode = node;
|
|
39288
|
-
moveOffset = --offset;
|
|
39289
|
-
}
|
|
39290
|
-
else if (before.nodeType == 3) {
|
|
39291
|
-
node = before;
|
|
39292
|
-
offset = node.nodeValue.length;
|
|
39293
|
-
}
|
|
39294
|
-
else
|
|
39295
|
-
break;
|
|
39311
|
+
break;
|
|
39296
39312
|
}
|
|
39297
39313
|
}
|
|
39298
39314
|
else if (isBlockNode(node)) {
|
|
@@ -39313,7 +39329,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39313
39329
|
}
|
|
39314
39330
|
else {
|
|
39315
39331
|
node = prev;
|
|
39316
|
-
offset =
|
|
39332
|
+
offset = nodeSize(node);
|
|
39317
39333
|
}
|
|
39318
39334
|
}
|
|
39319
39335
|
}
|
|
@@ -39329,19 +39345,20 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39329
39345
|
let node = sel.focusNode, offset = sel.focusOffset;
|
|
39330
39346
|
if (!node)
|
|
39331
39347
|
return;
|
|
39332
|
-
let len =
|
|
39348
|
+
let len = nodeSize(node);
|
|
39333
39349
|
let moveNode, moveOffset;
|
|
39334
39350
|
for (;;) {
|
|
39335
39351
|
if (offset < len) {
|
|
39336
|
-
if (node
|
|
39352
|
+
if (!isElt(node))
|
|
39337
39353
|
break;
|
|
39338
39354
|
let after = node.childNodes[offset];
|
|
39339
39355
|
if (isIgnorable(after, 1)) {
|
|
39340
39356
|
moveNode = node;
|
|
39341
39357
|
moveOffset = ++offset;
|
|
39342
39358
|
}
|
|
39343
|
-
else
|
|
39359
|
+
else {
|
|
39344
39360
|
break;
|
|
39361
|
+
}
|
|
39345
39362
|
}
|
|
39346
39363
|
else if (isBlockNode(node)) {
|
|
39347
39364
|
break;
|
|
@@ -39362,7 +39379,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39362
39379
|
else {
|
|
39363
39380
|
node = next;
|
|
39364
39381
|
offset = 0;
|
|
39365
|
-
len =
|
|
39382
|
+
len = nodeSize(node);
|
|
39366
39383
|
}
|
|
39367
39384
|
}
|
|
39368
39385
|
}
|
|
@@ -39380,9 +39397,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39380
39397
|
}
|
|
39381
39398
|
while (node && offset < node.childNodes.length) {
|
|
39382
39399
|
let next = node.childNodes[offset];
|
|
39383
|
-
if (next
|
|
39400
|
+
if (isText(next))
|
|
39384
39401
|
return next;
|
|
39385
|
-
if (next
|
|
39402
|
+
if (isElt(next) && next.contentEditable == "false")
|
|
39386
39403
|
break;
|
|
39387
39404
|
node = next;
|
|
39388
39405
|
offset = 0;
|
|
@@ -39395,16 +39412,16 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39395
39412
|
}
|
|
39396
39413
|
while (node && offset) {
|
|
39397
39414
|
let next = node.childNodes[offset - 1];
|
|
39398
|
-
if (next
|
|
39415
|
+
if (isText(next))
|
|
39399
39416
|
return next;
|
|
39400
|
-
if (next
|
|
39417
|
+
if (isElt(next) && next.contentEditable == "false")
|
|
39401
39418
|
break;
|
|
39402
39419
|
node = next;
|
|
39403
39420
|
offset = node.childNodes.length;
|
|
39404
39421
|
}
|
|
39405
39422
|
}
|
|
39406
39423
|
function setSelFocus(view, node, offset) {
|
|
39407
|
-
if (node
|
|
39424
|
+
if (!isText(node)) {
|
|
39408
39425
|
let before, after;
|
|
39409
39426
|
if (after = textNodeAfter(node, offset)) {
|
|
39410
39427
|
node = after;
|
|
@@ -39514,8 +39531,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39514
39531
|
if (!safari || view.state.selection.$head.parentOffset > 0)
|
|
39515
39532
|
return false;
|
|
39516
39533
|
let { focusNode, focusOffset } = view.domSelectionRange();
|
|
39517
|
-
if (focusNode && focusNode
|
|
39518
|
-
focusNode.firstChild && focusNode.firstChild.contentEditable == "false") {
|
|
39534
|
+
if (focusNode && isElt(focusNode) && focusOffset == 0 &&
|
|
39535
|
+
focusNode.firstChild && isElt(focusNode.firstChild) && focusNode.firstChild.contentEditable == "false") {
|
|
39519
39536
|
let child = focusNode.firstChild;
|
|
39520
39537
|
switchEditable(view, child, "true");
|
|
39521
39538
|
setTimeout(() => switchEditable(view, child, "false"), 20);
|
|
@@ -39586,7 +39603,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39586
39603
|
let doc = detachedDoc(), wrap = doc.createElement("div");
|
|
39587
39604
|
wrap.appendChild(serializer.serializeFragment(content, { document: doc }));
|
|
39588
39605
|
let firstChild = wrap.firstChild, needsWrap, wrappers = 0;
|
|
39589
|
-
while (firstChild && firstChild
|
|
39606
|
+
while (firstChild && isElt(firstChild) && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) {
|
|
39590
39607
|
for (let i = needsWrap.length - 1; i >= 0; i--) {
|
|
39591
39608
|
let wrapper = doc.createElement(needsWrap[i]);
|
|
39592
39609
|
while (wrap.firstChild)
|
|
@@ -39596,7 +39613,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39596
39613
|
}
|
|
39597
39614
|
firstChild = wrap.firstChild;
|
|
39598
39615
|
}
|
|
39599
|
-
if (firstChild && firstChild
|
|
39616
|
+
if (firstChild && isElt(firstChild))
|
|
39600
39617
|
firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`);
|
|
39601
39618
|
let text = view.someProp("clipboardTextSerializer", f => f(slice, view)) ||
|
|
39602
39619
|
slice.content.textBetween(0, slice.content.size, "\n\n");
|
|
@@ -39642,7 +39659,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39642
39659
|
if (sliceData && sliceData[3])
|
|
39643
39660
|
for (let i = +sliceData[3]; i > 0; i--) {
|
|
39644
39661
|
let child = dom.firstChild;
|
|
39645
|
-
while (child && child
|
|
39662
|
+
while (child && !isElt(child))
|
|
39646
39663
|
child = child.nextSibling;
|
|
39647
39664
|
if (!child)
|
|
39648
39665
|
break;
|
|
@@ -39847,12 +39864,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39847
39864
|
if (!type || type.hasRequiredAttrs())
|
|
39848
39865
|
break;
|
|
39849
39866
|
try {
|
|
39850
|
-
type.
|
|
39867
|
+
content = Fragment.from(type.create(array[i + 1], content));
|
|
39851
39868
|
}
|
|
39852
39869
|
catch (e) {
|
|
39853
39870
|
break;
|
|
39854
39871
|
}
|
|
39855
|
-
content = Fragment.from(type.create(array[i + 1], content));
|
|
39856
39872
|
openStart++;
|
|
39857
39873
|
openEnd++;
|
|
39858
39874
|
}
|
|
@@ -40184,7 +40200,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40184
40200
|
}
|
|
40185
40201
|
const target = flushed ? null : event.target;
|
|
40186
40202
|
const targetDesc = target ? view.docView.nearestDesc(target, true) : null;
|
|
40187
|
-
this.target = targetDesc && targetDesc.nodeDOM
|
|
40203
|
+
this.target = targetDesc && isElt(targetDesc.nodeDOM) ? targetDesc.nodeDOM : null;
|
|
40188
40204
|
let { selection } = view.state;
|
|
40189
40205
|
if (event.button == 0 &&
|
|
40190
40206
|
(targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
|
|
@@ -40332,7 +40348,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40332
40348
|
if (!view.composing) {
|
|
40333
40349
|
view.domObserver.flush();
|
|
40334
40350
|
let { state } = view, $pos = state.selection.$to;
|
|
40335
|
-
if (state.selection instanceof TextSelection &&
|
|
40351
|
+
if (state.selection instanceof TextSelection && state.selection.empty &&
|
|
40336
40352
|
(state.storedMarks ||
|
|
40337
40353
|
(!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)) ||
|
|
40338
40354
|
chrome && windows$1 && selectionBeforeUneditable(view))) { // Issue #1500
|
|
@@ -40348,11 +40364,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40348
40364
|
// inside if necessary.
|
|
40349
40365
|
if (gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) {
|
|
40350
40366
|
let sel = view.domSelectionRange();
|
|
40351
|
-
for (let node = sel.focusNode, offset = sel.focusOffset; node && node
|
|
40367
|
+
for (let node = sel.focusNode, offset = sel.focusOffset; node && isElt(node) && offset != 0;) {
|
|
40352
40368
|
let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1];
|
|
40353
40369
|
if (!before)
|
|
40354
40370
|
break;
|
|
40355
|
-
if (before
|
|
40371
|
+
if (isText(before)) {
|
|
40356
40372
|
let sel = view.domSelection();
|
|
40357
40373
|
if (sel)
|
|
40358
40374
|
sel.collapse(before, before.nodeValue.length);
|
|
@@ -40371,10 +40387,10 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40371
40387
|
};
|
|
40372
40388
|
function selectionBeforeUneditable(view) {
|
|
40373
40389
|
let { focusNode, focusOffset } = view.domSelectionRange();
|
|
40374
|
-
if (!focusNode || focusNode
|
|
40390
|
+
if (!focusNode || !isElt(focusNode) || focusOffset >= focusNode.childNodes.length)
|
|
40375
40391
|
return false;
|
|
40376
40392
|
let next = focusNode.childNodes[focusOffset];
|
|
40377
|
-
return next
|
|
40393
|
+
return isElt(next) && next.contentEditable == "false";
|
|
40378
40394
|
}
|
|
40379
40395
|
editHandlers.compositionend = (view, event) => {
|
|
40380
40396
|
if (view.composing) {
|
|
@@ -40576,7 +40592,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40576
40592
|
else if (mouseDown && mouseDown.mightDrag) {
|
|
40577
40593
|
node = NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos);
|
|
40578
40594
|
}
|
|
40579
|
-
else if (event.target && event.target
|
|
40595
|
+
else if (event.target && isElt(event.target)) {
|
|
40580
40596
|
let desc = view.docView.nearestDesc(event.target, true);
|
|
40581
40597
|
if (desc && desc.node.type.spec.draggable && desc != view.docView)
|
|
40582
40598
|
node = NodeSelection.create(view.state.doc, desc.posBefore);
|
|
@@ -41547,7 +41563,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41547
41563
|
let desc = container && this.view.docView.nearestDesc(container);
|
|
41548
41564
|
if (desc && desc.ignoreMutation({
|
|
41549
41565
|
type: "selection",
|
|
41550
|
-
target: container
|
|
41566
|
+
target: isText(container) ? container.parentNode : container
|
|
41551
41567
|
})) {
|
|
41552
41568
|
this.setCurSelection();
|
|
41553
41569
|
return true;
|
|
@@ -41589,7 +41605,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41589
41605
|
for (let node of added)
|
|
41590
41606
|
if (node.nodeName == "BR" && node.parentNode) {
|
|
41591
41607
|
let after = node.nextSibling;
|
|
41592
|
-
while (after && after
|
|
41608
|
+
while (after && isElt(after)) {
|
|
41593
41609
|
if (after.contentEditable == "false") {
|
|
41594
41610
|
node.parentNode.removeChild(node);
|
|
41595
41611
|
break;
|
|
@@ -41662,7 +41678,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41662
41678
|
for (let i = 0; i < mut.addedNodes.length; i++) {
|
|
41663
41679
|
let node = mut.addedNodes[i];
|
|
41664
41680
|
added.push(node);
|
|
41665
|
-
if (node
|
|
41681
|
+
if (isText(node))
|
|
41666
41682
|
this.lastChangedTextNode = node;
|
|
41667
41683
|
}
|
|
41668
41684
|
if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target))
|
|
@@ -41777,8 +41793,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41777
41793
|
let parent = nextCell;
|
|
41778
41794
|
for (;;) {
|
|
41779
41795
|
let first = parent.firstChild;
|
|
41780
|
-
if (!first || first
|
|
41781
|
-
/^(BR|IMG)$/.test(first.nodeName))
|
|
41796
|
+
if (!first || !isElt(first) || first.contentEditable == "false" || /^(BR|IMG)$/.test(first.nodeName))
|
|
41782
41797
|
break;
|
|
41783
41798
|
parent = first;
|
|
41784
41799
|
}
|
|
@@ -41803,7 +41818,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41803
41818
|
let domSel = view.domSelectionRange();
|
|
41804
41819
|
let find;
|
|
41805
41820
|
let anchor = domSel.anchorNode;
|
|
41806
|
-
if (anchor && view.dom
|
|
41821
|
+
if (anchor && contains(view.dom, anchor)) {
|
|
41807
41822
|
find = [{ node: anchor, offset: domSel.anchorOffset }];
|
|
41808
41823
|
if (!selectionCollapsed(domSel))
|
|
41809
41824
|
find.push({ node: domSel.focusNode, offset: domSel.focusOffset });
|
|
@@ -41911,7 +41926,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41911
41926
|
if (change)
|
|
41912
41927
|
view.input.domChangeCount++;
|
|
41913
41928
|
if ((ios && view.input.lastIOSEnter > Date.now() - 225 || android) &&
|
|
41914
|
-
addedNodes.some(n => n
|
|
41929
|
+
addedNodes.some(n => isElt(n) && !isInline.test(n.nodeName)) &&
|
|
41915
41930
|
(!change || change.endA >= change.endB) &&
|
|
41916
41931
|
view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
|
|
41917
41932
|
view.input.lastIOSEnter = 0;
|
|
@@ -41969,9 +41984,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41969
41984
|
// as being an iOS enter press), just dispatch an Enter key instead.
|
|
41970
41985
|
if (((ios && view.input.lastIOSEnter > Date.now() - 225 &&
|
|
41971
41986
|
(!inlineChange || addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P"))) ||
|
|
41972
|
-
(!inlineChange && $from.pos
|
|
41973
|
-
(!$from.sameParent($to) || !$from.parent.inlineContent) &&
|
|
41974
|
-
$from.pos < $to.pos && !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")))) &&
|
|
41987
|
+
(!inlineChange && looksLikeEnter(parse.doc, $from.pos, $to.pos))) &&
|
|
41975
41988
|
view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
|
|
41976
41989
|
view.input.lastIOSEnter = 0;
|
|
41977
41990
|
return;
|
|
@@ -42122,6 +42135,16 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42122
42135
|
// The fragments after the join point must match
|
|
42123
42136
|
return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content);
|
|
42124
42137
|
}
|
|
42138
|
+
function looksLikeEnter(content, from, to) {
|
|
42139
|
+
let newTextlines = 0, newLeaves = 0;
|
|
42140
|
+
content.nodesBetween(from, to, (node, pos) => {
|
|
42141
|
+
if (node.isTextblock && pos >= from && pos < to)
|
|
42142
|
+
newTextlines++;
|
|
42143
|
+
else if (node.isText ? /\S/.test(node.text.slice(Math.max(0, from - pos), Math.min(node.nodeSize, to - pos))) : node.isLeaf)
|
|
42144
|
+
newLeaves++;
|
|
42145
|
+
});
|
|
42146
|
+
return newLeaves == 0 && newTextlines == 1;
|
|
42147
|
+
}
|
|
42125
42148
|
function skipClosingAndOpening($pos, fromEnd, mayOpen) {
|
|
42126
42149
|
let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos;
|
|
42127
42150
|
while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) {
|
|
@@ -42382,11 +42405,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42382
42405
|
*/
|
|
42383
42406
|
scrollToSelection() {
|
|
42384
42407
|
let startDOM = this.domSelectionRange().focusNode;
|
|
42385
|
-
if (!startDOM || !this.dom
|
|
42408
|
+
if (!startDOM || !contains(this.dom, startDOM)) ;
|
|
42386
42409
|
else if (this.someProp("handleScrollToSelection", f => f(this))) ;
|
|
42387
42410
|
else if (this.state.selection instanceof NodeSelection) {
|
|
42388
42411
|
let target = this.docView.domAfterPos(this.state.selection.from);
|
|
42389
|
-
if (target
|
|
42412
|
+
if (isElt(target))
|
|
42390
42413
|
scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
|
|
42391
42414
|
}
|
|
42392
42415
|
else {
|
|
@@ -42651,7 +42674,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42651
42674
|
@internal
|
|
42652
42675
|
*/
|
|
42653
42676
|
domSelectionRange() {
|
|
42654
|
-
let sel = this.domSelection();
|
|
42677
|
+
let sel = this.dom.isConnected !== false && this.domSelection();
|
|
42655
42678
|
if (!sel)
|
|
42656
42679
|
return { focusNode: null, focusOffset: 0, anchorNode: null, anchorOffset: 0 };
|
|
42657
42680
|
return safari && this.root.nodeType === 11 &&
|
|
@@ -42982,399 +43005,1030 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42982
43005
|
};
|
|
42983
43006
|
}
|
|
42984
43007
|
|
|
42985
|
-
|
|
42986
|
-
|
|
42987
|
-
|
|
42988
|
-
|
|
42989
|
-
|
|
42990
|
-
|
|
42991
|
-
|
|
42992
|
-
|
|
42993
|
-
|
|
42994
|
-
|
|
42995
|
-
|
|
42996
|
-
|
|
42997
|
-
|
|
42998
|
-
|
|
42999
|
-
|
|
43000
|
-
plugins: state.plugins,
|
|
43001
|
-
schema: state.schema,
|
|
43002
|
-
reconfigure: state.reconfigure.bind(state),
|
|
43003
|
-
toJSON: state.toJSON.bind(state),
|
|
43004
|
-
get storedMarks() {
|
|
43005
|
-
return storedMarks;
|
|
43006
|
-
},
|
|
43007
|
-
get selection() {
|
|
43008
|
-
return selection;
|
|
43009
|
-
},
|
|
43010
|
-
get doc() {
|
|
43011
|
-
return doc;
|
|
43012
|
-
},
|
|
43013
|
-
get tr() {
|
|
43014
|
-
selection = transaction.selection;
|
|
43015
|
-
doc = transaction.doc;
|
|
43016
|
-
storedMarks = transaction.storedMarks;
|
|
43017
|
-
return transaction;
|
|
43018
|
-
}
|
|
43019
|
-
};
|
|
43020
|
-
}
|
|
43021
|
-
//#endregion
|
|
43022
|
-
//#region src/CommandManager.ts
|
|
43023
|
-
var CommandManager = class CommandManager {
|
|
43024
|
-
constructor(props) {
|
|
43025
|
-
this.editor = props.editor;
|
|
43026
|
-
this.rawCommands = this.editor.extensionManager.commands;
|
|
43027
|
-
this.customState = props.state;
|
|
43028
|
-
}
|
|
43029
|
-
get hasCustomState() {
|
|
43030
|
-
return !!this.customState;
|
|
43031
|
-
}
|
|
43032
|
-
get state() {
|
|
43033
|
-
return this.customState || this.editor.state;
|
|
43034
|
-
}
|
|
43035
|
-
get commands() {
|
|
43036
|
-
const { rawCommands, editor, state } = this;
|
|
43037
|
-
const { view } = editor;
|
|
43038
|
-
const { tr } = state;
|
|
43039
|
-
const props = this.buildProps(tr);
|
|
43040
|
-
return Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43041
|
-
const method = (...args) => {
|
|
43042
|
-
const callback = command(...args)(props);
|
|
43043
|
-
if (!tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
|
|
43044
|
-
return callback;
|
|
43045
|
-
};
|
|
43046
|
-
return [name, method];
|
|
43047
|
-
}));
|
|
43048
|
-
}
|
|
43049
|
-
get chain() {
|
|
43050
|
-
return () => this.createChain();
|
|
43051
|
-
}
|
|
43052
|
-
get can() {
|
|
43053
|
-
return () => this.createCan();
|
|
43054
|
-
}
|
|
43055
|
-
createChain(startTr, shouldDispatch = true) {
|
|
43056
|
-
const { rawCommands, editor, state } = this;
|
|
43057
|
-
const { view } = editor;
|
|
43058
|
-
const callbacks = [];
|
|
43059
|
-
const hasStartTransaction = !!startTr;
|
|
43060
|
-
const tr = startTr || state.tr;
|
|
43061
|
-
const run = () => {
|
|
43062
|
-
if (!hasStartTransaction && shouldDispatch && !tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
|
|
43063
|
-
return callbacks.every((callback) => callback === true);
|
|
43064
|
-
};
|
|
43065
|
-
const chain = {
|
|
43066
|
-
...Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43067
|
-
const chainedCommand = (...args) => {
|
|
43068
|
-
const props = this.buildProps(tr, shouldDispatch);
|
|
43069
|
-
const callback = command(...args)(props);
|
|
43070
|
-
callbacks.push(callback);
|
|
43071
|
-
return chain;
|
|
43072
|
-
};
|
|
43073
|
-
return [name, chainedCommand];
|
|
43074
|
-
})),
|
|
43075
|
-
run
|
|
43076
|
-
};
|
|
43077
|
-
return chain;
|
|
43078
|
-
}
|
|
43079
|
-
/**
|
|
43080
|
-
* Creates a chain that safely returns `false` when run.
|
|
43081
|
-
* @returns A non-dispatching command chain.
|
|
43082
|
-
* @example
|
|
43083
|
-
* const chain = CommandManager.createFakeChain()
|
|
43084
|
-
* chain.focus().run() // false
|
|
43085
|
-
*/
|
|
43086
|
-
static createFakeChain() {
|
|
43087
|
-
const chain = new Proxy({}, { get: (_target, property) => {
|
|
43088
|
-
if (property === "then") return;
|
|
43089
|
-
if (property === "run") return () => false;
|
|
43090
|
-
return () => chain;
|
|
43091
|
-
} });
|
|
43092
|
-
return chain;
|
|
43093
|
-
}
|
|
43094
|
-
createCan(startTr) {
|
|
43095
|
-
const { rawCommands, state } = this;
|
|
43096
|
-
const dispatch = false;
|
|
43097
|
-
const tr = startTr || state.tr;
|
|
43098
|
-
const props = this.buildProps(tr, dispatch);
|
|
43099
|
-
return {
|
|
43100
|
-
...Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43101
|
-
return [name, (...args) => command(...args)({
|
|
43102
|
-
...props,
|
|
43103
|
-
dispatch: void 0
|
|
43104
|
-
})];
|
|
43105
|
-
})),
|
|
43106
|
-
chain: () => this.createChain(tr, dispatch)
|
|
43107
|
-
};
|
|
43108
|
-
}
|
|
43109
|
-
/**
|
|
43110
|
-
* Creates capability checks that safely return `false`.
|
|
43111
|
-
* @returns A non-dispatching capability checker.
|
|
43112
|
-
* @example
|
|
43113
|
-
* const can = CommandManager.createFallbackCan()
|
|
43114
|
-
* can.focus() // false
|
|
43115
|
-
*/
|
|
43116
|
-
static createFallbackCan() {
|
|
43117
|
-
const chain = CommandManager.createFakeChain();
|
|
43118
|
-
return new Proxy({ chain: () => chain }, { get: (target, property) => {
|
|
43119
|
-
if (property === "then") return;
|
|
43120
|
-
if (property === "chain") return target.chain;
|
|
43121
|
-
return () => false;
|
|
43122
|
-
} });
|
|
43123
|
-
}
|
|
43124
|
-
buildProps(tr, shouldDispatch = true) {
|
|
43125
|
-
const { rawCommands, editor, state } = this;
|
|
43126
|
-
const { view } = editor;
|
|
43127
|
-
const props = {
|
|
43128
|
-
tr,
|
|
43129
|
-
editor,
|
|
43130
|
-
view,
|
|
43131
|
-
state: createChainableState({
|
|
43132
|
-
state,
|
|
43133
|
-
transaction: tr
|
|
43134
|
-
}),
|
|
43135
|
-
dispatch: shouldDispatch ? () => void 0 : void 0,
|
|
43136
|
-
chain: () => this.createChain(tr, shouldDispatch),
|
|
43137
|
-
can: () => this.createCan(tr),
|
|
43138
|
-
get commands() {
|
|
43139
|
-
return Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43140
|
-
return [name, (...args) => command(...args)(props)];
|
|
43141
|
-
}));
|
|
43142
|
-
}
|
|
43143
|
-
};
|
|
43144
|
-
return props;
|
|
43145
|
-
}
|
|
43146
|
-
};
|
|
43147
|
-
//#endregion
|
|
43148
|
-
//#region src/commands/blur.ts
|
|
43149
|
-
const blur = () => ({ editor, view }) => {
|
|
43150
|
-
requestAnimationFrame(() => {
|
|
43151
|
-
if (!editor.isDestroyed) {
|
|
43152
|
-
var _window;
|
|
43153
|
-
view.dom.blur();
|
|
43154
|
-
(_window = window) === null || _window === void 0 || (_window = _window.getSelection()) === null || _window === void 0 || _window.removeAllRanges();
|
|
43155
|
-
}
|
|
43156
|
-
});
|
|
43157
|
-
return true;
|
|
43158
|
-
};
|
|
43159
|
-
//#endregion
|
|
43160
|
-
//#region src/commands/clearContent.ts
|
|
43161
|
-
const clearContent = (emitUpdate = true) => ({ commands }) => {
|
|
43162
|
-
return commands.setContent("", { emitUpdate });
|
|
43163
|
-
};
|
|
43164
|
-
//#endregion
|
|
43165
|
-
//#region src/commands/clearNodes.ts
|
|
43166
|
-
const clearNodes = () => ({ state, tr, dispatch }) => {
|
|
43167
|
-
const { selection } = tr;
|
|
43168
|
-
const { ranges } = selection;
|
|
43169
|
-
if (!dispatch) return true;
|
|
43170
|
-
ranges.forEach(({ $from, $to }) => {
|
|
43171
|
-
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
43172
|
-
if (node.type.isText) return;
|
|
43173
|
-
const { doc, mapping } = tr;
|
|
43174
|
-
const $mappedFrom = doc.resolve(mapping.map(pos));
|
|
43175
|
-
const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize));
|
|
43176
|
-
const nodeRange = $mappedFrom.blockRange($mappedTo);
|
|
43177
|
-
if (!nodeRange) return;
|
|
43178
|
-
const targetLiftDepth = liftTarget(nodeRange);
|
|
43179
|
-
if (node.type.isTextblock) {
|
|
43180
|
-
const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index());
|
|
43181
|
-
tr.setNodeMarkup(nodeRange.start, defaultType);
|
|
43182
|
-
}
|
|
43183
|
-
if (targetLiftDepth || targetLiftDepth === 0) tr.lift(nodeRange, targetLiftDepth);
|
|
43184
|
-
});
|
|
43185
|
-
});
|
|
43186
|
-
return true;
|
|
43187
|
-
};
|
|
43188
|
-
//#endregion
|
|
43189
|
-
//#region src/commands/command.ts
|
|
43190
|
-
const command = (fn) => (props) => {
|
|
43191
|
-
return fn(props);
|
|
43192
|
-
};
|
|
43193
|
-
//#endregion
|
|
43194
|
-
//#region src/commands/createParagraphNear.ts
|
|
43195
|
-
const createParagraphNear$1 = () => ({ state, dispatch }) => {
|
|
43196
|
-
return createParagraphNear(state, dispatch);
|
|
43197
|
-
};
|
|
43198
|
-
//#endregion
|
|
43199
|
-
//#region src/commands/cut.ts
|
|
43200
|
-
const cut = (originRange, targetPos) => ({ editor, tr }) => {
|
|
43201
|
-
const { state } = editor;
|
|
43202
|
-
const contentSlice = state.doc.slice(originRange.from, originRange.to);
|
|
43203
|
-
tr.deleteRange(originRange.from, originRange.to);
|
|
43204
|
-
const newPos = tr.mapping.map(targetPos);
|
|
43205
|
-
tr.insert(newPos, contentSlice.content);
|
|
43206
|
-
tr.setSelection(new TextSelection(tr.doc.resolve(Math.max(newPos - 1, 0))));
|
|
43207
|
-
return true;
|
|
43208
|
-
};
|
|
43209
|
-
//#endregion
|
|
43210
|
-
//#region src/commands/deleteCurrentNode.ts
|
|
43211
|
-
const deleteCurrentNode = () => ({ tr, dispatch }) => {
|
|
43212
|
-
const { selection } = tr;
|
|
43213
|
-
const currentNode = selection.$anchor.node();
|
|
43214
|
-
if (currentNode.content.size > 0) return false;
|
|
43215
|
-
const $pos = tr.selection.$anchor;
|
|
43216
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === currentNode.type) {
|
|
43217
|
-
if (dispatch) {
|
|
43218
|
-
const from = $pos.before(depth);
|
|
43219
|
-
const to = $pos.after(depth);
|
|
43220
|
-
tr.delete(from, to).scrollIntoView();
|
|
43221
|
-
}
|
|
43222
|
-
return true;
|
|
43223
|
-
}
|
|
43224
|
-
return false;
|
|
43225
|
-
};
|
|
43226
|
-
//#endregion
|
|
43227
|
-
//#region src/helpers/getNodeType.ts
|
|
43228
|
-
function getNodeType(nameOrType, schema) {
|
|
43229
|
-
if (typeof nameOrType === "string") {
|
|
43230
|
-
if (!schema.nodes[nameOrType]) throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`);
|
|
43231
|
-
return schema.nodes[nameOrType];
|
|
43232
|
-
}
|
|
43233
|
-
return nameOrType;
|
|
43234
|
-
}
|
|
43235
|
-
//#endregion
|
|
43236
|
-
//#region src/commands/deleteNode.ts
|
|
43237
|
-
const deleteNode = (typeOrName) => ({ tr, state, dispatch }) => {
|
|
43238
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
43239
|
-
const $pos = tr.selection.$anchor;
|
|
43240
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === type) {
|
|
43241
|
-
if (dispatch) {
|
|
43242
|
-
const from = $pos.before(depth);
|
|
43243
|
-
const to = $pos.after(depth);
|
|
43244
|
-
tr.delete(from, to).scrollIntoView();
|
|
43245
|
-
}
|
|
43246
|
-
return true;
|
|
43247
|
-
}
|
|
43248
|
-
return false;
|
|
43008
|
+
var GOOD_LEAF_SIZE = 200;
|
|
43009
|
+
|
|
43010
|
+
// :: class<T> A rope sequence is a persistent sequence data structure
|
|
43011
|
+
// that supports appending, prepending, and slicing without doing a
|
|
43012
|
+
// full copy. It is represented as a mostly-balanced tree.
|
|
43013
|
+
var RopeSequence = function RopeSequence () {};
|
|
43014
|
+
|
|
43015
|
+
RopeSequence.prototype.append = function append (other) {
|
|
43016
|
+
if (!other.length) { return this }
|
|
43017
|
+
other = RopeSequence.from(other);
|
|
43018
|
+
|
|
43019
|
+
return (!this.length && other) ||
|
|
43020
|
+
(other.length < GOOD_LEAF_SIZE && this.leafAppend(other)) ||
|
|
43021
|
+
(this.length < GOOD_LEAF_SIZE && other.leafPrepend(this)) ||
|
|
43022
|
+
this.appendInner(other)
|
|
43249
43023
|
};
|
|
43250
|
-
|
|
43251
|
-
|
|
43252
|
-
|
|
43253
|
-
|
|
43254
|
-
|
|
43255
|
-
|
|
43024
|
+
|
|
43025
|
+
// :: (union<[T], RopeSequence<T>>) → RopeSequence<T>
|
|
43026
|
+
// Prepend an array or other rope to this one, returning a new rope.
|
|
43027
|
+
RopeSequence.prototype.prepend = function prepend (other) {
|
|
43028
|
+
if (!other.length) { return this }
|
|
43029
|
+
return RopeSequence.from(other).append(this)
|
|
43256
43030
|
};
|
|
43257
|
-
|
|
43258
|
-
|
|
43259
|
-
|
|
43260
|
-
* Check if a node has text content based on its content specification.
|
|
43261
|
-
* Returns true if the node's content spec matches text* or text+ patterns.
|
|
43262
|
-
*/
|
|
43263
|
-
const hasTextContent = (nodeSpec) => {
|
|
43264
|
-
if (!nodeSpec.content) return false;
|
|
43265
|
-
return /^text(\*|\+)/.test(nodeSpec.content);
|
|
43031
|
+
|
|
43032
|
+
RopeSequence.prototype.appendInner = function appendInner (other) {
|
|
43033
|
+
return new Append(this, other)
|
|
43266
43034
|
};
|
|
43267
|
-
|
|
43268
|
-
|
|
43269
|
-
|
|
43270
|
-
|
|
43271
|
-
|
|
43272
|
-
|
|
43273
|
-
|
|
43274
|
-
|
|
43275
|
-
|
|
43276
|
-
const expandSelectionForSide = ($pos, schema, side) => {
|
|
43277
|
-
if (!$pos.parent.isInline) return $pos.pos;
|
|
43278
|
-
if (side === "left" && $pos.pos > $pos.start() || side === "right" && $pos.pos < $pos.end()) return $pos.pos;
|
|
43279
|
-
const parentContent = schema.nodes[$pos.parent.type.name].spec;
|
|
43280
|
-
if (!hasTextContent(parentContent)) return $pos.pos;
|
|
43281
|
-
return side === "left" ? $pos.start() - 1 : $pos.end() + 1;
|
|
43035
|
+
|
|
43036
|
+
// :: (?number, ?number) → RopeSequence<T>
|
|
43037
|
+
// Create a rope repesenting a sub-sequence of this rope.
|
|
43038
|
+
RopeSequence.prototype.slice = function slice (from, to) {
|
|
43039
|
+
if ( from === void 0 ) from = 0;
|
|
43040
|
+
if ( to === void 0 ) to = this.length;
|
|
43041
|
+
|
|
43042
|
+
if (from >= to) { return RopeSequence.empty }
|
|
43043
|
+
return this.sliceInner(Math.max(0, from), Math.min(this.length, to))
|
|
43282
43044
|
};
|
|
43283
|
-
|
|
43284
|
-
|
|
43285
|
-
|
|
43286
|
-
|
|
43287
|
-
|
|
43288
|
-
|
|
43289
|
-
const expandSelectionForInlineText = ($from, $to, schema) => {
|
|
43290
|
-
return {
|
|
43291
|
-
from: expandSelectionForSide($from, schema, "left"),
|
|
43292
|
-
to: expandSelectionForSide($to, schema, "right")
|
|
43293
|
-
};
|
|
43045
|
+
|
|
43046
|
+
// :: (number) → T
|
|
43047
|
+
// Retrieve the element at the given position from this rope.
|
|
43048
|
+
RopeSequence.prototype.get = function get (i) {
|
|
43049
|
+
if (i < 0 || i >= this.length) { return undefined }
|
|
43050
|
+
return this.getInner(i)
|
|
43294
43051
|
};
|
|
43295
|
-
|
|
43296
|
-
|
|
43297
|
-
|
|
43298
|
-
|
|
43299
|
-
|
|
43300
|
-
|
|
43301
|
-
|
|
43302
|
-
|
|
43303
|
-
|
|
43304
|
-
|
|
43305
|
-
|
|
43306
|
-
|
|
43307
|
-
|
|
43308
|
-
|
|
43309
|
-
tr.scrollIntoView();
|
|
43310
|
-
dispatch(tr);
|
|
43311
|
-
}
|
|
43312
|
-
return true;
|
|
43052
|
+
|
|
43053
|
+
// :: ((element: T, index: number) → ?bool, ?number, ?number)
|
|
43054
|
+
// Call the given function for each element between the given
|
|
43055
|
+
// indices. This tends to be more efficient than looping over the
|
|
43056
|
+
// indices and calling `get`, because it doesn't have to descend the
|
|
43057
|
+
// tree for every element.
|
|
43058
|
+
RopeSequence.prototype.forEach = function forEach (f, from, to) {
|
|
43059
|
+
if ( from === void 0 ) from = 0;
|
|
43060
|
+
if ( to === void 0 ) to = this.length;
|
|
43061
|
+
|
|
43062
|
+
if (from <= to)
|
|
43063
|
+
{ this.forEachInner(f, from, to, 0); }
|
|
43064
|
+
else
|
|
43065
|
+
{ this.forEachInvertedInner(f, from, to, 0); }
|
|
43313
43066
|
};
|
|
43314
|
-
|
|
43315
|
-
|
|
43316
|
-
|
|
43317
|
-
|
|
43067
|
+
|
|
43068
|
+
// :: ((element: T, index: number) → U, ?number, ?number) → [U]
|
|
43069
|
+
// Map the given functions over the elements of the rope, producing
|
|
43070
|
+
// a flat array.
|
|
43071
|
+
RopeSequence.prototype.map = function map (f, from, to) {
|
|
43072
|
+
if ( from === void 0 ) from = 0;
|
|
43073
|
+
if ( to === void 0 ) to = this.length;
|
|
43074
|
+
|
|
43075
|
+
var result = [];
|
|
43076
|
+
this.forEach(function (elt, i) { return result.push(f(elt, i)); }, from, to);
|
|
43077
|
+
return result
|
|
43318
43078
|
};
|
|
43319
|
-
|
|
43320
|
-
|
|
43321
|
-
|
|
43322
|
-
|
|
43079
|
+
|
|
43080
|
+
// :: (?union<[T], RopeSequence<T>>) → RopeSequence<T>
|
|
43081
|
+
// Create a rope representing the given array, or return the rope
|
|
43082
|
+
// itself if a rope was given.
|
|
43083
|
+
RopeSequence.from = function from (values) {
|
|
43084
|
+
if (values instanceof RopeSequence) { return values }
|
|
43085
|
+
return values && values.length ? new Leaf(values) : RopeSequence.empty
|
|
43323
43086
|
};
|
|
43324
|
-
|
|
43325
|
-
|
|
43326
|
-
|
|
43327
|
-
|
|
43328
|
-
|
|
43329
|
-
|
|
43330
|
-
|
|
43331
|
-
|
|
43332
|
-
|
|
43333
|
-
|
|
43334
|
-
|
|
43335
|
-
|
|
43336
|
-
|
|
43337
|
-
|
|
43338
|
-
|
|
43339
|
-
|
|
43340
|
-
|
|
43341
|
-
|
|
43342
|
-
|
|
43343
|
-
|
|
43344
|
-
|
|
43345
|
-
|
|
43346
|
-
|
|
43347
|
-
|
|
43348
|
-
|
|
43349
|
-
|
|
43350
|
-
|
|
43351
|
-
|
|
43352
|
-
|
|
43353
|
-
|
|
43354
|
-
|
|
43355
|
-
|
|
43356
|
-
|
|
43357
|
-
|
|
43358
|
-
|
|
43359
|
-
|
|
43360
|
-
|
|
43361
|
-
|
|
43362
|
-
|
|
43363
|
-
|
|
43364
|
-
|
|
43365
|
-
|
|
43366
|
-
|
|
43367
|
-
|
|
43368
|
-
|
|
43369
|
-
|
|
43370
|
-
|
|
43371
|
-
|
|
43372
|
-
|
|
43373
|
-
|
|
43374
|
-
|
|
43375
|
-
|
|
43376
|
-
|
|
43377
|
-
|
|
43087
|
+
|
|
43088
|
+
var Leaf = /*@__PURE__*/(function (RopeSequence) {
|
|
43089
|
+
function Leaf(values) {
|
|
43090
|
+
RopeSequence.call(this);
|
|
43091
|
+
this.values = values;
|
|
43092
|
+
}
|
|
43093
|
+
|
|
43094
|
+
if ( RopeSequence ) Leaf.__proto__ = RopeSequence;
|
|
43095
|
+
Leaf.prototype = Object.create( RopeSequence && RopeSequence.prototype );
|
|
43096
|
+
Leaf.prototype.constructor = Leaf;
|
|
43097
|
+
|
|
43098
|
+
var prototypeAccessors = { length: { configurable: true },depth: { configurable: true } };
|
|
43099
|
+
|
|
43100
|
+
Leaf.prototype.flatten = function flatten () {
|
|
43101
|
+
return this.values
|
|
43102
|
+
};
|
|
43103
|
+
|
|
43104
|
+
Leaf.prototype.sliceInner = function sliceInner (from, to) {
|
|
43105
|
+
if (from == 0 && to == this.length) { return this }
|
|
43106
|
+
return new Leaf(this.values.slice(from, to))
|
|
43107
|
+
};
|
|
43108
|
+
|
|
43109
|
+
Leaf.prototype.getInner = function getInner (i) {
|
|
43110
|
+
return this.values[i]
|
|
43111
|
+
};
|
|
43112
|
+
|
|
43113
|
+
Leaf.prototype.forEachInner = function forEachInner (f, from, to, start) {
|
|
43114
|
+
for (var i = from; i < to; i++)
|
|
43115
|
+
{ if (f(this.values[i], start + i) === false) { return false } }
|
|
43116
|
+
};
|
|
43117
|
+
|
|
43118
|
+
Leaf.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
|
|
43119
|
+
for (var i = from - 1; i >= to; i--)
|
|
43120
|
+
{ if (f(this.values[i], start + i) === false) { return false } }
|
|
43121
|
+
};
|
|
43122
|
+
|
|
43123
|
+
Leaf.prototype.leafAppend = function leafAppend (other) {
|
|
43124
|
+
if (this.length + other.length <= GOOD_LEAF_SIZE)
|
|
43125
|
+
{ return new Leaf(this.values.concat(other.flatten())) }
|
|
43126
|
+
};
|
|
43127
|
+
|
|
43128
|
+
Leaf.prototype.leafPrepend = function leafPrepend (other) {
|
|
43129
|
+
if (this.length + other.length <= GOOD_LEAF_SIZE)
|
|
43130
|
+
{ return new Leaf(other.flatten().concat(this.values)) }
|
|
43131
|
+
};
|
|
43132
|
+
|
|
43133
|
+
prototypeAccessors.length.get = function () { return this.values.length };
|
|
43134
|
+
|
|
43135
|
+
prototypeAccessors.depth.get = function () { return 0 };
|
|
43136
|
+
|
|
43137
|
+
Object.defineProperties( Leaf.prototype, prototypeAccessors );
|
|
43138
|
+
|
|
43139
|
+
return Leaf;
|
|
43140
|
+
}(RopeSequence));
|
|
43141
|
+
|
|
43142
|
+
// :: RopeSequence
|
|
43143
|
+
// The empty rope sequence.
|
|
43144
|
+
RopeSequence.empty = new Leaf([]);
|
|
43145
|
+
|
|
43146
|
+
var Append = /*@__PURE__*/(function (RopeSequence) {
|
|
43147
|
+
function Append(left, right) {
|
|
43148
|
+
RopeSequence.call(this);
|
|
43149
|
+
this.left = left;
|
|
43150
|
+
this.right = right;
|
|
43151
|
+
this.length = left.length + right.length;
|
|
43152
|
+
this.depth = Math.max(left.depth, right.depth) + 1;
|
|
43153
|
+
}
|
|
43154
|
+
|
|
43155
|
+
if ( RopeSequence ) Append.__proto__ = RopeSequence;
|
|
43156
|
+
Append.prototype = Object.create( RopeSequence && RopeSequence.prototype );
|
|
43157
|
+
Append.prototype.constructor = Append;
|
|
43158
|
+
|
|
43159
|
+
Append.prototype.flatten = function flatten () {
|
|
43160
|
+
return this.left.flatten().concat(this.right.flatten())
|
|
43161
|
+
};
|
|
43162
|
+
|
|
43163
|
+
Append.prototype.getInner = function getInner (i) {
|
|
43164
|
+
return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length)
|
|
43165
|
+
};
|
|
43166
|
+
|
|
43167
|
+
Append.prototype.forEachInner = function forEachInner (f, from, to, start) {
|
|
43168
|
+
var leftLen = this.left.length;
|
|
43169
|
+
if (from < leftLen &&
|
|
43170
|
+
this.left.forEachInner(f, from, Math.min(to, leftLen), start) === false)
|
|
43171
|
+
{ return false }
|
|
43172
|
+
if (to > leftLen &&
|
|
43173
|
+
this.right.forEachInner(f, Math.max(from - leftLen, 0), Math.min(this.length, to) - leftLen, start + leftLen) === false)
|
|
43174
|
+
{ return false }
|
|
43175
|
+
};
|
|
43176
|
+
|
|
43177
|
+
Append.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
|
|
43178
|
+
var leftLen = this.left.length;
|
|
43179
|
+
if (from > leftLen &&
|
|
43180
|
+
this.right.forEachInvertedInner(f, from - leftLen, Math.max(to, leftLen) - leftLen, start + leftLen) === false)
|
|
43181
|
+
{ return false }
|
|
43182
|
+
if (to < leftLen &&
|
|
43183
|
+
this.left.forEachInvertedInner(f, Math.min(from, leftLen), to, start) === false)
|
|
43184
|
+
{ return false }
|
|
43185
|
+
};
|
|
43186
|
+
|
|
43187
|
+
Append.prototype.sliceInner = function sliceInner (from, to) {
|
|
43188
|
+
if (from == 0 && to == this.length) { return this }
|
|
43189
|
+
var leftLen = this.left.length;
|
|
43190
|
+
if (to <= leftLen) { return this.left.slice(from, to) }
|
|
43191
|
+
if (from >= leftLen) { return this.right.slice(from - leftLen, to - leftLen) }
|
|
43192
|
+
return this.left.slice(from, leftLen).append(this.right.slice(0, to - leftLen))
|
|
43193
|
+
};
|
|
43194
|
+
|
|
43195
|
+
Append.prototype.leafAppend = function leafAppend (other) {
|
|
43196
|
+
var inner = this.right.leafAppend(other);
|
|
43197
|
+
if (inner) { return new Append(this.left, inner) }
|
|
43198
|
+
};
|
|
43199
|
+
|
|
43200
|
+
Append.prototype.leafPrepend = function leafPrepend (other) {
|
|
43201
|
+
var inner = this.left.leafPrepend(other);
|
|
43202
|
+
if (inner) { return new Append(inner, this.right) }
|
|
43203
|
+
};
|
|
43204
|
+
|
|
43205
|
+
Append.prototype.appendInner = function appendInner (other) {
|
|
43206
|
+
if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1)
|
|
43207
|
+
{ return new Append(this.left, new Append(this.right, other)) }
|
|
43208
|
+
return new Append(this, other)
|
|
43209
|
+
};
|
|
43210
|
+
|
|
43211
|
+
return Append;
|
|
43212
|
+
}(RopeSequence));
|
|
43213
|
+
|
|
43214
|
+
// ProseMirror's history isn't simply a way to roll back to a previous
|
|
43215
|
+
// state, because ProseMirror supports applying changes without adding
|
|
43216
|
+
// them to the history (for example during collaboration).
|
|
43217
|
+
//
|
|
43218
|
+
// To this end, each 'Branch' (one for the undo history and one for
|
|
43219
|
+
// the redo history) keeps an array of 'Items', which can optionally
|
|
43220
|
+
// hold a step (an actual undoable change), and always hold a position
|
|
43221
|
+
// map (which is needed to move changes below them to apply to the
|
|
43222
|
+
// current document).
|
|
43223
|
+
//
|
|
43224
|
+
// An item that has both a step and a selection bookmark is the start
|
|
43225
|
+
// of an 'event' — a group of changes that will be undone or redone at
|
|
43226
|
+
// once. (It stores only the bookmark, since that way we don't have to
|
|
43227
|
+
// provide a document until the selection is actually applied, which
|
|
43228
|
+
// is useful when compressing.)
|
|
43229
|
+
// Used to schedule history compression
|
|
43230
|
+
const max_empty_items = 500;
|
|
43231
|
+
class Branch {
|
|
43232
|
+
constructor(items, eventCount) {
|
|
43233
|
+
this.items = items;
|
|
43234
|
+
this.eventCount = eventCount;
|
|
43235
|
+
}
|
|
43236
|
+
// Pop the latest event off the branch's history and apply it
|
|
43237
|
+
// to a document transform.
|
|
43238
|
+
popEvent(state, preserveItems) {
|
|
43239
|
+
if (this.eventCount == 0)
|
|
43240
|
+
return null;
|
|
43241
|
+
let end = this.items.length;
|
|
43242
|
+
for (;; end--) {
|
|
43243
|
+
let next = this.items.get(end - 1);
|
|
43244
|
+
if (next.selection) {
|
|
43245
|
+
--end;
|
|
43246
|
+
break;
|
|
43247
|
+
}
|
|
43248
|
+
}
|
|
43249
|
+
let remap, mapFrom;
|
|
43250
|
+
if (preserveItems) {
|
|
43251
|
+
remap = this.remapping(end, this.items.length);
|
|
43252
|
+
mapFrom = remap.maps.length;
|
|
43253
|
+
}
|
|
43254
|
+
let transform = state.tr;
|
|
43255
|
+
let selection, remaining;
|
|
43256
|
+
let addAfter = [], addBefore = [];
|
|
43257
|
+
this.items.forEach((item, i) => {
|
|
43258
|
+
if (!item.step) {
|
|
43259
|
+
if (!remap) {
|
|
43260
|
+
remap = this.remapping(end, i + 1);
|
|
43261
|
+
mapFrom = remap.maps.length;
|
|
43262
|
+
}
|
|
43263
|
+
mapFrom--;
|
|
43264
|
+
addBefore.push(item);
|
|
43265
|
+
return;
|
|
43266
|
+
}
|
|
43267
|
+
if (remap) {
|
|
43268
|
+
addBefore.push(new Item(item.map));
|
|
43269
|
+
let step = item.step.map(remap.slice(mapFrom)), map;
|
|
43270
|
+
if (step && transform.maybeStep(step).doc) {
|
|
43271
|
+
map = transform.mapping.maps[transform.mapping.maps.length - 1];
|
|
43272
|
+
addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length));
|
|
43273
|
+
}
|
|
43274
|
+
mapFrom--;
|
|
43275
|
+
if (map)
|
|
43276
|
+
remap.appendMap(map, mapFrom);
|
|
43277
|
+
}
|
|
43278
|
+
else {
|
|
43279
|
+
transform.maybeStep(item.step);
|
|
43280
|
+
}
|
|
43281
|
+
if (item.selection) {
|
|
43282
|
+
selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;
|
|
43283
|
+
remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1);
|
|
43284
|
+
return false;
|
|
43285
|
+
}
|
|
43286
|
+
}, this.items.length, 0);
|
|
43287
|
+
return { remaining: remaining, transform, selection: selection };
|
|
43288
|
+
}
|
|
43289
|
+
// Create a new branch with the given transform added.
|
|
43290
|
+
addTransform(transform, selection, histOptions, preserveItems) {
|
|
43291
|
+
let newItems = [], eventCount = this.eventCount;
|
|
43292
|
+
let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
|
|
43293
|
+
for (let i = 0; i < transform.steps.length; i++) {
|
|
43294
|
+
let step = transform.steps[i].invert(transform.docs[i]);
|
|
43295
|
+
let item = new Item(transform.mapping.maps[i], step, selection), merged;
|
|
43296
|
+
if (merged = lastItem && lastItem.merge(item)) {
|
|
43297
|
+
item = merged;
|
|
43298
|
+
if (i)
|
|
43299
|
+
newItems.pop();
|
|
43300
|
+
else
|
|
43301
|
+
oldItems = oldItems.slice(0, oldItems.length - 1);
|
|
43302
|
+
}
|
|
43303
|
+
newItems.push(item);
|
|
43304
|
+
if (selection) {
|
|
43305
|
+
eventCount++;
|
|
43306
|
+
selection = undefined;
|
|
43307
|
+
}
|
|
43308
|
+
if (!preserveItems)
|
|
43309
|
+
lastItem = item;
|
|
43310
|
+
}
|
|
43311
|
+
let overflow = eventCount - histOptions.depth;
|
|
43312
|
+
if (overflow > DEPTH_OVERFLOW) {
|
|
43313
|
+
oldItems = cutOffEvents(oldItems, overflow);
|
|
43314
|
+
eventCount -= overflow;
|
|
43315
|
+
}
|
|
43316
|
+
return new Branch(oldItems.append(newItems), eventCount);
|
|
43317
|
+
}
|
|
43318
|
+
remapping(from, to) {
|
|
43319
|
+
let maps = new Mapping;
|
|
43320
|
+
this.items.forEach((item, i) => {
|
|
43321
|
+
let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from
|
|
43322
|
+
? maps.maps.length - item.mirrorOffset : undefined;
|
|
43323
|
+
maps.appendMap(item.map, mirrorPos);
|
|
43324
|
+
}, from, to);
|
|
43325
|
+
return maps;
|
|
43326
|
+
}
|
|
43327
|
+
addMaps(array) {
|
|
43328
|
+
if (this.eventCount == 0)
|
|
43329
|
+
return this;
|
|
43330
|
+
return new Branch(this.items.append(array.map(map => new Item(map))), this.eventCount);
|
|
43331
|
+
}
|
|
43332
|
+
// When the collab module receives remote changes, the history has
|
|
43333
|
+
// to know about those, so that it can adjust the steps that were
|
|
43334
|
+
// rebased on top of the remote changes, and include the position
|
|
43335
|
+
// maps for the remote changes in its array of items.
|
|
43336
|
+
rebased(rebasedTransform, rebasedCount) {
|
|
43337
|
+
if (!this.eventCount)
|
|
43338
|
+
return this;
|
|
43339
|
+
rebasedCount = Math.min(this.items.length, rebasedCount);
|
|
43340
|
+
let rebasedItems = [], start = this.items.length - rebasedCount;
|
|
43341
|
+
let mapping = rebasedTransform.mapping;
|
|
43342
|
+
let newUntil = rebasedTransform.steps.length;
|
|
43343
|
+
let eventCount = this.eventCount;
|
|
43344
|
+
this.items.forEach(item => { if (item.selection)
|
|
43345
|
+
eventCount--; }, start);
|
|
43346
|
+
let iRebased = rebasedCount;
|
|
43347
|
+
this.items.forEach(item => {
|
|
43348
|
+
let pos = mapping.getMirror(--iRebased);
|
|
43349
|
+
if (pos == null)
|
|
43350
|
+
return;
|
|
43351
|
+
newUntil = Math.min(newUntil, pos);
|
|
43352
|
+
let map = mapping.maps[pos];
|
|
43353
|
+
if (item.step) {
|
|
43354
|
+
let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);
|
|
43355
|
+
let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
|
|
43356
|
+
if (selection)
|
|
43357
|
+
eventCount++;
|
|
43358
|
+
rebasedItems.push(new Item(map, step, selection));
|
|
43359
|
+
}
|
|
43360
|
+
else {
|
|
43361
|
+
rebasedItems.push(new Item(map));
|
|
43362
|
+
}
|
|
43363
|
+
}, start);
|
|
43364
|
+
let newMaps = [];
|
|
43365
|
+
for (let i = rebasedCount; i < newUntil; i++)
|
|
43366
|
+
newMaps.push(new Item(mapping.maps[i]));
|
|
43367
|
+
let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
|
|
43368
|
+
let branch = new Branch(items, eventCount);
|
|
43369
|
+
if (branch.emptyItemCount() > max_empty_items)
|
|
43370
|
+
branch = branch.compress(this.items.length - rebasedItems.length);
|
|
43371
|
+
return branch;
|
|
43372
|
+
}
|
|
43373
|
+
emptyItemCount() {
|
|
43374
|
+
let count = 0;
|
|
43375
|
+
this.items.forEach(item => { if (!item.step)
|
|
43376
|
+
count++; });
|
|
43377
|
+
return count;
|
|
43378
|
+
}
|
|
43379
|
+
// Compressing a branch means rewriting it to push the air (map-only
|
|
43380
|
+
// items) out. During collaboration, these naturally accumulate
|
|
43381
|
+
// because each remote change adds one. The `upto` argument is used
|
|
43382
|
+
// to ensure that only the items below a given level are compressed,
|
|
43383
|
+
// because `rebased` relies on a clean, untouched set of items in
|
|
43384
|
+
// order to associate old items with rebased steps.
|
|
43385
|
+
compress(upto = this.items.length) {
|
|
43386
|
+
let remap = this.remapping(0, upto), mapFrom = remap.maps.length;
|
|
43387
|
+
let items = [], events = 0;
|
|
43388
|
+
this.items.forEach((item, i) => {
|
|
43389
|
+
if (i >= upto) {
|
|
43390
|
+
items.push(item);
|
|
43391
|
+
if (item.selection)
|
|
43392
|
+
events++;
|
|
43393
|
+
}
|
|
43394
|
+
else if (item.step) {
|
|
43395
|
+
let step = item.step.map(remap.slice(mapFrom)), map = step && step.getMap();
|
|
43396
|
+
mapFrom--;
|
|
43397
|
+
if (map)
|
|
43398
|
+
remap.appendMap(map, mapFrom);
|
|
43399
|
+
if (step) {
|
|
43400
|
+
let selection = item.selection && item.selection.map(remap.slice(mapFrom));
|
|
43401
|
+
if (selection)
|
|
43402
|
+
events++;
|
|
43403
|
+
let newItem = new Item(map.invert(), step, selection), merged, last = items.length - 1;
|
|
43404
|
+
if (merged = items.length && items[last].merge(newItem))
|
|
43405
|
+
items[last] = merged;
|
|
43406
|
+
else
|
|
43407
|
+
items.push(newItem);
|
|
43408
|
+
}
|
|
43409
|
+
}
|
|
43410
|
+
else if (item.map) {
|
|
43411
|
+
mapFrom--;
|
|
43412
|
+
}
|
|
43413
|
+
}, this.items.length, 0);
|
|
43414
|
+
return new Branch(RopeSequence.from(items.reverse()), events);
|
|
43415
|
+
}
|
|
43416
|
+
}
|
|
43417
|
+
Branch.empty = new Branch(RopeSequence.empty, 0);
|
|
43418
|
+
function cutOffEvents(items, n) {
|
|
43419
|
+
let cutPoint;
|
|
43420
|
+
items.forEach((item, i) => {
|
|
43421
|
+
if (item.selection && (n-- == 0)) {
|
|
43422
|
+
cutPoint = i;
|
|
43423
|
+
return false;
|
|
43424
|
+
}
|
|
43425
|
+
});
|
|
43426
|
+
return items.slice(cutPoint);
|
|
43427
|
+
}
|
|
43428
|
+
class Item {
|
|
43429
|
+
constructor(
|
|
43430
|
+
// The (forward) step map for this item.
|
|
43431
|
+
map,
|
|
43432
|
+
// The inverted step
|
|
43433
|
+
step,
|
|
43434
|
+
// If this is non-null, this item is the start of a group, and
|
|
43435
|
+
// this selection is the starting selection for the group (the one
|
|
43436
|
+
// that was active before the first step was applied)
|
|
43437
|
+
selection,
|
|
43438
|
+
// If this item is the inverse of a previous mapping on the stack,
|
|
43439
|
+
// this points at the inverse's offset
|
|
43440
|
+
mirrorOffset) {
|
|
43441
|
+
this.map = map;
|
|
43442
|
+
this.step = step;
|
|
43443
|
+
this.selection = selection;
|
|
43444
|
+
this.mirrorOffset = mirrorOffset;
|
|
43445
|
+
}
|
|
43446
|
+
merge(other) {
|
|
43447
|
+
if (this.step && other.step && !other.selection) {
|
|
43448
|
+
let step = other.step.merge(this.step);
|
|
43449
|
+
if (step)
|
|
43450
|
+
return new Item(step.getMap().invert(), step, this.selection);
|
|
43451
|
+
}
|
|
43452
|
+
}
|
|
43453
|
+
}
|
|
43454
|
+
// The value of the state field that tracks undo/redo history for that
|
|
43455
|
+
// state. Will be stored in the plugin state when the history plugin
|
|
43456
|
+
// is active.
|
|
43457
|
+
class HistoryState {
|
|
43458
|
+
constructor(done, undone, prevRanges, prevTime, prevComposition) {
|
|
43459
|
+
this.done = done;
|
|
43460
|
+
this.undone = undone;
|
|
43461
|
+
this.prevRanges = prevRanges;
|
|
43462
|
+
this.prevTime = prevTime;
|
|
43463
|
+
this.prevComposition = prevComposition;
|
|
43464
|
+
}
|
|
43465
|
+
}
|
|
43466
|
+
const DEPTH_OVERFLOW = 20;
|
|
43467
|
+
// Record a transformation in undo history.
|
|
43468
|
+
function applyTransaction(history, state, tr, options) {
|
|
43469
|
+
let historyTr = tr.getMeta(historyKey), rebased;
|
|
43470
|
+
if (historyTr)
|
|
43471
|
+
return historyTr.historyState;
|
|
43472
|
+
if (tr.getMeta(closeHistoryKey))
|
|
43473
|
+
history = new HistoryState(history.done, history.undone, null, 0, -1);
|
|
43474
|
+
let appended = tr.getMeta("appendedTransaction");
|
|
43475
|
+
if (tr.steps.length == 0) {
|
|
43476
|
+
return history;
|
|
43477
|
+
}
|
|
43478
|
+
else if (appended && appended.getMeta(historyKey)) {
|
|
43479
|
+
if (appended.getMeta(historyKey).redo)
|
|
43480
|
+
return new HistoryState(history.done.addTransform(tr, undefined, options, mustPreserveItems(state)), history.undone, rangesFor(tr.mapping.maps), history.prevTime, history.prevComposition);
|
|
43481
|
+
else
|
|
43482
|
+
return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);
|
|
43483
|
+
}
|
|
43484
|
+
else if (tr.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) {
|
|
43485
|
+
// Group transforms that occur in quick succession into one event.
|
|
43486
|
+
let composition = tr.getMeta("composition");
|
|
43487
|
+
let newGroup = history.prevTime == 0 ||
|
|
43488
|
+
(!appended && history.prevComposition != composition &&
|
|
43489
|
+
(history.prevTime < (tr.time || 0) - options.newGroupDelay || !isAdjacentTo(tr, history.prevRanges)));
|
|
43490
|
+
let prevRanges = appended ? mapRanges(history.prevRanges, tr.mapping) : rangesFor(tr.mapping.maps);
|
|
43491
|
+
return new HistoryState(history.done.addTransform(tr, newGroup ? state.selection.getBookmark() : undefined, options, mustPreserveItems(state)), Branch.empty, prevRanges, tr.time, composition == null ? history.prevComposition : composition);
|
|
43492
|
+
}
|
|
43493
|
+
else if (rebased = tr.getMeta("rebased")) {
|
|
43494
|
+
// Used by the collab module to tell the history that some of its
|
|
43495
|
+
// content has been rebased.
|
|
43496
|
+
return new HistoryState(history.done.rebased(tr, rebased), history.undone.rebased(tr, rebased), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
|
43497
|
+
}
|
|
43498
|
+
else {
|
|
43499
|
+
return new HistoryState(history.done.addMaps(tr.mapping.maps), history.undone.addMaps(tr.mapping.maps), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
|
43500
|
+
}
|
|
43501
|
+
}
|
|
43502
|
+
function isAdjacentTo(transform, prevRanges) {
|
|
43503
|
+
if (!prevRanges)
|
|
43504
|
+
return false;
|
|
43505
|
+
if (!transform.docChanged)
|
|
43506
|
+
return true;
|
|
43507
|
+
let adjacent = false;
|
|
43508
|
+
transform.mapping.maps[0].forEach((start, end) => {
|
|
43509
|
+
for (let i = 0; i < prevRanges.length; i += 2)
|
|
43510
|
+
if (start <= prevRanges[i + 1] && end >= prevRanges[i])
|
|
43511
|
+
adjacent = true;
|
|
43512
|
+
});
|
|
43513
|
+
return adjacent;
|
|
43514
|
+
}
|
|
43515
|
+
function rangesFor(maps) {
|
|
43516
|
+
let result = [];
|
|
43517
|
+
for (let i = maps.length - 1; i >= 0 && result.length == 0; i--)
|
|
43518
|
+
maps[i].forEach((_from, _to, from, to) => result.push(from, to));
|
|
43519
|
+
return result;
|
|
43520
|
+
}
|
|
43521
|
+
function mapRanges(ranges, mapping) {
|
|
43522
|
+
if (!ranges)
|
|
43523
|
+
return null;
|
|
43524
|
+
let result = [];
|
|
43525
|
+
for (let i = 0; i < ranges.length; i += 2) {
|
|
43526
|
+
let from = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1);
|
|
43527
|
+
if (from <= to)
|
|
43528
|
+
result.push(from, to);
|
|
43529
|
+
}
|
|
43530
|
+
return result;
|
|
43531
|
+
}
|
|
43532
|
+
// Apply the latest event from one branch to the document and shift the event
|
|
43533
|
+
// onto the other branch.
|
|
43534
|
+
function histTransaction(history, state, redo) {
|
|
43535
|
+
let preserveItems = mustPreserveItems(state);
|
|
43536
|
+
let histOptions = historyKey.get(state).spec.config;
|
|
43537
|
+
let pop = (redo ? history.undone : history.done).popEvent(state, preserveItems);
|
|
43538
|
+
if (!pop)
|
|
43539
|
+
return null;
|
|
43540
|
+
let selection = pop.selection.resolve(pop.transform.doc);
|
|
43541
|
+
let added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);
|
|
43542
|
+
let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1);
|
|
43543
|
+
return pop.transform.setSelection(selection).setMeta(historyKey, { redo, historyState: newHist });
|
|
43544
|
+
}
|
|
43545
|
+
let cachedPreserveItems = false, cachedPreserveItemsPlugins = null;
|
|
43546
|
+
// Check whether any plugin in the given state has a
|
|
43547
|
+
// `historyPreserveItems` property in its spec, in which case we must
|
|
43548
|
+
// preserve steps exactly as they came in, so that they can be
|
|
43549
|
+
// rebased.
|
|
43550
|
+
function mustPreserveItems(state) {
|
|
43551
|
+
let plugins = state.plugins;
|
|
43552
|
+
if (cachedPreserveItemsPlugins != plugins) {
|
|
43553
|
+
cachedPreserveItems = false;
|
|
43554
|
+
cachedPreserveItemsPlugins = plugins;
|
|
43555
|
+
for (let i = 0; i < plugins.length; i++)
|
|
43556
|
+
if (plugins[i].spec.historyPreserveItems) {
|
|
43557
|
+
cachedPreserveItems = true;
|
|
43558
|
+
break;
|
|
43559
|
+
}
|
|
43560
|
+
}
|
|
43561
|
+
return cachedPreserveItems;
|
|
43562
|
+
}
|
|
43563
|
+
/**
|
|
43564
|
+
Set a flag on the given transaction that will prevent further steps
|
|
43565
|
+
from being appended to an existing history event (so that they
|
|
43566
|
+
require a separate undo command to undo).
|
|
43567
|
+
*/
|
|
43568
|
+
function closeHistory(tr) {
|
|
43569
|
+
return tr.setMeta(closeHistoryKey, true);
|
|
43570
|
+
}
|
|
43571
|
+
const historyKey = new PluginKey("history");
|
|
43572
|
+
const closeHistoryKey = new PluginKey("closeHistory");
|
|
43573
|
+
/**
|
|
43574
|
+
Returns a plugin that enables the undo history for an editor. The
|
|
43575
|
+
plugin will track undo and redo stacks, which can be used with the
|
|
43576
|
+
[`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.
|
|
43577
|
+
|
|
43578
|
+
You can set an `"addToHistory"` [metadata
|
|
43579
|
+
property](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction
|
|
43580
|
+
to prevent it from being rolled back by undo.
|
|
43581
|
+
*/
|
|
43582
|
+
function history(config = {}) {
|
|
43583
|
+
config = { depth: config.depth || 100,
|
|
43584
|
+
newGroupDelay: config.newGroupDelay || 500 };
|
|
43585
|
+
return new Plugin({
|
|
43586
|
+
key: historyKey,
|
|
43587
|
+
state: {
|
|
43588
|
+
init() {
|
|
43589
|
+
return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);
|
|
43590
|
+
},
|
|
43591
|
+
apply(tr, hist, state) {
|
|
43592
|
+
return applyTransaction(hist, state, tr, config);
|
|
43593
|
+
}
|
|
43594
|
+
},
|
|
43595
|
+
config,
|
|
43596
|
+
props: {
|
|
43597
|
+
handleDOMEvents: {
|
|
43598
|
+
beforeinput(view, e) {
|
|
43599
|
+
let inputType = e.inputType;
|
|
43600
|
+
let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
|
|
43601
|
+
if (!command || !view.editable)
|
|
43602
|
+
return false;
|
|
43603
|
+
e.preventDefault();
|
|
43604
|
+
return command(view.state, view.dispatch);
|
|
43605
|
+
}
|
|
43606
|
+
}
|
|
43607
|
+
}
|
|
43608
|
+
});
|
|
43609
|
+
}
|
|
43610
|
+
function buildCommand(redo, scroll) {
|
|
43611
|
+
return (state, dispatch) => {
|
|
43612
|
+
let hist = historyKey.getState(state);
|
|
43613
|
+
if (!hist || (redo ? hist.undone : hist.done).eventCount == 0)
|
|
43614
|
+
return false;
|
|
43615
|
+
if (dispatch) {
|
|
43616
|
+
let tr = histTransaction(hist, state, redo);
|
|
43617
|
+
if (tr)
|
|
43618
|
+
dispatch(scroll ? tr.scrollIntoView() : tr);
|
|
43619
|
+
}
|
|
43620
|
+
return true;
|
|
43621
|
+
};
|
|
43622
|
+
}
|
|
43623
|
+
/**
|
|
43624
|
+
A command function that undoes the last change, if any.
|
|
43625
|
+
*/
|
|
43626
|
+
const undo = buildCommand(false, true);
|
|
43627
|
+
/**
|
|
43628
|
+
A command function that redoes the last undone change, if any.
|
|
43629
|
+
*/
|
|
43630
|
+
const redo = buildCommand(true, true);
|
|
43631
|
+
/**
|
|
43632
|
+
Returns true if the given transaction was generated by the history
|
|
43633
|
+
plugin.
|
|
43634
|
+
*/
|
|
43635
|
+
function isHistoryTransaction(tr) {
|
|
43636
|
+
return tr.getMeta(historyKey) != null;
|
|
43637
|
+
}
|
|
43638
|
+
|
|
43639
|
+
//#region src/helpers/createChainableState.ts
|
|
43640
|
+
/**
|
|
43641
|
+
* Takes a Transaction & Editor State and turns it into a chainable state object
|
|
43642
|
+
* @param config The transaction and state to create the chainable state from
|
|
43643
|
+
* @returns A chainable Editor state object
|
|
43644
|
+
*/
|
|
43645
|
+
function createChainableState(config) {
|
|
43646
|
+
const { state, transaction } = config;
|
|
43647
|
+
let { selection } = transaction;
|
|
43648
|
+
let { doc } = transaction;
|
|
43649
|
+
let { storedMarks } = transaction;
|
|
43650
|
+
return {
|
|
43651
|
+
...state,
|
|
43652
|
+
apply: state.apply.bind(state),
|
|
43653
|
+
applyTransaction: state.applyTransaction.bind(state),
|
|
43654
|
+
plugins: state.plugins,
|
|
43655
|
+
schema: state.schema,
|
|
43656
|
+
reconfigure: state.reconfigure.bind(state),
|
|
43657
|
+
toJSON: state.toJSON.bind(state),
|
|
43658
|
+
get storedMarks() {
|
|
43659
|
+
return storedMarks;
|
|
43660
|
+
},
|
|
43661
|
+
get selection() {
|
|
43662
|
+
return selection;
|
|
43663
|
+
},
|
|
43664
|
+
get doc() {
|
|
43665
|
+
return doc;
|
|
43666
|
+
},
|
|
43667
|
+
get tr() {
|
|
43668
|
+
selection = transaction.selection;
|
|
43669
|
+
doc = transaction.doc;
|
|
43670
|
+
storedMarks = transaction.storedMarks;
|
|
43671
|
+
return transaction;
|
|
43672
|
+
}
|
|
43673
|
+
};
|
|
43674
|
+
}
|
|
43675
|
+
//#endregion
|
|
43676
|
+
//#region src/CommandManager.ts
|
|
43677
|
+
var CommandManager = class CommandManager {
|
|
43678
|
+
constructor(props) {
|
|
43679
|
+
this.editor = props.editor;
|
|
43680
|
+
this.rawCommands = this.editor.extensionManager.commands;
|
|
43681
|
+
this.customState = props.state;
|
|
43682
|
+
}
|
|
43683
|
+
get hasCustomState() {
|
|
43684
|
+
return !!this.customState;
|
|
43685
|
+
}
|
|
43686
|
+
get state() {
|
|
43687
|
+
return this.customState || this.editor.state;
|
|
43688
|
+
}
|
|
43689
|
+
get commands() {
|
|
43690
|
+
const { rawCommands, editor, state } = this;
|
|
43691
|
+
const { view } = editor;
|
|
43692
|
+
const { tr } = state;
|
|
43693
|
+
const props = this.buildProps(tr);
|
|
43694
|
+
return Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43695
|
+
const method = (...args) => {
|
|
43696
|
+
const callback = command(...args)(props);
|
|
43697
|
+
if (!tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
|
|
43698
|
+
return callback;
|
|
43699
|
+
};
|
|
43700
|
+
return [name, method];
|
|
43701
|
+
}));
|
|
43702
|
+
}
|
|
43703
|
+
get chain() {
|
|
43704
|
+
return () => this.createChain();
|
|
43705
|
+
}
|
|
43706
|
+
get can() {
|
|
43707
|
+
return () => this.createCan();
|
|
43708
|
+
}
|
|
43709
|
+
createChain(startTr, shouldDispatch = true) {
|
|
43710
|
+
const { rawCommands, editor, state } = this;
|
|
43711
|
+
const { view } = editor;
|
|
43712
|
+
const callbacks = [];
|
|
43713
|
+
const hasStartTransaction = !!startTr;
|
|
43714
|
+
const tr = startTr || state.tr;
|
|
43715
|
+
const run = () => {
|
|
43716
|
+
if (!hasStartTransaction && shouldDispatch && !tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
|
|
43717
|
+
return callbacks.every((callback) => callback === true);
|
|
43718
|
+
};
|
|
43719
|
+
const chain = {
|
|
43720
|
+
...Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43721
|
+
const chainedCommand = (...args) => {
|
|
43722
|
+
const props = this.buildProps(tr, shouldDispatch);
|
|
43723
|
+
const callback = command(...args)(props);
|
|
43724
|
+
callbacks.push(callback);
|
|
43725
|
+
return chain;
|
|
43726
|
+
};
|
|
43727
|
+
return [name, chainedCommand];
|
|
43728
|
+
})),
|
|
43729
|
+
run
|
|
43730
|
+
};
|
|
43731
|
+
return chain;
|
|
43732
|
+
}
|
|
43733
|
+
/**
|
|
43734
|
+
* Creates a chain that safely returns `false` when run.
|
|
43735
|
+
* @returns A non-dispatching command chain.
|
|
43736
|
+
* @example
|
|
43737
|
+
* const chain = CommandManager.createFakeChain()
|
|
43738
|
+
* chain.focus().run() // false
|
|
43739
|
+
*/
|
|
43740
|
+
static createFakeChain() {
|
|
43741
|
+
const chain = new Proxy({}, { get: (_target, property) => {
|
|
43742
|
+
if (property === "then") return;
|
|
43743
|
+
if (property === "run") return () => false;
|
|
43744
|
+
return () => chain;
|
|
43745
|
+
} });
|
|
43746
|
+
return chain;
|
|
43747
|
+
}
|
|
43748
|
+
createCan(startTr) {
|
|
43749
|
+
const { rawCommands, state } = this;
|
|
43750
|
+
const dispatch = false;
|
|
43751
|
+
const tr = startTr || state.tr;
|
|
43752
|
+
const props = this.buildProps(tr, dispatch);
|
|
43753
|
+
return {
|
|
43754
|
+
...Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43755
|
+
return [name, (...args) => command(...args)({
|
|
43756
|
+
...props,
|
|
43757
|
+
dispatch: void 0
|
|
43758
|
+
})];
|
|
43759
|
+
})),
|
|
43760
|
+
chain: () => this.createChain(tr, dispatch)
|
|
43761
|
+
};
|
|
43762
|
+
}
|
|
43763
|
+
/**
|
|
43764
|
+
* Creates capability checks that safely return `false`.
|
|
43765
|
+
* @returns A non-dispatching capability checker.
|
|
43766
|
+
* @example
|
|
43767
|
+
* const can = CommandManager.createFallbackCan()
|
|
43768
|
+
* can.focus() // false
|
|
43769
|
+
*/
|
|
43770
|
+
static createFallbackCan() {
|
|
43771
|
+
const chain = CommandManager.createFakeChain();
|
|
43772
|
+
return new Proxy({ chain: () => chain }, { get: (target, property) => {
|
|
43773
|
+
if (property === "then") return;
|
|
43774
|
+
if (property === "chain") return target.chain;
|
|
43775
|
+
return () => false;
|
|
43776
|
+
} });
|
|
43777
|
+
}
|
|
43778
|
+
buildProps(tr, shouldDispatch = true) {
|
|
43779
|
+
const { rawCommands, editor, state } = this;
|
|
43780
|
+
const { view } = editor;
|
|
43781
|
+
const props = {
|
|
43782
|
+
tr,
|
|
43783
|
+
editor,
|
|
43784
|
+
view,
|
|
43785
|
+
state: createChainableState({
|
|
43786
|
+
state,
|
|
43787
|
+
transaction: tr
|
|
43788
|
+
}),
|
|
43789
|
+
dispatch: shouldDispatch ? () => void 0 : void 0,
|
|
43790
|
+
chain: () => this.createChain(tr, shouldDispatch),
|
|
43791
|
+
can: () => this.createCan(tr),
|
|
43792
|
+
get commands() {
|
|
43793
|
+
return Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43794
|
+
return [name, (...args) => command(...args)(props)];
|
|
43795
|
+
}));
|
|
43796
|
+
}
|
|
43797
|
+
};
|
|
43798
|
+
return props;
|
|
43799
|
+
}
|
|
43800
|
+
};
|
|
43801
|
+
//#endregion
|
|
43802
|
+
//#region src/commands/blur.ts
|
|
43803
|
+
const blur = () => ({ editor, view }) => {
|
|
43804
|
+
requestAnimationFrame(() => {
|
|
43805
|
+
if (!editor.isDestroyed) {
|
|
43806
|
+
var _window;
|
|
43807
|
+
view.dom.blur();
|
|
43808
|
+
(_window = window) === null || _window === void 0 || (_window = _window.getSelection()) === null || _window === void 0 || _window.removeAllRanges();
|
|
43809
|
+
}
|
|
43810
|
+
});
|
|
43811
|
+
return true;
|
|
43812
|
+
};
|
|
43813
|
+
//#endregion
|
|
43814
|
+
//#region src/commands/clearContent.ts
|
|
43815
|
+
const clearContent = (emitUpdate = true) => ({ commands }) => {
|
|
43816
|
+
return commands.setContent("", { emitUpdate });
|
|
43817
|
+
};
|
|
43818
|
+
//#endregion
|
|
43819
|
+
//#region src/commands/clearNodes.ts
|
|
43820
|
+
const clearNodes = () => ({ state, tr, dispatch }) => {
|
|
43821
|
+
const { selection } = tr;
|
|
43822
|
+
const { ranges } = selection;
|
|
43823
|
+
if (!dispatch) return true;
|
|
43824
|
+
ranges.forEach(({ $from, $to }) => {
|
|
43825
|
+
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
43826
|
+
if (node.type.isText) return;
|
|
43827
|
+
const { doc, mapping } = tr;
|
|
43828
|
+
const $mappedFrom = doc.resolve(mapping.map(pos));
|
|
43829
|
+
const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize));
|
|
43830
|
+
const nodeRange = $mappedFrom.blockRange($mappedTo);
|
|
43831
|
+
if (!nodeRange) return;
|
|
43832
|
+
const targetLiftDepth = liftTarget(nodeRange);
|
|
43833
|
+
if (node.type.isTextblock) {
|
|
43834
|
+
const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index());
|
|
43835
|
+
tr.setNodeMarkup(nodeRange.start, defaultType);
|
|
43836
|
+
}
|
|
43837
|
+
if (targetLiftDepth || targetLiftDepth === 0) tr.lift(nodeRange, targetLiftDepth);
|
|
43838
|
+
});
|
|
43839
|
+
});
|
|
43840
|
+
return true;
|
|
43841
|
+
};
|
|
43842
|
+
//#endregion
|
|
43843
|
+
//#region src/commands/command.ts
|
|
43844
|
+
const command = (fn) => (props) => {
|
|
43845
|
+
return fn(props);
|
|
43846
|
+
};
|
|
43847
|
+
//#endregion
|
|
43848
|
+
//#region src/commands/createParagraphNear.ts
|
|
43849
|
+
const createParagraphNear$1 = () => ({ state, dispatch }) => {
|
|
43850
|
+
return createParagraphNear(state, dispatch);
|
|
43851
|
+
};
|
|
43852
|
+
//#endregion
|
|
43853
|
+
//#region src/commands/cut.ts
|
|
43854
|
+
const cut = (originRange, targetPos) => ({ editor, tr }) => {
|
|
43855
|
+
const { state } = editor;
|
|
43856
|
+
const contentSlice = state.doc.slice(originRange.from, originRange.to);
|
|
43857
|
+
tr.deleteRange(originRange.from, originRange.to);
|
|
43858
|
+
const newPos = tr.mapping.map(targetPos);
|
|
43859
|
+
tr.insert(newPos, contentSlice.content);
|
|
43860
|
+
tr.setSelection(new TextSelection(tr.doc.resolve(Math.max(newPos - 1, 0))));
|
|
43861
|
+
return true;
|
|
43862
|
+
};
|
|
43863
|
+
//#endregion
|
|
43864
|
+
//#region src/commands/deleteCurrentNode.ts
|
|
43865
|
+
const deleteCurrentNode = () => ({ tr, dispatch }) => {
|
|
43866
|
+
const { selection } = tr;
|
|
43867
|
+
const currentNode = selection.$anchor.node();
|
|
43868
|
+
if (currentNode.content.size > 0) return false;
|
|
43869
|
+
const $pos = tr.selection.$anchor;
|
|
43870
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === currentNode.type) {
|
|
43871
|
+
if (dispatch) {
|
|
43872
|
+
const from = $pos.before(depth);
|
|
43873
|
+
const to = $pos.after(depth);
|
|
43874
|
+
tr.delete(from, to).scrollIntoView();
|
|
43875
|
+
}
|
|
43876
|
+
return true;
|
|
43877
|
+
}
|
|
43878
|
+
return false;
|
|
43879
|
+
};
|
|
43880
|
+
//#endregion
|
|
43881
|
+
//#region src/helpers/getNodeType.ts
|
|
43882
|
+
function getNodeType(nameOrType, schema) {
|
|
43883
|
+
if (typeof nameOrType === "string") {
|
|
43884
|
+
if (!schema.nodes[nameOrType]) throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`);
|
|
43885
|
+
return schema.nodes[nameOrType];
|
|
43886
|
+
}
|
|
43887
|
+
return nameOrType;
|
|
43888
|
+
}
|
|
43889
|
+
//#endregion
|
|
43890
|
+
//#region src/commands/deleteNode.ts
|
|
43891
|
+
const deleteNode = (typeOrName) => ({ tr, state, dispatch }) => {
|
|
43892
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
43893
|
+
const $pos = tr.selection.$anchor;
|
|
43894
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === type) {
|
|
43895
|
+
if (dispatch) {
|
|
43896
|
+
const from = $pos.before(depth);
|
|
43897
|
+
const to = $pos.after(depth);
|
|
43898
|
+
tr.delete(from, to).scrollIntoView();
|
|
43899
|
+
}
|
|
43900
|
+
return true;
|
|
43901
|
+
}
|
|
43902
|
+
return false;
|
|
43903
|
+
};
|
|
43904
|
+
//#endregion
|
|
43905
|
+
//#region src/commands/deleteRange.ts
|
|
43906
|
+
const deleteRange = (range) => ({ tr, dispatch }) => {
|
|
43907
|
+
const { from, to } = range;
|
|
43908
|
+
if (dispatch) tr.delete(from, to);
|
|
43909
|
+
return true;
|
|
43910
|
+
};
|
|
43911
|
+
//#endregion
|
|
43912
|
+
//#region src/commands/deleteSelection.ts
|
|
43913
|
+
/**
|
|
43914
|
+
* Check if a node has text content based on its content specification.
|
|
43915
|
+
* Returns true if the node's content spec matches text* or text+ patterns.
|
|
43916
|
+
*/
|
|
43917
|
+
const hasTextContent = (nodeSpec) => {
|
|
43918
|
+
if (!nodeSpec.content) return false;
|
|
43919
|
+
return /^text(\*|\+)/.test(nodeSpec.content);
|
|
43920
|
+
};
|
|
43921
|
+
/**
|
|
43922
|
+
* Expand selection position for a specific side (left or right) to handle inline text nodes.
|
|
43923
|
+
* This function checks if the position is within an inline node with text content and
|
|
43924
|
+
* expands it to include the entire node boundaries for proper deletion.
|
|
43925
|
+
* @param $pos - The resolved position to expand
|
|
43926
|
+
* @param schema - The ProseMirror schema
|
|
43927
|
+
* @param side - Which side to expand ('left' or 'right')
|
|
43928
|
+
* @returns The expanded position for deletion
|
|
43929
|
+
*/
|
|
43930
|
+
const expandSelectionForSide = ($pos, schema, side) => {
|
|
43931
|
+
if (!$pos.parent.isInline) return $pos.pos;
|
|
43932
|
+
if (side === "left" && $pos.pos > $pos.start() || side === "right" && $pos.pos < $pos.end()) return $pos.pos;
|
|
43933
|
+
const parentContent = schema.nodes[$pos.parent.type.name].spec;
|
|
43934
|
+
if (!hasTextContent(parentContent)) return $pos.pos;
|
|
43935
|
+
return side === "left" ? $pos.start() - 1 : $pos.end() + 1;
|
|
43936
|
+
};
|
|
43937
|
+
/**
|
|
43938
|
+
* Expand selection range to properly handle deletion of inline text nodes.
|
|
43939
|
+
* Inline text nodes don't collapse correctly when text inside is deleted,
|
|
43940
|
+
* so we need to expand the selection to include the entire node.
|
|
43941
|
+
* See: https://code.haverbeke.berlin/prosemirror/prosemirror/issues/1365
|
|
43942
|
+
*/
|
|
43943
|
+
const expandSelectionForInlineText = ($from, $to, schema) => {
|
|
43944
|
+
return {
|
|
43945
|
+
from: expandSelectionForSide($from, schema, "left"),
|
|
43946
|
+
to: expandSelectionForSide($to, schema, "right")
|
|
43947
|
+
};
|
|
43948
|
+
};
|
|
43949
|
+
const deleteSelection = () => ({ state, dispatch }) => {
|
|
43950
|
+
if (state.selection.empty) return false;
|
|
43951
|
+
if (dispatch) {
|
|
43952
|
+
const tr = state.tr;
|
|
43953
|
+
const { ranges } = state.selection;
|
|
43954
|
+
const mapFrom = tr.steps.length;
|
|
43955
|
+
ranges.forEach((range) => {
|
|
43956
|
+
const mapping = tr.mapping.slice(mapFrom);
|
|
43957
|
+
const $from = tr.doc.resolve(mapping.map(range.$from.pos));
|
|
43958
|
+
const $to = tr.doc.resolve(mapping.map(range.$to.pos));
|
|
43959
|
+
const { from, to } = expandSelectionForInlineText($from, $to, state.schema);
|
|
43960
|
+
tr.deleteRange(from, to);
|
|
43961
|
+
});
|
|
43962
|
+
if (!tr.selection.empty) tr.setSelection(TextSelection.near(tr.doc.resolve(tr.selection.from)));
|
|
43963
|
+
tr.scrollIntoView();
|
|
43964
|
+
dispatch(tr);
|
|
43965
|
+
}
|
|
43966
|
+
return true;
|
|
43967
|
+
};
|
|
43968
|
+
//#endregion
|
|
43969
|
+
//#region src/commands/enter.ts
|
|
43970
|
+
const enter = () => ({ commands }) => {
|
|
43971
|
+
return commands.keyboardShortcut("Enter");
|
|
43972
|
+
};
|
|
43973
|
+
//#endregion
|
|
43974
|
+
//#region src/commands/exitCode.ts
|
|
43975
|
+
const exitCode$1 = () => ({ state, dispatch }) => {
|
|
43976
|
+
return exitCode(state, dispatch);
|
|
43977
|
+
};
|
|
43978
|
+
//#endregion
|
|
43979
|
+
//#region src/utilities/isRegExp.ts
|
|
43980
|
+
function isRegExp$1(value) {
|
|
43981
|
+
return Object.prototype.toString.call(value) === "[object RegExp]";
|
|
43982
|
+
}
|
|
43983
|
+
//#endregion
|
|
43984
|
+
//#region src/utilities/objectIncludes.ts
|
|
43985
|
+
/**
|
|
43986
|
+
* Check if object1 includes object2
|
|
43987
|
+
* @param object1 Object
|
|
43988
|
+
* @param object2 Object
|
|
43989
|
+
*/
|
|
43990
|
+
function objectIncludes(object1, object2, options = { strict: true }) {
|
|
43991
|
+
const keys = Object.keys(object2);
|
|
43992
|
+
if (!keys.length) return true;
|
|
43993
|
+
return keys.every((key) => {
|
|
43994
|
+
if (options.strict) return object2[key] === object1[key];
|
|
43995
|
+
if (isRegExp$1(object2[key])) return object2[key].test(object1[key]);
|
|
43996
|
+
return object2[key] === object1[key];
|
|
43997
|
+
});
|
|
43998
|
+
}
|
|
43999
|
+
//#endregion
|
|
44000
|
+
//#region src/helpers/getMarkRange.ts
|
|
44001
|
+
function findMarkInSet(marks, type, attributes = {}) {
|
|
44002
|
+
return marks.find((item) => {
|
|
44003
|
+
return item.type === type && objectIncludes(Object.fromEntries(Object.keys(attributes).map((k) => [k, item.attrs[k]])), attributes);
|
|
44004
|
+
});
|
|
44005
|
+
}
|
|
44006
|
+
function isMarkInSet(marks, type, attributes = {}) {
|
|
44007
|
+
return !!findMarkInSet(marks, type, attributes);
|
|
44008
|
+
}
|
|
44009
|
+
/**
|
|
44010
|
+
* Get the range of a mark at a resolved position.
|
|
44011
|
+
*/
|
|
44012
|
+
function getMarkRange($pos, type, attributes) {
|
|
44013
|
+
if (!$pos || !type) return;
|
|
44014
|
+
let start = $pos.parent.childAfter($pos.parentOffset);
|
|
44015
|
+
if (!start.node || !start.node.marks.some((mark) => mark.type === type)) start = $pos.parent.childBefore($pos.parentOffset);
|
|
44016
|
+
if (!start.node || !start.node.marks.some((mark) => mark.type === type)) return;
|
|
44017
|
+
if (!attributes) {
|
|
44018
|
+
const firstMark = start.node.marks.find((mark) => mark.type === type);
|
|
44019
|
+
if (firstMark) attributes = firstMark.attrs;
|
|
44020
|
+
}
|
|
44021
|
+
if (!findMarkInSet([...start.node.marks], type, attributes)) return;
|
|
44022
|
+
let startIndex = start.index;
|
|
44023
|
+
let startPos = $pos.start() + start.offset;
|
|
44024
|
+
let endIndex = startIndex + 1;
|
|
44025
|
+
let endPos = startPos + start.node.nodeSize;
|
|
44026
|
+
while (startIndex > 0 && isMarkInSet([...$pos.parent.child(startIndex - 1).marks], type, attributes)) {
|
|
44027
|
+
startIndex -= 1;
|
|
44028
|
+
startPos -= $pos.parent.child(startIndex).nodeSize;
|
|
44029
|
+
}
|
|
44030
|
+
while (endIndex < $pos.parent.childCount && isMarkInSet([...$pos.parent.child(endIndex).marks], type, attributes)) {
|
|
44031
|
+
endPos += $pos.parent.child(endIndex).nodeSize;
|
|
43378
44032
|
endIndex += 1;
|
|
43379
44033
|
}
|
|
43380
44034
|
return {
|
|
@@ -43784,11 +44438,21 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
43784
44438
|
return joinForward(state, dispatch);
|
|
43785
44439
|
};
|
|
43786
44440
|
//#endregion
|
|
44441
|
+
//#region src/commands/canJoinItemsAt.ts
|
|
44442
|
+
const canJoinItemsAt = (doc, pos) => {
|
|
44443
|
+
const $pos = doc.resolve(pos);
|
|
44444
|
+
const before = $pos.nodeBefore;
|
|
44445
|
+
const after = $pos.nodeAfter;
|
|
44446
|
+
if (!before || !after) return false;
|
|
44447
|
+
return !before.type.spec.isolating && !after.type.spec.isolating;
|
|
44448
|
+
};
|
|
44449
|
+
//#endregion
|
|
43787
44450
|
//#region src/commands/joinItemBackward.ts
|
|
43788
44451
|
const joinItemBackward = () => ({ state, dispatch, tr }) => {
|
|
43789
44452
|
try {
|
|
43790
44453
|
const point = joinPoint(state.doc, state.selection.$from.pos, -1);
|
|
43791
44454
|
if (point === null || point === void 0) return false;
|
|
44455
|
+
if (!canJoinItemsAt(state.doc, point)) return false;
|
|
43792
44456
|
tr.join(point, 2);
|
|
43793
44457
|
if (dispatch) dispatch(tr);
|
|
43794
44458
|
return true;
|
|
@@ -43802,6 +44466,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
43802
44466
|
try {
|
|
43803
44467
|
const point = joinPoint(state.doc, state.selection.$from.pos, 1);
|
|
43804
44468
|
if (point === null || point === void 0) return false;
|
|
44469
|
+
if (!canJoinItemsAt(state.doc, point)) return false;
|
|
43805
44470
|
tr.join(point, 2);
|
|
43806
44471
|
if (dispatch) dispatch(tr);
|
|
43807
44472
|
return true;
|
|
@@ -45208,8 +45873,14 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45208
45873
|
type: deflt,
|
|
45209
45874
|
attrs: newAttributes
|
|
45210
45875
|
}] : void 0;
|
|
45211
|
-
|
|
45212
|
-
|
|
45876
|
+
const deletedTr = selection instanceof TextSelection && !selection.empty ? EditorState.create({
|
|
45877
|
+
doc: tr.doc,
|
|
45878
|
+
selection
|
|
45879
|
+
}).tr.deleteSelection() : null;
|
|
45880
|
+
const splitDoc = deletedTr ? deletedTr.doc : tr.doc;
|
|
45881
|
+
const splitPos = deletedTr ? deletedTr.mapping.map($from.pos) : $from.pos;
|
|
45882
|
+
let can = canSplit(splitDoc, splitPos, 1, types);
|
|
45883
|
+
if (!types && !can && canSplit(splitDoc, splitPos, 1, deflt ? [{ type: deflt }] : void 0)) {
|
|
45213
45884
|
can = true;
|
|
45214
45885
|
types = deflt ? [{
|
|
45215
45886
|
type: deflt,
|
|
@@ -45218,12 +45889,13 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45218
45889
|
}
|
|
45219
45890
|
if (dispatch) {
|
|
45220
45891
|
if (can) {
|
|
45892
|
+
const mapFrom = tr.steps.length;
|
|
45221
45893
|
if (selection instanceof TextSelection) tr.deleteSelection();
|
|
45222
|
-
tr.split(tr.mapping.map($from.pos), 1, types);
|
|
45894
|
+
tr.split(tr.mapping.slice(mapFrom).map($from.pos), 1, types);
|
|
45223
45895
|
if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) {
|
|
45224
|
-
const first = tr.mapping.map($from.before());
|
|
45896
|
+
const first = tr.mapping.slice(mapFrom).map($from.before());
|
|
45225
45897
|
const $first = tr.doc.resolve(first);
|
|
45226
|
-
if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) tr.setNodeMarkup(tr.mapping.map($from.before()), deflt);
|
|
45898
|
+
if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) tr.setNodeMarkup(tr.mapping.slice(mapFrom).map($from.before()), deflt);
|
|
45227
45899
|
}
|
|
45228
45900
|
}
|
|
45229
45901
|
if (keepMarks) ensureMarks(state, editor.extensionManager.splittableMarks);
|
|
@@ -45276,16 +45948,19 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45276
45948
|
...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
|
|
45277
45949
|
...overrideAttrs
|
|
45278
45950
|
};
|
|
45951
|
+
const splitsAtStartOfItem = $from.parentOffset === 0 && $from.index(-1) === 0;
|
|
45952
|
+
const itemStart = $from.before(-1);
|
|
45279
45953
|
tr.delete($from.pos, $to.pos);
|
|
45954
|
+
const trailingTypeAttributes = splitsAtStartOfItem ? grandParent.attrs : newTypeAttributes;
|
|
45280
45955
|
const types = nextType ? [{
|
|
45281
45956
|
type,
|
|
45282
|
-
attrs:
|
|
45957
|
+
attrs: trailingTypeAttributes
|
|
45283
45958
|
}, {
|
|
45284
45959
|
type: nextType,
|
|
45285
45960
|
attrs: newNextTypeAttributes
|
|
45286
45961
|
}] : [{
|
|
45287
45962
|
type,
|
|
45288
|
-
attrs:
|
|
45963
|
+
attrs: trailingTypeAttributes
|
|
45289
45964
|
}];
|
|
45290
45965
|
if (!canSplit(tr.doc, $from.pos, 2)) return false;
|
|
45291
45966
|
if (dispatch) {
|
|
@@ -45293,6 +45968,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45293
45968
|
const { splittableMarks } = editor.extensionManager;
|
|
45294
45969
|
const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
|
|
45295
45970
|
tr.split($from.pos, 2, types).scrollIntoView();
|
|
45971
|
+
if (splitsAtStartOfItem) tr.setNodeMarkup(itemStart, void 0, newTypeAttributes);
|
|
45296
45972
|
if (!marks || !dispatch) return true;
|
|
45297
45973
|
const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
|
|
45298
45974
|
tr.ensureMarks(filteredMarks);
|
|
@@ -46825,55 +47501,106 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
46825
47501
|
}
|
|
46826
47502
|
return result;
|
|
46827
47503
|
};
|
|
47504
|
+
/**
|
|
47505
|
+
* Prepares the typed text so the rule handler can inspect the resulting document.
|
|
47506
|
+
*/
|
|
47507
|
+
function createRuleTransaction(config) {
|
|
47508
|
+
const { editor, from, to, text, insertText } = config;
|
|
47509
|
+
if (!insertText) return {
|
|
47510
|
+
inputTransaction: null,
|
|
47511
|
+
tr: editor.view.state.tr
|
|
47512
|
+
};
|
|
47513
|
+
const inputTransaction = editor.view.state.tr.insertText(text, from, to);
|
|
47514
|
+
return {
|
|
47515
|
+
inputTransaction,
|
|
47516
|
+
tr: EditorState.create({
|
|
47517
|
+
doc: inputTransaction.doc,
|
|
47518
|
+
selection: inputTransaction.selection,
|
|
47519
|
+
storedMarks: inputTransaction.storedMarks
|
|
47520
|
+
}).tr
|
|
47521
|
+
};
|
|
47522
|
+
}
|
|
47523
|
+
/**
|
|
47524
|
+
* Runs a matching rule and dispatches the typed text before its conversion.
|
|
47525
|
+
*/
|
|
47526
|
+
function applyRule(config) {
|
|
47527
|
+
const { editor, from, to, text, rule, match, plugin, insertText } = config;
|
|
47528
|
+
const { view } = editor;
|
|
47529
|
+
const { inputTransaction, tr } = createRuleTransaction({
|
|
47530
|
+
editor,
|
|
47531
|
+
from,
|
|
47532
|
+
to,
|
|
47533
|
+
text,
|
|
47534
|
+
insertText
|
|
47535
|
+
});
|
|
47536
|
+
const inputEnd = inputTransaction ? from + text.length : to;
|
|
47537
|
+
const state = createChainableState({
|
|
47538
|
+
state: view.state,
|
|
47539
|
+
transaction: tr
|
|
47540
|
+
});
|
|
47541
|
+
const range = {
|
|
47542
|
+
from: from - (match[0].length - text.length),
|
|
47543
|
+
to: inputEnd
|
|
47544
|
+
};
|
|
47545
|
+
const { commands, chain, can } = new CommandManager({
|
|
47546
|
+
editor,
|
|
47547
|
+
state
|
|
47548
|
+
});
|
|
47549
|
+
if (rule.handler({
|
|
47550
|
+
state,
|
|
47551
|
+
range,
|
|
47552
|
+
match,
|
|
47553
|
+
commands,
|
|
47554
|
+
chain,
|
|
47555
|
+
can
|
|
47556
|
+
}) === null || !tr.steps.length) return false;
|
|
47557
|
+
if (inputTransaction) {
|
|
47558
|
+
view.dispatch(inputTransaction);
|
|
47559
|
+
if (!view.state.doc.eq(inputTransaction.doc)) return true;
|
|
47560
|
+
}
|
|
47561
|
+
closeHistory(tr);
|
|
47562
|
+
tr.setMeta("inputRule", true);
|
|
47563
|
+
if (rule.undoable) tr.setMeta(plugin, {
|
|
47564
|
+
transform: tr,
|
|
47565
|
+
from,
|
|
47566
|
+
to: inputEnd,
|
|
47567
|
+
text
|
|
47568
|
+
});
|
|
47569
|
+
view.dispatch(tr);
|
|
47570
|
+
return true;
|
|
47571
|
+
}
|
|
47572
|
+
/**
|
|
47573
|
+
* Checks that the part of a match already in the document has matching positions.
|
|
47574
|
+
*/
|
|
47575
|
+
function matchesDocument($from, match, text) {
|
|
47576
|
+
const matchedDocLength = match[0].length - text.length;
|
|
47577
|
+
if (matchedDocLength <= 0) return true;
|
|
47578
|
+
const matchStartOffset = $from.parentOffset - matchedDocLength;
|
|
47579
|
+
return matchStartOffset >= 0 && $from.parent.textBetween(matchStartOffset, $from.parentOffset) === match[0].slice(0, matchedDocLength);
|
|
47580
|
+
}
|
|
46828
47581
|
function run$1$1(config) {
|
|
46829
47582
|
var _ref;
|
|
46830
|
-
const { editor, from, to, text, rules, plugin } = config;
|
|
47583
|
+
const { editor, from, to, text, rules, plugin, insertText } = config;
|
|
46831
47584
|
const { view } = editor;
|
|
46832
47585
|
if (view.composing) return false;
|
|
46833
47586
|
const $from = view.state.doc.resolve(from);
|
|
46834
47587
|
if ($from.parent.type.spec.code || !!((_ref = $from.nodeBefore || $from.nodeAfter) === null || _ref === void 0 ? void 0 : _ref.marks.find((mark) => mark.type.spec.code))) return false;
|
|
46835
|
-
let matched = false;
|
|
46836
47588
|
const textBefore = getTextContentFromNodes($from) + text;
|
|
46837
|
-
|
|
46838
|
-
if (matched) return;
|
|
47589
|
+
for (const rule of rules) {
|
|
46839
47590
|
const match = inputRuleMatcherHandler(textBefore, rule.find);
|
|
46840
|
-
if (!match)
|
|
46841
|
-
|
|
46842
|
-
if (matchedDocLength > 0) {
|
|
46843
|
-
const matchStartOffset = $from.parentOffset - matchedDocLength;
|
|
46844
|
-
if (matchStartOffset < 0 || $from.parent.textBetween(matchStartOffset, $from.parentOffset) !== match[0].slice(0, matchedDocLength)) return;
|
|
46845
|
-
}
|
|
46846
|
-
const tr = view.state.tr;
|
|
46847
|
-
const state = createChainableState({
|
|
46848
|
-
state: view.state,
|
|
46849
|
-
transaction: tr
|
|
46850
|
-
});
|
|
46851
|
-
const range = {
|
|
46852
|
-
from: from - (match[0].length - text.length),
|
|
46853
|
-
to
|
|
46854
|
-
};
|
|
46855
|
-
const { commands, chain, can } = new CommandManager({
|
|
47591
|
+
if (!match || !matchesDocument($from, match, text)) continue;
|
|
47592
|
+
if (applyRule({
|
|
46856
47593
|
editor,
|
|
46857
|
-
state
|
|
46858
|
-
});
|
|
46859
|
-
if (rule.handler({
|
|
46860
|
-
state,
|
|
46861
|
-
range,
|
|
46862
|
-
match,
|
|
46863
|
-
commands,
|
|
46864
|
-
chain,
|
|
46865
|
-
can
|
|
46866
|
-
}) === null || !tr.steps.length) return;
|
|
46867
|
-
if (rule.undoable) tr.setMeta(plugin, {
|
|
46868
|
-
transform: tr,
|
|
46869
47594
|
from,
|
|
46870
47595
|
to,
|
|
46871
|
-
text
|
|
46872
|
-
|
|
46873
|
-
|
|
46874
|
-
|
|
46875
|
-
|
|
46876
|
-
|
|
47596
|
+
text,
|
|
47597
|
+
rule,
|
|
47598
|
+
match,
|
|
47599
|
+
plugin,
|
|
47600
|
+
insertText
|
|
47601
|
+
})) return true;
|
|
47602
|
+
}
|
|
47603
|
+
return false;
|
|
46877
47604
|
}
|
|
46878
47605
|
/**
|
|
46879
47606
|
* Create an input rules plugin. When enabled, it will cause text
|
|
@@ -46917,7 +47644,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
46917
47644
|
to,
|
|
46918
47645
|
text,
|
|
46919
47646
|
rules,
|
|
46920
|
-
plugin
|
|
47647
|
+
plugin,
|
|
47648
|
+
insertText: true
|
|
46921
47649
|
});
|
|
46922
47650
|
},
|
|
46923
47651
|
handleDOMEvents: { compositionend: (view) => {
|
|
@@ -47153,6 +47881,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
47153
47881
|
pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null;
|
|
47154
47882
|
return tr;
|
|
47155
47883
|
};
|
|
47884
|
+
editor.on("destroy", () => {
|
|
47885
|
+
if (tiptapDragFromOtherEditor === editor) tiptapDragFromOtherEditor = null;
|
|
47886
|
+
});
|
|
47156
47887
|
return rules.map((rule) => {
|
|
47157
47888
|
return new Plugin({
|
|
47158
47889
|
view(view) {
|
|
@@ -47178,6 +47909,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
47178
47909
|
if (!isDroppedFromProseMirror) {
|
|
47179
47910
|
const dragFromOtherEditor = tiptapDragFromOtherEditor;
|
|
47180
47911
|
if (dragFromOtherEditor === null || dragFromOtherEditor === void 0 ? void 0 : dragFromOtherEditor.isEditable) setTimeout(() => {
|
|
47912
|
+
if (dragFromOtherEditor.isDestroyed) return;
|
|
47181
47913
|
const selection = dragFromOtherEditor.state.selection;
|
|
47182
47914
|
if (selection) dragFromOtherEditor.commands.deleteRange({
|
|
47183
47915
|
from: selection.from,
|
|
@@ -48347,7 +49079,10 @@ img.ProseMirror-separator {
|
|
|
48347
49079
|
...options
|
|
48348
49080
|
};
|
|
48349
49081
|
if (!this.editorView || !this.state || this.isDestroyed) return;
|
|
48350
|
-
if (this.options.editorProps) this.view.setProps(
|
|
49082
|
+
if (this.options.editorProps) this.view.setProps({
|
|
49083
|
+
...this.options.editorProps,
|
|
49084
|
+
attributes: this.getEditorViewAttributes()
|
|
49085
|
+
});
|
|
48351
49086
|
this.view.updateState(this.state);
|
|
48352
49087
|
}
|
|
48353
49088
|
/**
|
|
@@ -48503,6 +49238,23 @@ img.ProseMirror-separator {
|
|
|
48503
49238
|
return doc;
|
|
48504
49239
|
}
|
|
48505
49240
|
/**
|
|
49241
|
+
* Returns the attributes for the editor element.
|
|
49242
|
+
* Merges the default `role="textbox"` with the attributes from `editorProps`,
|
|
49243
|
+
* so the role is kept no matter when the props are applied.
|
|
49244
|
+
*/
|
|
49245
|
+
getEditorViewAttributes() {
|
|
49246
|
+
var _this$options$editorP;
|
|
49247
|
+
const attributes = (_this$options$editorP = this.options.editorProps) === null || _this$options$editorP === void 0 ? void 0 : _this$options$editorP.attributes;
|
|
49248
|
+
if (isFunction$3(attributes)) return (state) => ({
|
|
49249
|
+
role: "textbox",
|
|
49250
|
+
...attributes(state)
|
|
49251
|
+
});
|
|
49252
|
+
return {
|
|
49253
|
+
role: "textbox",
|
|
49254
|
+
...attributes
|
|
49255
|
+
};
|
|
49256
|
+
}
|
|
49257
|
+
/**
|
|
48506
49258
|
* Creates a ProseMirror view.
|
|
48507
49259
|
*/
|
|
48508
49260
|
createView(element) {
|
|
@@ -48513,10 +49265,7 @@ img.ProseMirror-separator {
|
|
|
48513
49265
|
const transformPastedHTML = this.extensionManager.transformPastedHTML(baseTransformPastedHTML);
|
|
48514
49266
|
this.editorView = new EditorView(element, {
|
|
48515
49267
|
...editorProps,
|
|
48516
|
-
attributes:
|
|
48517
|
-
role: "textbox",
|
|
48518
|
-
...editorProps === null || editorProps === void 0 ? void 0 : editorProps.attributes
|
|
48519
|
-
},
|
|
49268
|
+
attributes: this.getEditorViewAttributes(),
|
|
48520
49269
|
dispatchTransaction: dispatch,
|
|
48521
49270
|
transformPastedHTML,
|
|
48522
49271
|
state: this.editorState,
|
|
@@ -58219,7 +58968,7 @@ img.ProseMirror-separator {
|
|
|
58219
58968
|
toDOM() { return ["div", ["hr"]]; }
|
|
58220
58969
|
},
|
|
58221
58970
|
heading: {
|
|
58222
|
-
attrs: { level: { default: 1 } },
|
|
58971
|
+
attrs: { level: { default: 1, validate: "number" } },
|
|
58223
58972
|
content: "(text | image)*",
|
|
58224
58973
|
group: "block",
|
|
58225
58974
|
defining: true,
|
|
@@ -58229,7 +58978,7 @@ img.ProseMirror-separator {
|
|
|
58229
58978
|
{ tag: "h4", attrs: { level: 4 } },
|
|
58230
58979
|
{ tag: "h5", attrs: { level: 5 } },
|
|
58231
58980
|
{ tag: "h6", attrs: { level: 6 } }],
|
|
58232
|
-
toDOM(node) { return ["h" + node.attrs.level, 0]; }
|
|
58981
|
+
toDOM(node) { return ["h" + +node.attrs.level, 0]; }
|
|
58233
58982
|
},
|
|
58234
58983
|
code_block: {
|
|
58235
58984
|
content: "text*",
|
|
@@ -61726,8 +62475,27 @@ img.ProseMirror-separator {
|
|
|
61726
62475
|
const UNICODE_WHITESPACE_PATTERN = "[\0- \xA0 -\u2029 ]";
|
|
61727
62476
|
const UNICODE_WHITESPACE_REGEX = new RegExp(UNICODE_WHITESPACE_PATTERN);
|
|
61728
62477
|
const UNICODE_WHITESPACE_REGEX_END = new RegExp(`${UNICODE_WHITESPACE_PATTERN}$`);
|
|
62478
|
+
const UNICODE_WHITESPACE_REGEX_TRAILING = new RegExp(`${UNICODE_WHITESPACE_PATTERN}+$`);
|
|
61729
62479
|
const UNICODE_WHITESPACE_REGEX_GLOBAL = new RegExp(UNICODE_WHITESPACE_PATTERN, "g");
|
|
61730
62480
|
//#endregion
|
|
62481
|
+
//#region src/helpers/unlinkTrailingWhitespace.ts
|
|
62482
|
+
function unlinkTrailingWhitespace(tr, range, type) {
|
|
62483
|
+
var _rangeEnd$nodeBefore, _insertedText$match;
|
|
62484
|
+
const rangeEnd = tr.doc.resolve(range.to);
|
|
62485
|
+
if (!((_rangeEnd$nodeBefore = rangeEnd.nodeBefore) === null || _rangeEnd$nodeBefore === void 0 ? void 0 : _rangeEnd$nodeBefore.isText)) return;
|
|
62486
|
+
const trailingWhitespace = (_insertedText$match = tr.doc.textBetween(range.from, range.to, "", "").match(UNICODE_WHITESPACE_REGEX_TRAILING)) === null || _insertedText$match === void 0 ? void 0 : _insertedText$match[0];
|
|
62487
|
+
if (!trailingWhitespace) return;
|
|
62488
|
+
const whitespaceFrom = range.to - trailingWhitespace.length;
|
|
62489
|
+
const linkMarks = getMarksBetween(whitespaceFrom, range.to, tr.doc).filter((item) => item.mark.type === type);
|
|
62490
|
+
if (!linkMarks.length) return;
|
|
62491
|
+
const { nodeAfter } = rangeEnd;
|
|
62492
|
+
if (!!nodeAfter && linkMarks.some((item) => item.mark.isInSet(nodeAfter.marks))) return;
|
|
62493
|
+
const storedMarks = tr.storedMarks;
|
|
62494
|
+
tr.removeMark(whitespaceFrom, range.to, type);
|
|
62495
|
+
tr.setStoredMarks(storedMarks);
|
|
62496
|
+
if (tr.selection.empty && tr.selection.from === range.to) tr.removeStoredMark(type);
|
|
62497
|
+
}
|
|
62498
|
+
//#endregion
|
|
61731
62499
|
//#region src/helpers/autolink.ts
|
|
61732
62500
|
/**
|
|
61733
62501
|
* Check if the provided tokens form a valid link structure, which can either be a single link token
|
|
@@ -61768,6 +62536,21 @@ img.ProseMirror-separator {
|
|
|
61768
62536
|
if (!docChanges || preventAutolink) return;
|
|
61769
62537
|
const { tr } = newState;
|
|
61770
62538
|
const transform = combineTransactionSteps(oldState.doc, [...transactions]);
|
|
62539
|
+
if (!transactions.some(isHistoryTransaction)) {
|
|
62540
|
+
const insertedRanges = [];
|
|
62541
|
+
transform.steps.forEach((step, index) => {
|
|
62542
|
+
if (!(step instanceof ReplaceStep) || !step.slice.size) return;
|
|
62543
|
+
const mapping = transform.mapping.slice(index + 1);
|
|
62544
|
+
const from = mapping.map(step.from, 1);
|
|
62545
|
+
const to = mapping.map(step.from + step.slice.size, -1);
|
|
62546
|
+
if (from < to) insertedRanges.push({
|
|
62547
|
+
from,
|
|
62548
|
+
to
|
|
62549
|
+
});
|
|
62550
|
+
});
|
|
62551
|
+
insertedRanges.sort((left, right) => right.to - left.to);
|
|
62552
|
+
insertedRanges.forEach((range) => unlinkTrailingWhitespace(tr, range, options.type));
|
|
62553
|
+
}
|
|
61771
62554
|
getChangedRanges(transform).forEach(({ newRange }) => {
|
|
61772
62555
|
const nodesInChangedRanges = findChildrenInRange(newState.doc, newRange, (node) => node.isTextblock);
|
|
61773
62556
|
let textBlock;
|
|
@@ -63154,6 +63937,54 @@ img.ProseMirror-separator {
|
|
|
63154
63937
|
});
|
|
63155
63938
|
}
|
|
63156
63939
|
//#endregion
|
|
63940
|
+
//#region src/ordered-list/collectOrderedListItemsFromSource.ts
|
|
63941
|
+
const ORDERED_LIST_SCAN_WINDOW = 64;
|
|
63942
|
+
function takeLines(source, max) {
|
|
63943
|
+
const lines = [];
|
|
63944
|
+
let start = 0;
|
|
63945
|
+
while (lines.length < max) {
|
|
63946
|
+
const lineEnd = source.indexOf("\n", start);
|
|
63947
|
+
if (lineEnd === -1) {
|
|
63948
|
+
lines.push(source.slice(start));
|
|
63949
|
+
return lines;
|
|
63950
|
+
}
|
|
63951
|
+
lines.push(source.slice(start, lineEnd));
|
|
63952
|
+
start = lineEnd + 1;
|
|
63953
|
+
}
|
|
63954
|
+
return lines;
|
|
63955
|
+
}
|
|
63956
|
+
/**
|
|
63957
|
+
* Collect ordered list items from the start of `source`, reading only the lines the list needs.
|
|
63958
|
+
*
|
|
63959
|
+
* @param source Markdown beginning at a block boundary.
|
|
63960
|
+
* @returns The items, how many lines they consumed, and the lines that were read.
|
|
63961
|
+
* @example
|
|
63962
|
+
* collectOrderedListItemsFromSource('1. one\n2. two\n\nAfter')
|
|
63963
|
+
* // → [[item, item], 3, ['1. one', '2. two', '', 'After']]
|
|
63964
|
+
*/
|
|
63965
|
+
function collectOrderedListItemsFromSource(source) {
|
|
63966
|
+
const firstLineEnd = source.indexOf("\n");
|
|
63967
|
+
const firstLine = firstLineEnd === -1 ? source : source.slice(0, firstLineEnd);
|
|
63968
|
+
if (!ORDERED_LIST_ITEM_REGEX.test(firstLine)) return [
|
|
63969
|
+
[],
|
|
63970
|
+
0,
|
|
63971
|
+
[]
|
|
63972
|
+
];
|
|
63973
|
+
let windowSize = ORDERED_LIST_SCAN_WINDOW;
|
|
63974
|
+
let lines = takeLines(source, windowSize);
|
|
63975
|
+
let collected = collectOrderedListItems(lines);
|
|
63976
|
+
while (collected[1] === lines.length && lines.length === windowSize) {
|
|
63977
|
+
windowSize *= 2;
|
|
63978
|
+
lines = takeLines(source, windowSize);
|
|
63979
|
+
collected = collectOrderedListItems(lines);
|
|
63980
|
+
}
|
|
63981
|
+
return [
|
|
63982
|
+
collected[0],
|
|
63983
|
+
collected[1],
|
|
63984
|
+
lines
|
|
63985
|
+
];
|
|
63986
|
+
}
|
|
63987
|
+
//#endregion
|
|
63157
63988
|
//#region src/ordered-list/ordered-list.ts
|
|
63158
63989
|
const ListItemName = "listItem";
|
|
63159
63990
|
const TextStyleName = "textStyle";
|
|
@@ -63272,8 +64103,7 @@ img.ProseMirror-separator {
|
|
|
63272
64103
|
start: () => -1,
|
|
63273
64104
|
tokenize: (src, _tokens, lexer) => {
|
|
63274
64105
|
var _listItems$, _listItems$2;
|
|
63275
|
-
const lines = src
|
|
63276
|
-
const [listItems, consumed] = collectOrderedListItems(lines);
|
|
64106
|
+
const [listItems, consumed, lines] = collectOrderedListItemsFromSource(src);
|
|
63277
64107
|
if (listItems.length === 0) return;
|
|
63278
64108
|
const items = buildNestedStructure(listItems, listItems[0].indent, lexer);
|
|
63279
64109
|
if (items.length === 0) return;
|
|
@@ -66044,1028 +66874,414 @@ img.ProseMirror-separator {
|
|
|
66044
66874
|
//#region src/text.ts
|
|
66045
66875
|
/**
|
|
66046
66876
|
* This extension allows you to create text nodes.
|
|
66047
|
-
* @see https://www.tiptap.dev/api/nodes/text
|
|
66048
|
-
*/
|
|
66049
|
-
const Text = Node$1.create({
|
|
66050
|
-
name: "text",
|
|
66051
|
-
group: "inline",
|
|
66052
|
-
parseMarkdown: (token) => {
|
|
66053
|
-
return {
|
|
66054
|
-
type: "text",
|
|
66055
|
-
text: token.text || ""
|
|
66056
|
-
};
|
|
66057
|
-
},
|
|
66058
|
-
renderMarkdown: (node) => node.text || ""
|
|
66059
|
-
});
|
|
66060
|
-
//#endregion
|
|
66061
|
-
//#region src/index.ts
|
|
66062
|
-
var src_default = Text;
|
|
66063
|
-
|
|
66064
|
-
/**
|
|
66065
|
-
Create a plugin that, when added to a ProseMirror instance,
|
|
66066
|
-
causes a decoration to show up at the drop position when something
|
|
66067
|
-
is dragged over the editor.
|
|
66068
|
-
|
|
66069
|
-
Nodes may add a `disableDropCursor` property to their spec to
|
|
66070
|
-
control the showing of a drop cursor inside them. This may be a
|
|
66071
|
-
boolean or a function, which will be called with a view and a
|
|
66072
|
-
position, and should return a boolean.
|
|
66073
|
-
*/
|
|
66074
|
-
function dropCursor(options = {}) {
|
|
66075
|
-
return new Plugin({
|
|
66076
|
-
view(editorView) { return new DropCursorView(editorView, options); }
|
|
66077
|
-
});
|
|
66078
|
-
}
|
|
66079
|
-
class DropCursorView {
|
|
66080
|
-
constructor(editorView, options) {
|
|
66081
|
-
var _a;
|
|
66082
|
-
this.editorView = editorView;
|
|
66083
|
-
this.cursorPos = null;
|
|
66084
|
-
this.element = null;
|
|
66085
|
-
this.timeout = -1;
|
|
66086
|
-
this.lastDragEvent = null;
|
|
66087
|
-
this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1;
|
|
66088
|
-
this.color = options.color === false ? undefined : (options.color || "black");
|
|
66089
|
-
this.class = options.class;
|
|
66090
|
-
this.handlers = ["dragover", "dragend", "drop", "dragleave"].map(name => {
|
|
66091
|
-
let handler = (e) => { this[name](e); };
|
|
66092
|
-
editorView.dom.addEventListener(name, handler);
|
|
66093
|
-
return { name, handler };
|
|
66094
|
-
});
|
|
66095
|
-
}
|
|
66096
|
-
destroy() {
|
|
66097
|
-
this.handlers.forEach(({ name, handler }) => this.editorView.dom.removeEventListener(name, handler));
|
|
66098
|
-
}
|
|
66099
|
-
update(editorView, prevState) {
|
|
66100
|
-
if (this.cursorPos != null && prevState.doc != editorView.state.doc) {
|
|
66101
|
-
// if we currently have an on-going drag event
|
|
66102
|
-
// we need to update the cursor position again and update the overlay
|
|
66103
|
-
if (this.lastDragEvent) {
|
|
66104
|
-
let target = this.computeTarget(this.lastDragEvent);
|
|
66105
|
-
if (target == this.cursorPos)
|
|
66106
|
-
this.updateOverlay();
|
|
66107
|
-
else
|
|
66108
|
-
this.setCursor(target);
|
|
66109
|
-
}
|
|
66110
|
-
else {
|
|
66111
|
-
this.updateOverlay();
|
|
66112
|
-
}
|
|
66113
|
-
}
|
|
66114
|
-
}
|
|
66115
|
-
setCursor(pos) {
|
|
66116
|
-
if (pos == this.cursorPos)
|
|
66117
|
-
return;
|
|
66118
|
-
this.cursorPos = pos;
|
|
66119
|
-
if (pos == null) {
|
|
66120
|
-
this.element.parentNode.removeChild(this.element);
|
|
66121
|
-
this.element = null;
|
|
66122
|
-
}
|
|
66123
|
-
else {
|
|
66124
|
-
this.updateOverlay();
|
|
66125
|
-
}
|
|
66126
|
-
}
|
|
66127
|
-
updateOverlay() {
|
|
66128
|
-
let $pos = this.editorView.state.doc.resolve(this.cursorPos);
|
|
66129
|
-
let isBlock = !$pos.parent.inlineContent, rect;
|
|
66130
|
-
let editorDOM = this.editorView.dom, editorRect = editorDOM.getBoundingClientRect();
|
|
66131
|
-
let scaleX = editorRect.width / editorDOM.offsetWidth, scaleY = editorRect.height / editorDOM.offsetHeight;
|
|
66132
|
-
if (isBlock) {
|
|
66133
|
-
let before = $pos.nodeBefore, after = $pos.nodeAfter;
|
|
66134
|
-
if (before || after) {
|
|
66135
|
-
let node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0));
|
|
66136
|
-
if (node) {
|
|
66137
|
-
let nodeRect = node.getBoundingClientRect();
|
|
66138
|
-
let top = before ? nodeRect.bottom : nodeRect.top;
|
|
66139
|
-
if (before && after)
|
|
66140
|
-
top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2;
|
|
66141
|
-
let halfWidth = (this.width / 2) * scaleY;
|
|
66142
|
-
rect = { left: nodeRect.left, right: nodeRect.right, top: top - halfWidth, bottom: top + halfWidth };
|
|
66143
|
-
}
|
|
66144
|
-
}
|
|
66145
|
-
}
|
|
66146
|
-
if (!rect) {
|
|
66147
|
-
let coords = this.editorView.coordsAtPos(this.cursorPos);
|
|
66148
|
-
let halfWidth = (this.width / 2) * scaleX;
|
|
66149
|
-
rect = { left: coords.left - halfWidth, right: coords.left + halfWidth, top: coords.top, bottom: coords.bottom };
|
|
66150
|
-
}
|
|
66151
|
-
let parent = this.editorView.dom.offsetParent;
|
|
66152
|
-
if (!this.element) {
|
|
66153
|
-
this.element = parent.appendChild(document.createElement("div"));
|
|
66154
|
-
if (this.class)
|
|
66155
|
-
this.element.className = this.class;
|
|
66156
|
-
this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;";
|
|
66157
|
-
if (this.color) {
|
|
66158
|
-
this.element.style.backgroundColor = this.color;
|
|
66159
|
-
}
|
|
66160
|
-
}
|
|
66161
|
-
this.element.classList.toggle("prosemirror-dropcursor-block", isBlock);
|
|
66162
|
-
this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock);
|
|
66163
|
-
let parentLeft, parentTop;
|
|
66164
|
-
if (!parent || parent == document.body && getComputedStyle(parent).position == "static") {
|
|
66165
|
-
parentLeft = -pageXOffset;
|
|
66166
|
-
parentTop = -pageYOffset;
|
|
66167
|
-
}
|
|
66168
|
-
else {
|
|
66169
|
-
let rect = parent.getBoundingClientRect();
|
|
66170
|
-
let parentScaleX = rect.width / parent.offsetWidth, parentScaleY = rect.height / parent.offsetHeight;
|
|
66171
|
-
parentLeft = rect.left - parent.scrollLeft * parentScaleX;
|
|
66172
|
-
parentTop = rect.top - parent.scrollTop * parentScaleY;
|
|
66173
|
-
}
|
|
66174
|
-
this.element.style.left = (rect.left - parentLeft) / scaleX + "px";
|
|
66175
|
-
this.element.style.top = (rect.top - parentTop) / scaleY + "px";
|
|
66176
|
-
this.element.style.width = (rect.right - rect.left) / scaleX + "px";
|
|
66177
|
-
this.element.style.height = (rect.bottom - rect.top) / scaleY + "px";
|
|
66178
|
-
}
|
|
66179
|
-
scheduleRemoval(timeout) {
|
|
66180
|
-
clearTimeout(this.timeout);
|
|
66181
|
-
this.timeout = setTimeout(() => this.setCursor(null), timeout);
|
|
66182
|
-
}
|
|
66183
|
-
computeTarget(event) {
|
|
66184
|
-
let pos = this.editorView.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
66185
|
-
let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);
|
|
66186
|
-
let disableDropCursor = node && node.type.spec.disableDropCursor;
|
|
66187
|
-
let disabled = typeof disableDropCursor == "function"
|
|
66188
|
-
? disableDropCursor(this.editorView, pos, event)
|
|
66189
|
-
: disableDropCursor;
|
|
66190
|
-
if (!pos || disabled)
|
|
66191
|
-
return null;
|
|
66192
|
-
let target = pos.pos;
|
|
66193
|
-
if (this.editorView.dragging && this.editorView.dragging.slice) {
|
|
66194
|
-
let point = dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice);
|
|
66195
|
-
if (point != null)
|
|
66196
|
-
target = point;
|
|
66197
|
-
}
|
|
66198
|
-
return target;
|
|
66199
|
-
}
|
|
66200
|
-
dragover(event) {
|
|
66201
|
-
if (!this.editorView.editable)
|
|
66202
|
-
return;
|
|
66203
|
-
this.lastDragEvent = event;
|
|
66204
|
-
let target = this.computeTarget(event);
|
|
66205
|
-
if (target != null) {
|
|
66206
|
-
this.setCursor(target);
|
|
66207
|
-
this.scheduleRemoval(5000);
|
|
66208
|
-
}
|
|
66209
|
-
}
|
|
66210
|
-
dragend() {
|
|
66211
|
-
this.scheduleRemoval(20);
|
|
66212
|
-
}
|
|
66213
|
-
drop() {
|
|
66214
|
-
this.scheduleRemoval(20);
|
|
66215
|
-
}
|
|
66216
|
-
dragleave(event) {
|
|
66217
|
-
if (!this.editorView.dom.contains(event.relatedTarget))
|
|
66218
|
-
this.setCursor(null);
|
|
66219
|
-
}
|
|
66220
|
-
}
|
|
66221
|
-
|
|
66222
|
-
/**
|
|
66223
|
-
Gap cursor selections are represented using this class. Its
|
|
66224
|
-
`$anchor` and `$head` properties both point at the cursor position.
|
|
66225
|
-
*/
|
|
66226
|
-
class GapCursor extends Selection$2 {
|
|
66227
|
-
/**
|
|
66228
|
-
Create a gap cursor.
|
|
66229
|
-
*/
|
|
66230
|
-
constructor($pos) {
|
|
66231
|
-
super($pos, $pos);
|
|
66232
|
-
}
|
|
66233
|
-
map(doc, mapping) {
|
|
66234
|
-
let $pos = doc.resolve(mapping.map(this.head));
|
|
66235
|
-
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$2.near($pos);
|
|
66236
|
-
}
|
|
66237
|
-
content() { return Slice.empty; }
|
|
66238
|
-
eq(other) {
|
|
66239
|
-
return other instanceof GapCursor && other.head == this.head;
|
|
66240
|
-
}
|
|
66241
|
-
toJSON() {
|
|
66242
|
-
return { type: "gapcursor", pos: this.head };
|
|
66243
|
-
}
|
|
66244
|
-
/**
|
|
66245
|
-
@internal
|
|
66246
|
-
*/
|
|
66247
|
-
static fromJSON(doc, json) {
|
|
66248
|
-
if (typeof json.pos != "number")
|
|
66249
|
-
throw new RangeError("Invalid input for GapCursor.fromJSON");
|
|
66250
|
-
return new GapCursor(doc.resolve(json.pos));
|
|
66251
|
-
}
|
|
66252
|
-
/**
|
|
66253
|
-
@internal
|
|
66254
|
-
*/
|
|
66255
|
-
getBookmark() { return new GapBookmark(this.anchor); }
|
|
66256
|
-
/**
|
|
66257
|
-
@internal
|
|
66258
|
-
*/
|
|
66259
|
-
static valid($pos) {
|
|
66260
|
-
let parent = $pos.parent;
|
|
66261
|
-
if (parent.inlineContent || !closedBefore($pos) || !closedAfter($pos))
|
|
66262
|
-
return false;
|
|
66263
|
-
let override = parent.type.spec.allowGapCursor;
|
|
66264
|
-
if (override != null)
|
|
66265
|
-
return override;
|
|
66266
|
-
let deflt = parent.contentMatchAt($pos.index()).defaultType;
|
|
66267
|
-
return deflt && deflt.isTextblock;
|
|
66268
|
-
}
|
|
66269
|
-
/**
|
|
66270
|
-
@internal
|
|
66271
|
-
*/
|
|
66272
|
-
static findGapCursorFrom($pos, dir, mustMove = false) {
|
|
66273
|
-
search: for (;;) {
|
|
66274
|
-
if (!mustMove && GapCursor.valid($pos))
|
|
66275
|
-
return $pos;
|
|
66276
|
-
let pos = $pos.pos, next = null;
|
|
66277
|
-
// Scan up from this position
|
|
66278
|
-
for (let d = $pos.depth;; d--) {
|
|
66279
|
-
let parent = $pos.node(d);
|
|
66280
|
-
if (dir > 0 ? $pos.indexAfter(d) < parent.childCount : $pos.index(d) > 0) {
|
|
66281
|
-
next = parent.child(dir > 0 ? $pos.indexAfter(d) : $pos.index(d) - 1);
|
|
66282
|
-
break;
|
|
66283
|
-
}
|
|
66284
|
-
else if (d == 0) {
|
|
66285
|
-
return null;
|
|
66286
|
-
}
|
|
66287
|
-
pos += dir;
|
|
66288
|
-
let $cur = $pos.doc.resolve(pos);
|
|
66289
|
-
if (GapCursor.valid($cur))
|
|
66290
|
-
return $cur;
|
|
66291
|
-
}
|
|
66292
|
-
// And then down into the next node
|
|
66293
|
-
for (;;) {
|
|
66294
|
-
let inside = dir > 0 ? next.firstChild : next.lastChild;
|
|
66295
|
-
if (!inside) {
|
|
66296
|
-
if (next.isAtom && !next.isText && !NodeSelection.isSelectable(next)) {
|
|
66297
|
-
$pos = $pos.doc.resolve(pos + next.nodeSize * dir);
|
|
66298
|
-
mustMove = false;
|
|
66299
|
-
continue search;
|
|
66300
|
-
}
|
|
66301
|
-
break;
|
|
66302
|
-
}
|
|
66303
|
-
next = inside;
|
|
66304
|
-
pos += dir;
|
|
66305
|
-
let $cur = $pos.doc.resolve(pos);
|
|
66306
|
-
if (GapCursor.valid($cur))
|
|
66307
|
-
return $cur;
|
|
66308
|
-
}
|
|
66309
|
-
return null;
|
|
66310
|
-
}
|
|
66311
|
-
}
|
|
66312
|
-
}
|
|
66313
|
-
GapCursor.prototype.visible = false;
|
|
66314
|
-
GapCursor.findFrom = GapCursor.findGapCursorFrom;
|
|
66315
|
-
Selection$2.jsonID("gapcursor", GapCursor);
|
|
66316
|
-
class GapBookmark {
|
|
66317
|
-
constructor(pos) {
|
|
66318
|
-
this.pos = pos;
|
|
66319
|
-
}
|
|
66320
|
-
map(mapping) {
|
|
66321
|
-
return new GapBookmark(mapping.map(this.pos));
|
|
66322
|
-
}
|
|
66323
|
-
resolve(doc) {
|
|
66324
|
-
let $pos = doc.resolve(this.pos);
|
|
66325
|
-
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$2.near($pos);
|
|
66326
|
-
}
|
|
66327
|
-
}
|
|
66328
|
-
function needsGap(type) {
|
|
66329
|
-
return type.isAtom || type.spec.isolating || type.spec.createGapCursor;
|
|
66330
|
-
}
|
|
66331
|
-
function closedBefore($pos) {
|
|
66332
|
-
for (let d = $pos.depth; d >= 0; d--) {
|
|
66333
|
-
let index = $pos.index(d), parent = $pos.node(d);
|
|
66334
|
-
// At the start of this parent, look at next one
|
|
66335
|
-
if (index == 0) {
|
|
66336
|
-
if (parent.type.spec.isolating)
|
|
66337
|
-
return true;
|
|
66338
|
-
continue;
|
|
66339
|
-
}
|
|
66340
|
-
// See if the node before (or its first ancestor) is closed
|
|
66341
|
-
for (let before = parent.child(index - 1);; before = before.lastChild) {
|
|
66342
|
-
if ((before.childCount == 0 && !before.inlineContent) || needsGap(before.type))
|
|
66343
|
-
return true;
|
|
66344
|
-
if (before.inlineContent)
|
|
66345
|
-
return false;
|
|
66346
|
-
}
|
|
66347
|
-
}
|
|
66348
|
-
// Hit start of document
|
|
66349
|
-
return true;
|
|
66350
|
-
}
|
|
66351
|
-
function closedAfter($pos) {
|
|
66352
|
-
for (let d = $pos.depth; d >= 0; d--) {
|
|
66353
|
-
let index = $pos.indexAfter(d), parent = $pos.node(d);
|
|
66354
|
-
if (index == parent.childCount) {
|
|
66355
|
-
if (parent.type.spec.isolating)
|
|
66356
|
-
return true;
|
|
66357
|
-
continue;
|
|
66358
|
-
}
|
|
66359
|
-
for (let after = parent.child(index);; after = after.firstChild) {
|
|
66360
|
-
if ((after.childCount == 0 && !after.inlineContent) || needsGap(after.type))
|
|
66361
|
-
return true;
|
|
66362
|
-
if (after.inlineContent)
|
|
66363
|
-
return false;
|
|
66364
|
-
}
|
|
66365
|
-
}
|
|
66366
|
-
return true;
|
|
66367
|
-
}
|
|
66877
|
+
* @see https://www.tiptap.dev/api/nodes/text
|
|
66878
|
+
*/
|
|
66879
|
+
const Text = Node$1.create({
|
|
66880
|
+
name: "text",
|
|
66881
|
+
group: "inline",
|
|
66882
|
+
parseMarkdown: (token) => {
|
|
66883
|
+
return {
|
|
66884
|
+
type: "text",
|
|
66885
|
+
text: token.text || ""
|
|
66886
|
+
};
|
|
66887
|
+
},
|
|
66888
|
+
renderMarkdown: (node) => node.text || ""
|
|
66889
|
+
});
|
|
66890
|
+
//#endregion
|
|
66891
|
+
//#region src/index.ts
|
|
66892
|
+
var src_default = Text;
|
|
66368
66893
|
|
|
66369
66894
|
/**
|
|
66370
|
-
Create a
|
|
66371
|
-
|
|
66372
|
-
|
|
66373
|
-
|
|
66374
|
-
`
|
|
66375
|
-
|
|
66376
|
-
|
|
66895
|
+
Create a plugin that, when added to a ProseMirror instance,
|
|
66896
|
+
causes a decoration to show up at the drop position when something
|
|
66897
|
+
is dragged over the editor.
|
|
66898
|
+
|
|
66899
|
+
Nodes may add a `disableDropCursor` property to their spec to
|
|
66900
|
+
control the showing of a drop cursor inside them. This may be a
|
|
66901
|
+
boolean or a function, which will be called with a view and a
|
|
66902
|
+
position, and should return a boolean.
|
|
66377
66903
|
*/
|
|
66378
|
-
function
|
|
66904
|
+
function dropCursor(options = {}) {
|
|
66379
66905
|
return new Plugin({
|
|
66380
|
-
|
|
66381
|
-
decorations: drawGapCursor,
|
|
66382
|
-
createSelectionBetween(_view, $anchor, $head) {
|
|
66383
|
-
return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null;
|
|
66384
|
-
},
|
|
66385
|
-
handleClick,
|
|
66386
|
-
handleKeyDown,
|
|
66387
|
-
handleDOMEvents: { beforeinput: beforeinput }
|
|
66388
|
-
}
|
|
66906
|
+
view(editorView) { return new DropCursorView(editorView, options); }
|
|
66389
66907
|
});
|
|
66390
66908
|
}
|
|
66391
|
-
|
|
66392
|
-
|
|
66393
|
-
|
|
66394
|
-
|
|
66395
|
-
|
|
66396
|
-
|
|
66397
|
-
|
|
66398
|
-
|
|
66399
|
-
|
|
66400
|
-
|
|
66401
|
-
|
|
66402
|
-
|
|
66403
|
-
|
|
66404
|
-
|
|
66405
|
-
|
|
66406
|
-
|
|
66407
|
-
}
|
|
66408
|
-
let $found = GapCursor.findGapCursorFrom($start, dir, mustMove);
|
|
66409
|
-
if (!$found)
|
|
66410
|
-
return false;
|
|
66411
|
-
if (dispatch)
|
|
66412
|
-
dispatch(state.tr.setSelection(new GapCursor($found)));
|
|
66413
|
-
return true;
|
|
66414
|
-
};
|
|
66415
|
-
}
|
|
66416
|
-
function handleClick(view, pos, event) {
|
|
66417
|
-
if (!view || !view.editable)
|
|
66418
|
-
return false;
|
|
66419
|
-
let $pos = view.state.doc.resolve(pos);
|
|
66420
|
-
if (!GapCursor.valid($pos))
|
|
66421
|
-
return false;
|
|
66422
|
-
let clickPos = view.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
66423
|
-
if (clickPos && clickPos.inside > -1 && NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside)))
|
|
66424
|
-
return false;
|
|
66425
|
-
view.dispatch(view.state.tr.setSelection(new GapCursor($pos)));
|
|
66426
|
-
return true;
|
|
66427
|
-
}
|
|
66428
|
-
// This is a hack that, when a composition starts while a gap cursor
|
|
66429
|
-
// is active, quickly creates an inline context for the composition to
|
|
66430
|
-
// happen in, to avoid it being aborted by the DOM selection being
|
|
66431
|
-
// moved into a valid position.
|
|
66432
|
-
function beforeinput(view, event) {
|
|
66433
|
-
if (event.inputType != "insertCompositionText" || !(view.state.selection instanceof GapCursor))
|
|
66434
|
-
return false;
|
|
66435
|
-
let { $from } = view.state.selection;
|
|
66436
|
-
let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text);
|
|
66437
|
-
if (!insert)
|
|
66438
|
-
return false;
|
|
66439
|
-
let frag = Fragment.empty;
|
|
66440
|
-
for (let i = insert.length - 1; i >= 0; i--)
|
|
66441
|
-
frag = Fragment.from(insert[i].createAndFill(null, frag));
|
|
66442
|
-
let tr = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0));
|
|
66443
|
-
tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + 1)));
|
|
66444
|
-
view.dispatch(tr);
|
|
66445
|
-
return false;
|
|
66446
|
-
}
|
|
66447
|
-
function drawGapCursor(state) {
|
|
66448
|
-
if (!(state.selection instanceof GapCursor))
|
|
66449
|
-
return null;
|
|
66450
|
-
let node = document.createElement("div");
|
|
66451
|
-
node.className = "ProseMirror-gapcursor";
|
|
66452
|
-
return DecorationSet.create(state.doc, [Decoration.widget(state.selection.head, node, { key: "gapcursor" })]);
|
|
66453
|
-
}
|
|
66454
|
-
|
|
66455
|
-
var GOOD_LEAF_SIZE = 200;
|
|
66456
|
-
|
|
66457
|
-
// :: class<T> A rope sequence is a persistent sequence data structure
|
|
66458
|
-
// that supports appending, prepending, and slicing without doing a
|
|
66459
|
-
// full copy. It is represented as a mostly-balanced tree.
|
|
66460
|
-
var RopeSequence = function RopeSequence () {};
|
|
66461
|
-
|
|
66462
|
-
RopeSequence.prototype.append = function append (other) {
|
|
66463
|
-
if (!other.length) { return this }
|
|
66464
|
-
other = RopeSequence.from(other);
|
|
66465
|
-
|
|
66466
|
-
return (!this.length && other) ||
|
|
66467
|
-
(other.length < GOOD_LEAF_SIZE && this.leafAppend(other)) ||
|
|
66468
|
-
(this.length < GOOD_LEAF_SIZE && other.leafPrepend(this)) ||
|
|
66469
|
-
this.appendInner(other)
|
|
66470
|
-
};
|
|
66471
|
-
|
|
66472
|
-
// :: (union<[T], RopeSequence<T>>) → RopeSequence<T>
|
|
66473
|
-
// Prepend an array or other rope to this one, returning a new rope.
|
|
66474
|
-
RopeSequence.prototype.prepend = function prepend (other) {
|
|
66475
|
-
if (!other.length) { return this }
|
|
66476
|
-
return RopeSequence.from(other).append(this)
|
|
66477
|
-
};
|
|
66478
|
-
|
|
66479
|
-
RopeSequence.prototype.appendInner = function appendInner (other) {
|
|
66480
|
-
return new Append(this, other)
|
|
66481
|
-
};
|
|
66482
|
-
|
|
66483
|
-
// :: (?number, ?number) → RopeSequence<T>
|
|
66484
|
-
// Create a rope repesenting a sub-sequence of this rope.
|
|
66485
|
-
RopeSequence.prototype.slice = function slice (from, to) {
|
|
66486
|
-
if ( from === void 0 ) from = 0;
|
|
66487
|
-
if ( to === void 0 ) to = this.length;
|
|
66488
|
-
|
|
66489
|
-
if (from >= to) { return RopeSequence.empty }
|
|
66490
|
-
return this.sliceInner(Math.max(0, from), Math.min(this.length, to))
|
|
66491
|
-
};
|
|
66492
|
-
|
|
66493
|
-
// :: (number) → T
|
|
66494
|
-
// Retrieve the element at the given position from this rope.
|
|
66495
|
-
RopeSequence.prototype.get = function get (i) {
|
|
66496
|
-
if (i < 0 || i >= this.length) { return undefined }
|
|
66497
|
-
return this.getInner(i)
|
|
66498
|
-
};
|
|
66499
|
-
|
|
66500
|
-
// :: ((element: T, index: number) → ?bool, ?number, ?number)
|
|
66501
|
-
// Call the given function for each element between the given
|
|
66502
|
-
// indices. This tends to be more efficient than looping over the
|
|
66503
|
-
// indices and calling `get`, because it doesn't have to descend the
|
|
66504
|
-
// tree for every element.
|
|
66505
|
-
RopeSequence.prototype.forEach = function forEach (f, from, to) {
|
|
66506
|
-
if ( from === void 0 ) from = 0;
|
|
66507
|
-
if ( to === void 0 ) to = this.length;
|
|
66508
|
-
|
|
66509
|
-
if (from <= to)
|
|
66510
|
-
{ this.forEachInner(f, from, to, 0); }
|
|
66511
|
-
else
|
|
66512
|
-
{ this.forEachInvertedInner(f, from, to, 0); }
|
|
66513
|
-
};
|
|
66514
|
-
|
|
66515
|
-
// :: ((element: T, index: number) → U, ?number, ?number) → [U]
|
|
66516
|
-
// Map the given functions over the elements of the rope, producing
|
|
66517
|
-
// a flat array.
|
|
66518
|
-
RopeSequence.prototype.map = function map (f, from, to) {
|
|
66519
|
-
if ( from === void 0 ) from = 0;
|
|
66520
|
-
if ( to === void 0 ) to = this.length;
|
|
66521
|
-
|
|
66522
|
-
var result = [];
|
|
66523
|
-
this.forEach(function (elt, i) { return result.push(f(elt, i)); }, from, to);
|
|
66524
|
-
return result
|
|
66525
|
-
};
|
|
66526
|
-
|
|
66527
|
-
// :: (?union<[T], RopeSequence<T>>) → RopeSequence<T>
|
|
66528
|
-
// Create a rope representing the given array, or return the rope
|
|
66529
|
-
// itself if a rope was given.
|
|
66530
|
-
RopeSequence.from = function from (values) {
|
|
66531
|
-
if (values instanceof RopeSequence) { return values }
|
|
66532
|
-
return values && values.length ? new Leaf(values) : RopeSequence.empty
|
|
66533
|
-
};
|
|
66534
|
-
|
|
66535
|
-
var Leaf = /*@__PURE__*/(function (RopeSequence) {
|
|
66536
|
-
function Leaf(values) {
|
|
66537
|
-
RopeSequence.call(this);
|
|
66538
|
-
this.values = values;
|
|
66539
|
-
}
|
|
66540
|
-
|
|
66541
|
-
if ( RopeSequence ) Leaf.__proto__ = RopeSequence;
|
|
66542
|
-
Leaf.prototype = Object.create( RopeSequence && RopeSequence.prototype );
|
|
66543
|
-
Leaf.prototype.constructor = Leaf;
|
|
66544
|
-
|
|
66545
|
-
var prototypeAccessors = { length: { configurable: true },depth: { configurable: true } };
|
|
66546
|
-
|
|
66547
|
-
Leaf.prototype.flatten = function flatten () {
|
|
66548
|
-
return this.values
|
|
66549
|
-
};
|
|
66550
|
-
|
|
66551
|
-
Leaf.prototype.sliceInner = function sliceInner (from, to) {
|
|
66552
|
-
if (from == 0 && to == this.length) { return this }
|
|
66553
|
-
return new Leaf(this.values.slice(from, to))
|
|
66554
|
-
};
|
|
66555
|
-
|
|
66556
|
-
Leaf.prototype.getInner = function getInner (i) {
|
|
66557
|
-
return this.values[i]
|
|
66558
|
-
};
|
|
66559
|
-
|
|
66560
|
-
Leaf.prototype.forEachInner = function forEachInner (f, from, to, start) {
|
|
66561
|
-
for (var i = from; i < to; i++)
|
|
66562
|
-
{ if (f(this.values[i], start + i) === false) { return false } }
|
|
66563
|
-
};
|
|
66564
|
-
|
|
66565
|
-
Leaf.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
|
|
66566
|
-
for (var i = from - 1; i >= to; i--)
|
|
66567
|
-
{ if (f(this.values[i], start + i) === false) { return false } }
|
|
66568
|
-
};
|
|
66569
|
-
|
|
66570
|
-
Leaf.prototype.leafAppend = function leafAppend (other) {
|
|
66571
|
-
if (this.length + other.length <= GOOD_LEAF_SIZE)
|
|
66572
|
-
{ return new Leaf(this.values.concat(other.flatten())) }
|
|
66573
|
-
};
|
|
66574
|
-
|
|
66575
|
-
Leaf.prototype.leafPrepend = function leafPrepend (other) {
|
|
66576
|
-
if (this.length + other.length <= GOOD_LEAF_SIZE)
|
|
66577
|
-
{ return new Leaf(other.flatten().concat(this.values)) }
|
|
66578
|
-
};
|
|
66579
|
-
|
|
66580
|
-
prototypeAccessors.length.get = function () { return this.values.length };
|
|
66581
|
-
|
|
66582
|
-
prototypeAccessors.depth.get = function () { return 0 };
|
|
66583
|
-
|
|
66584
|
-
Object.defineProperties( Leaf.prototype, prototypeAccessors );
|
|
66585
|
-
|
|
66586
|
-
return Leaf;
|
|
66587
|
-
}(RopeSequence));
|
|
66588
|
-
|
|
66589
|
-
// :: RopeSequence
|
|
66590
|
-
// The empty rope sequence.
|
|
66591
|
-
RopeSequence.empty = new Leaf([]);
|
|
66592
|
-
|
|
66593
|
-
var Append = /*@__PURE__*/(function (RopeSequence) {
|
|
66594
|
-
function Append(left, right) {
|
|
66595
|
-
RopeSequence.call(this);
|
|
66596
|
-
this.left = left;
|
|
66597
|
-
this.right = right;
|
|
66598
|
-
this.length = left.length + right.length;
|
|
66599
|
-
this.depth = Math.max(left.depth, right.depth) + 1;
|
|
66600
|
-
}
|
|
66601
|
-
|
|
66602
|
-
if ( RopeSequence ) Append.__proto__ = RopeSequence;
|
|
66603
|
-
Append.prototype = Object.create( RopeSequence && RopeSequence.prototype );
|
|
66604
|
-
Append.prototype.constructor = Append;
|
|
66605
|
-
|
|
66606
|
-
Append.prototype.flatten = function flatten () {
|
|
66607
|
-
return this.left.flatten().concat(this.right.flatten())
|
|
66608
|
-
};
|
|
66609
|
-
|
|
66610
|
-
Append.prototype.getInner = function getInner (i) {
|
|
66611
|
-
return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length)
|
|
66612
|
-
};
|
|
66613
|
-
|
|
66614
|
-
Append.prototype.forEachInner = function forEachInner (f, from, to, start) {
|
|
66615
|
-
var leftLen = this.left.length;
|
|
66616
|
-
if (from < leftLen &&
|
|
66617
|
-
this.left.forEachInner(f, from, Math.min(to, leftLen), start) === false)
|
|
66618
|
-
{ return false }
|
|
66619
|
-
if (to > leftLen &&
|
|
66620
|
-
this.right.forEachInner(f, Math.max(from - leftLen, 0), Math.min(this.length, to) - leftLen, start + leftLen) === false)
|
|
66621
|
-
{ return false }
|
|
66622
|
-
};
|
|
66623
|
-
|
|
66624
|
-
Append.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
|
|
66625
|
-
var leftLen = this.left.length;
|
|
66626
|
-
if (from > leftLen &&
|
|
66627
|
-
this.right.forEachInvertedInner(f, from - leftLen, Math.max(to, leftLen) - leftLen, start + leftLen) === false)
|
|
66628
|
-
{ return false }
|
|
66629
|
-
if (to < leftLen &&
|
|
66630
|
-
this.left.forEachInvertedInner(f, Math.min(from, leftLen), to, start) === false)
|
|
66631
|
-
{ return false }
|
|
66632
|
-
};
|
|
66633
|
-
|
|
66634
|
-
Append.prototype.sliceInner = function sliceInner (from, to) {
|
|
66635
|
-
if (from == 0 && to == this.length) { return this }
|
|
66636
|
-
var leftLen = this.left.length;
|
|
66637
|
-
if (to <= leftLen) { return this.left.slice(from, to) }
|
|
66638
|
-
if (from >= leftLen) { return this.right.slice(from - leftLen, to - leftLen) }
|
|
66639
|
-
return this.left.slice(from, leftLen).append(this.right.slice(0, to - leftLen))
|
|
66640
|
-
};
|
|
66641
|
-
|
|
66642
|
-
Append.prototype.leafAppend = function leafAppend (other) {
|
|
66643
|
-
var inner = this.right.leafAppend(other);
|
|
66644
|
-
if (inner) { return new Append(this.left, inner) }
|
|
66645
|
-
};
|
|
66646
|
-
|
|
66647
|
-
Append.prototype.leafPrepend = function leafPrepend (other) {
|
|
66648
|
-
var inner = this.left.leafPrepend(other);
|
|
66649
|
-
if (inner) { return new Append(inner, this.right) }
|
|
66650
|
-
};
|
|
66651
|
-
|
|
66652
|
-
Append.prototype.appendInner = function appendInner (other) {
|
|
66653
|
-
if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1)
|
|
66654
|
-
{ return new Append(this.left, new Append(this.right, other)) }
|
|
66655
|
-
return new Append(this, other)
|
|
66656
|
-
};
|
|
66657
|
-
|
|
66658
|
-
return Append;
|
|
66659
|
-
}(RopeSequence));
|
|
66660
|
-
|
|
66661
|
-
// ProseMirror's history isn't simply a way to roll back to a previous
|
|
66662
|
-
// state, because ProseMirror supports applying changes without adding
|
|
66663
|
-
// them to the history (for example during collaboration).
|
|
66664
|
-
//
|
|
66665
|
-
// To this end, each 'Branch' (one for the undo history and one for
|
|
66666
|
-
// the redo history) keeps an array of 'Items', which can optionally
|
|
66667
|
-
// hold a step (an actual undoable change), and always hold a position
|
|
66668
|
-
// map (which is needed to move changes below them to apply to the
|
|
66669
|
-
// current document).
|
|
66670
|
-
//
|
|
66671
|
-
// An item that has both a step and a selection bookmark is the start
|
|
66672
|
-
// of an 'event' — a group of changes that will be undone or redone at
|
|
66673
|
-
// once. (It stores only the bookmark, since that way we don't have to
|
|
66674
|
-
// provide a document until the selection is actually applied, which
|
|
66675
|
-
// is useful when compressing.)
|
|
66676
|
-
// Used to schedule history compression
|
|
66677
|
-
const max_empty_items = 500;
|
|
66678
|
-
class Branch {
|
|
66679
|
-
constructor(items, eventCount) {
|
|
66680
|
-
this.items = items;
|
|
66681
|
-
this.eventCount = eventCount;
|
|
66682
|
-
}
|
|
66683
|
-
// Pop the latest event off the branch's history and apply it
|
|
66684
|
-
// to a document transform.
|
|
66685
|
-
popEvent(state, preserveItems) {
|
|
66686
|
-
if (this.eventCount == 0)
|
|
66687
|
-
return null;
|
|
66688
|
-
let end = this.items.length;
|
|
66689
|
-
for (;; end--) {
|
|
66690
|
-
let next = this.items.get(end - 1);
|
|
66691
|
-
if (next.selection) {
|
|
66692
|
-
--end;
|
|
66693
|
-
break;
|
|
66694
|
-
}
|
|
66695
|
-
}
|
|
66696
|
-
let remap, mapFrom;
|
|
66697
|
-
if (preserveItems) {
|
|
66698
|
-
remap = this.remapping(end, this.items.length);
|
|
66699
|
-
mapFrom = remap.maps.length;
|
|
66700
|
-
}
|
|
66701
|
-
let transform = state.tr;
|
|
66702
|
-
let selection, remaining;
|
|
66703
|
-
let addAfter = [], addBefore = [];
|
|
66704
|
-
this.items.forEach((item, i) => {
|
|
66705
|
-
if (!item.step) {
|
|
66706
|
-
if (!remap) {
|
|
66707
|
-
remap = this.remapping(end, i + 1);
|
|
66708
|
-
mapFrom = remap.maps.length;
|
|
66709
|
-
}
|
|
66710
|
-
mapFrom--;
|
|
66711
|
-
addBefore.push(item);
|
|
66712
|
-
return;
|
|
66713
|
-
}
|
|
66714
|
-
if (remap) {
|
|
66715
|
-
addBefore.push(new Item(item.map));
|
|
66716
|
-
let step = item.step.map(remap.slice(mapFrom)), map;
|
|
66717
|
-
if (step && transform.maybeStep(step).doc) {
|
|
66718
|
-
map = transform.mapping.maps[transform.mapping.maps.length - 1];
|
|
66719
|
-
addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length));
|
|
66720
|
-
}
|
|
66721
|
-
mapFrom--;
|
|
66722
|
-
if (map)
|
|
66723
|
-
remap.appendMap(map, mapFrom);
|
|
66724
|
-
}
|
|
66725
|
-
else {
|
|
66726
|
-
transform.maybeStep(item.step);
|
|
66727
|
-
}
|
|
66728
|
-
if (item.selection) {
|
|
66729
|
-
selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;
|
|
66730
|
-
remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1);
|
|
66731
|
-
return false;
|
|
66732
|
-
}
|
|
66733
|
-
}, this.items.length, 0);
|
|
66734
|
-
return { remaining: remaining, transform, selection: selection };
|
|
66735
|
-
}
|
|
66736
|
-
// Create a new branch with the given transform added.
|
|
66737
|
-
addTransform(transform, selection, histOptions, preserveItems) {
|
|
66738
|
-
let newItems = [], eventCount = this.eventCount;
|
|
66739
|
-
let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
|
|
66740
|
-
for (let i = 0; i < transform.steps.length; i++) {
|
|
66741
|
-
let step = transform.steps[i].invert(transform.docs[i]);
|
|
66742
|
-
let item = new Item(transform.mapping.maps[i], step, selection), merged;
|
|
66743
|
-
if (merged = lastItem && lastItem.merge(item)) {
|
|
66744
|
-
item = merged;
|
|
66745
|
-
if (i)
|
|
66746
|
-
newItems.pop();
|
|
66747
|
-
else
|
|
66748
|
-
oldItems = oldItems.slice(0, oldItems.length - 1);
|
|
66749
|
-
}
|
|
66750
|
-
newItems.push(item);
|
|
66751
|
-
if (selection) {
|
|
66752
|
-
eventCount++;
|
|
66753
|
-
selection = undefined;
|
|
66754
|
-
}
|
|
66755
|
-
if (!preserveItems)
|
|
66756
|
-
lastItem = item;
|
|
66757
|
-
}
|
|
66758
|
-
let overflow = eventCount - histOptions.depth;
|
|
66759
|
-
if (overflow > DEPTH_OVERFLOW) {
|
|
66760
|
-
oldItems = cutOffEvents(oldItems, overflow);
|
|
66761
|
-
eventCount -= overflow;
|
|
66762
|
-
}
|
|
66763
|
-
return new Branch(oldItems.append(newItems), eventCount);
|
|
66764
|
-
}
|
|
66765
|
-
remapping(from, to) {
|
|
66766
|
-
let maps = new Mapping;
|
|
66767
|
-
this.items.forEach((item, i) => {
|
|
66768
|
-
let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from
|
|
66769
|
-
? maps.maps.length - item.mirrorOffset : undefined;
|
|
66770
|
-
maps.appendMap(item.map, mirrorPos);
|
|
66771
|
-
}, from, to);
|
|
66772
|
-
return maps;
|
|
66773
|
-
}
|
|
66774
|
-
addMaps(array) {
|
|
66775
|
-
if (this.eventCount == 0)
|
|
66776
|
-
return this;
|
|
66777
|
-
return new Branch(this.items.append(array.map(map => new Item(map))), this.eventCount);
|
|
66778
|
-
}
|
|
66779
|
-
// When the collab module receives remote changes, the history has
|
|
66780
|
-
// to know about those, so that it can adjust the steps that were
|
|
66781
|
-
// rebased on top of the remote changes, and include the position
|
|
66782
|
-
// maps for the remote changes in its array of items.
|
|
66783
|
-
rebased(rebasedTransform, rebasedCount) {
|
|
66784
|
-
if (!this.eventCount)
|
|
66785
|
-
return this;
|
|
66786
|
-
let rebasedItems = [], start = Math.max(0, this.items.length - rebasedCount);
|
|
66787
|
-
let mapping = rebasedTransform.mapping;
|
|
66788
|
-
let newUntil = rebasedTransform.steps.length;
|
|
66789
|
-
let eventCount = this.eventCount;
|
|
66790
|
-
this.items.forEach(item => { if (item.selection)
|
|
66791
|
-
eventCount--; }, start);
|
|
66792
|
-
let iRebased = rebasedCount;
|
|
66793
|
-
this.items.forEach(item => {
|
|
66794
|
-
let pos = mapping.getMirror(--iRebased);
|
|
66795
|
-
if (pos == null)
|
|
66796
|
-
return;
|
|
66797
|
-
newUntil = Math.min(newUntil, pos);
|
|
66798
|
-
let map = mapping.maps[pos];
|
|
66799
|
-
if (item.step) {
|
|
66800
|
-
let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);
|
|
66801
|
-
let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
|
|
66802
|
-
if (selection)
|
|
66803
|
-
eventCount++;
|
|
66804
|
-
rebasedItems.push(new Item(map, step, selection));
|
|
66805
|
-
}
|
|
66806
|
-
else {
|
|
66807
|
-
rebasedItems.push(new Item(map));
|
|
66808
|
-
}
|
|
66809
|
-
}, start);
|
|
66810
|
-
let newMaps = [];
|
|
66811
|
-
for (let i = rebasedCount; i < newUntil; i++)
|
|
66812
|
-
newMaps.push(new Item(mapping.maps[i]));
|
|
66813
|
-
let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
|
|
66814
|
-
let branch = new Branch(items, eventCount);
|
|
66815
|
-
if (branch.emptyItemCount() > max_empty_items)
|
|
66816
|
-
branch = branch.compress(this.items.length - rebasedItems.length);
|
|
66817
|
-
return branch;
|
|
66909
|
+
class DropCursorView {
|
|
66910
|
+
constructor(editorView, options) {
|
|
66911
|
+
var _a;
|
|
66912
|
+
this.editorView = editorView;
|
|
66913
|
+
this.cursorPos = null;
|
|
66914
|
+
this.element = null;
|
|
66915
|
+
this.timeout = -1;
|
|
66916
|
+
this.lastDragEvent = null;
|
|
66917
|
+
this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1;
|
|
66918
|
+
this.color = options.color === false ? undefined : (options.color || "black");
|
|
66919
|
+
this.class = options.class;
|
|
66920
|
+
this.handlers = ["dragover", "dragend", "drop", "dragleave"].map(name => {
|
|
66921
|
+
let handler = (e) => { this[name](e); };
|
|
66922
|
+
editorView.dom.addEventListener(name, handler);
|
|
66923
|
+
return { name, handler };
|
|
66924
|
+
});
|
|
66818
66925
|
}
|
|
66819
|
-
|
|
66820
|
-
|
|
66821
|
-
this.
|
|
66822
|
-
count++; });
|
|
66823
|
-
return count;
|
|
66926
|
+
destroy() {
|
|
66927
|
+
this.setCursor(null);
|
|
66928
|
+
this.handlers.forEach(({ name, handler }) => this.editorView.dom.removeEventListener(name, handler));
|
|
66824
66929
|
}
|
|
66825
|
-
|
|
66826
|
-
|
|
66827
|
-
|
|
66828
|
-
|
|
66829
|
-
|
|
66830
|
-
|
|
66831
|
-
|
|
66832
|
-
|
|
66833
|
-
|
|
66834
|
-
|
|
66835
|
-
if (i >= upto) {
|
|
66836
|
-
items.push(item);
|
|
66837
|
-
if (item.selection)
|
|
66838
|
-
events++;
|
|
66930
|
+
update(editorView, prevState) {
|
|
66931
|
+
if (this.cursorPos != null && prevState.doc != editorView.state.doc) {
|
|
66932
|
+
// if we currently have an on-going drag event
|
|
66933
|
+
// we need to update the cursor position again and update the overlay
|
|
66934
|
+
if (this.lastDragEvent) {
|
|
66935
|
+
let target = this.computeTarget(this.lastDragEvent);
|
|
66936
|
+
if (target == this.cursorPos)
|
|
66937
|
+
this.updateOverlay();
|
|
66938
|
+
else
|
|
66939
|
+
this.setCursor(target);
|
|
66839
66940
|
}
|
|
66840
|
-
else
|
|
66841
|
-
|
|
66842
|
-
|
|
66843
|
-
|
|
66844
|
-
|
|
66845
|
-
|
|
66846
|
-
|
|
66847
|
-
|
|
66848
|
-
|
|
66849
|
-
|
|
66850
|
-
|
|
66851
|
-
|
|
66852
|
-
|
|
66853
|
-
|
|
66941
|
+
else {
|
|
66942
|
+
this.updateOverlay();
|
|
66943
|
+
}
|
|
66944
|
+
}
|
|
66945
|
+
}
|
|
66946
|
+
setCursor(pos) {
|
|
66947
|
+
if (pos == this.cursorPos)
|
|
66948
|
+
return;
|
|
66949
|
+
this.cursorPos = pos;
|
|
66950
|
+
if (pos == null) {
|
|
66951
|
+
this.element.parentNode.removeChild(this.element);
|
|
66952
|
+
this.element = null;
|
|
66953
|
+
}
|
|
66954
|
+
else {
|
|
66955
|
+
this.updateOverlay();
|
|
66956
|
+
}
|
|
66957
|
+
}
|
|
66958
|
+
updateOverlay() {
|
|
66959
|
+
let $pos = this.editorView.state.doc.resolve(this.cursorPos);
|
|
66960
|
+
let isBlock = !$pos.parent.inlineContent, rect;
|
|
66961
|
+
let editorDOM = this.editorView.dom, editorRect = editorDOM.getBoundingClientRect();
|
|
66962
|
+
let scaleX = editorRect.width / editorDOM.offsetWidth, scaleY = editorRect.height / editorDOM.offsetHeight;
|
|
66963
|
+
if (isBlock) {
|
|
66964
|
+
let before = $pos.nodeBefore, after = $pos.nodeAfter;
|
|
66965
|
+
if (before || after) {
|
|
66966
|
+
let node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0));
|
|
66967
|
+
if (node) {
|
|
66968
|
+
let nodeRect = node.getBoundingClientRect();
|
|
66969
|
+
let top = before ? nodeRect.bottom : nodeRect.top;
|
|
66970
|
+
if (before && after)
|
|
66971
|
+
top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2;
|
|
66972
|
+
let halfWidth = (this.width / 2) * scaleY;
|
|
66973
|
+
rect = { left: nodeRect.left, right: nodeRect.right, top: top - halfWidth, bottom: top + halfWidth };
|
|
66854
66974
|
}
|
|
66855
66975
|
}
|
|
66856
|
-
|
|
66857
|
-
|
|
66976
|
+
}
|
|
66977
|
+
if (!rect) {
|
|
66978
|
+
let coords = this.editorView.coordsAtPos(this.cursorPos);
|
|
66979
|
+
let halfWidth = (this.width / 2) * scaleX;
|
|
66980
|
+
rect = { left: coords.left - halfWidth, right: coords.left + halfWidth, top: coords.top, bottom: coords.bottom };
|
|
66981
|
+
}
|
|
66982
|
+
let parent = this.editorView.dom.offsetParent;
|
|
66983
|
+
if (!this.element) {
|
|
66984
|
+
this.element = parent.appendChild(document.createElement("div"));
|
|
66985
|
+
if (this.class)
|
|
66986
|
+
this.element.className = this.class;
|
|
66987
|
+
this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;";
|
|
66988
|
+
if (this.color) {
|
|
66989
|
+
this.element.style.backgroundColor = this.color;
|
|
66858
66990
|
}
|
|
66859
|
-
}
|
|
66860
|
-
|
|
66991
|
+
}
|
|
66992
|
+
this.element.classList.toggle("prosemirror-dropcursor-block", isBlock);
|
|
66993
|
+
this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock);
|
|
66994
|
+
let parentLeft, parentTop;
|
|
66995
|
+
if (!parent || parent == document.body && getComputedStyle(parent).position == "static") {
|
|
66996
|
+
parentLeft = -pageXOffset;
|
|
66997
|
+
parentTop = -pageYOffset;
|
|
66998
|
+
}
|
|
66999
|
+
else {
|
|
67000
|
+
let rect = parent.getBoundingClientRect();
|
|
67001
|
+
let parentScaleX = rect.width / parent.offsetWidth, parentScaleY = rect.height / parent.offsetHeight;
|
|
67002
|
+
parentLeft = rect.left - parent.scrollLeft * parentScaleX;
|
|
67003
|
+
parentTop = rect.top - parent.scrollTop * parentScaleY;
|
|
67004
|
+
}
|
|
67005
|
+
this.element.style.left = (rect.left - parentLeft) / scaleX + "px";
|
|
67006
|
+
this.element.style.top = (rect.top - parentTop) / scaleY + "px";
|
|
67007
|
+
this.element.style.width = (rect.right - rect.left) / scaleX + "px";
|
|
67008
|
+
this.element.style.height = (rect.bottom - rect.top) / scaleY + "px";
|
|
66861
67009
|
}
|
|
66862
|
-
|
|
66863
|
-
|
|
66864
|
-
|
|
66865
|
-
|
|
66866
|
-
|
|
66867
|
-
|
|
66868
|
-
|
|
66869
|
-
|
|
67010
|
+
scheduleRemoval(timeout) {
|
|
67011
|
+
clearTimeout(this.timeout);
|
|
67012
|
+
this.timeout = setTimeout(() => this.setCursor(null), timeout);
|
|
67013
|
+
}
|
|
67014
|
+
computeTarget(event) {
|
|
67015
|
+
let pos = this.editorView.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
67016
|
+
let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);
|
|
67017
|
+
let disableDropCursor = node && node.type.spec.disableDropCursor;
|
|
67018
|
+
let disabled = typeof disableDropCursor == "function"
|
|
67019
|
+
? disableDropCursor(this.editorView, pos, event)
|
|
67020
|
+
: disableDropCursor;
|
|
67021
|
+
if (!pos || disabled)
|
|
67022
|
+
return null;
|
|
67023
|
+
let target = pos.pos;
|
|
67024
|
+
if (this.editorView.dragging && this.editorView.dragging.slice) {
|
|
67025
|
+
let point = dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice);
|
|
67026
|
+
if (point != null)
|
|
67027
|
+
target = point;
|
|
66870
67028
|
}
|
|
66871
|
-
|
|
66872
|
-
return items.slice(cutPoint);
|
|
66873
|
-
}
|
|
66874
|
-
class Item {
|
|
66875
|
-
constructor(
|
|
66876
|
-
// The (forward) step map for this item.
|
|
66877
|
-
map,
|
|
66878
|
-
// The inverted step
|
|
66879
|
-
step,
|
|
66880
|
-
// If this is non-null, this item is the start of a group, and
|
|
66881
|
-
// this selection is the starting selection for the group (the one
|
|
66882
|
-
// that was active before the first step was applied)
|
|
66883
|
-
selection,
|
|
66884
|
-
// If this item is the inverse of a previous mapping on the stack,
|
|
66885
|
-
// this points at the inverse's offset
|
|
66886
|
-
mirrorOffset) {
|
|
66887
|
-
this.map = map;
|
|
66888
|
-
this.step = step;
|
|
66889
|
-
this.selection = selection;
|
|
66890
|
-
this.mirrorOffset = mirrorOffset;
|
|
67029
|
+
return target;
|
|
66891
67030
|
}
|
|
66892
|
-
|
|
66893
|
-
if (this.
|
|
66894
|
-
|
|
66895
|
-
|
|
66896
|
-
|
|
67031
|
+
dragover(event) {
|
|
67032
|
+
if (!this.editorView.editable)
|
|
67033
|
+
return;
|
|
67034
|
+
this.lastDragEvent = event;
|
|
67035
|
+
let target = this.computeTarget(event);
|
|
67036
|
+
if (target != null) {
|
|
67037
|
+
this.setCursor(target);
|
|
67038
|
+
this.scheduleRemoval(5000);
|
|
66897
67039
|
}
|
|
66898
67040
|
}
|
|
66899
|
-
|
|
66900
|
-
|
|
66901
|
-
|
|
66902
|
-
|
|
66903
|
-
|
|
66904
|
-
|
|
66905
|
-
|
|
66906
|
-
this.
|
|
66907
|
-
|
|
66908
|
-
this.prevTime = prevTime;
|
|
66909
|
-
this.prevComposition = prevComposition;
|
|
67041
|
+
dragend() {
|
|
67042
|
+
this.scheduleRemoval(20);
|
|
67043
|
+
}
|
|
67044
|
+
drop() {
|
|
67045
|
+
this.scheduleRemoval(20);
|
|
67046
|
+
}
|
|
67047
|
+
dragleave(event) {
|
|
67048
|
+
if (!this.editorView.dom.contains(event.relatedTarget))
|
|
67049
|
+
this.setCursor(null);
|
|
66910
67050
|
}
|
|
66911
67051
|
}
|
|
66912
|
-
|
|
66913
|
-
|
|
66914
|
-
|
|
66915
|
-
|
|
66916
|
-
|
|
66917
|
-
|
|
66918
|
-
|
|
66919
|
-
|
|
66920
|
-
|
|
66921
|
-
|
|
66922
|
-
|
|
67052
|
+
|
|
67053
|
+
/**
|
|
67054
|
+
Gap cursor selections are represented using this class. Its
|
|
67055
|
+
`$anchor` and `$head` properties both point at the cursor position.
|
|
67056
|
+
*/
|
|
67057
|
+
class GapCursor extends Selection$2 {
|
|
67058
|
+
/**
|
|
67059
|
+
Create a gap cursor.
|
|
67060
|
+
*/
|
|
67061
|
+
constructor($pos) {
|
|
67062
|
+
super($pos, $pos);
|
|
66923
67063
|
}
|
|
66924
|
-
|
|
66925
|
-
|
|
66926
|
-
|
|
66927
|
-
else
|
|
66928
|
-
return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);
|
|
67064
|
+
map(doc, mapping) {
|
|
67065
|
+
let $pos = doc.resolve(mapping.map(this.head));
|
|
67066
|
+
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$2.near($pos);
|
|
66929
67067
|
}
|
|
66930
|
-
|
|
66931
|
-
|
|
66932
|
-
|
|
66933
|
-
let newGroup = history.prevTime == 0 ||
|
|
66934
|
-
(!appended && history.prevComposition != composition &&
|
|
66935
|
-
(history.prevTime < (tr.time || 0) - options.newGroupDelay || !isAdjacentTo(tr, history.prevRanges)));
|
|
66936
|
-
let prevRanges = appended ? mapRanges(history.prevRanges, tr.mapping) : rangesFor(tr.mapping.maps);
|
|
66937
|
-
return new HistoryState(history.done.addTransform(tr, newGroup ? state.selection.getBookmark() : undefined, options, mustPreserveItems(state)), Branch.empty, prevRanges, tr.time, composition == null ? history.prevComposition : composition);
|
|
67068
|
+
content() { return Slice.empty; }
|
|
67069
|
+
eq(other) {
|
|
67070
|
+
return other instanceof GapCursor && other.head == this.head;
|
|
66938
67071
|
}
|
|
66939
|
-
|
|
66940
|
-
|
|
66941
|
-
// content has been rebased.
|
|
66942
|
-
return new HistoryState(history.done.rebased(tr, rebased), history.undone.rebased(tr, rebased), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
|
67072
|
+
toJSON() {
|
|
67073
|
+
return { type: "gapcursor", pos: this.head };
|
|
66943
67074
|
}
|
|
66944
|
-
|
|
66945
|
-
|
|
67075
|
+
/**
|
|
67076
|
+
@internal
|
|
67077
|
+
*/
|
|
67078
|
+
static fromJSON(doc, json) {
|
|
67079
|
+
if (typeof json.pos != "number")
|
|
67080
|
+
throw new RangeError("Invalid input for GapCursor.fromJSON");
|
|
67081
|
+
return new GapCursor(doc.resolve(json.pos));
|
|
67082
|
+
}
|
|
67083
|
+
/**
|
|
67084
|
+
@internal
|
|
67085
|
+
*/
|
|
67086
|
+
getBookmark() { return new GapBookmark(this.anchor); }
|
|
67087
|
+
/**
|
|
67088
|
+
@internal
|
|
67089
|
+
*/
|
|
67090
|
+
static valid($pos) {
|
|
67091
|
+
let parent = $pos.parent;
|
|
67092
|
+
if (parent.inlineContent || !closedBefore($pos) || !closedAfter($pos))
|
|
67093
|
+
return false;
|
|
67094
|
+
let override = parent.type.spec.allowGapCursor;
|
|
67095
|
+
if (override != null)
|
|
67096
|
+
return override;
|
|
67097
|
+
let deflt = parent.contentMatchAt($pos.index()).defaultType;
|
|
67098
|
+
return deflt && deflt.isTextblock;
|
|
67099
|
+
}
|
|
67100
|
+
/**
|
|
67101
|
+
@internal
|
|
67102
|
+
*/
|
|
67103
|
+
static findGapCursorFrom($pos, dir, mustMove = false) {
|
|
67104
|
+
search: for (;;) {
|
|
67105
|
+
if (!mustMove && GapCursor.valid($pos))
|
|
67106
|
+
return $pos;
|
|
67107
|
+
let pos = $pos.pos, next = null;
|
|
67108
|
+
// Scan up from this position
|
|
67109
|
+
for (let d = $pos.depth;; d--) {
|
|
67110
|
+
let parent = $pos.node(d);
|
|
67111
|
+
if (dir > 0 ? $pos.indexAfter(d) < parent.childCount : $pos.index(d) > 0) {
|
|
67112
|
+
next = parent.child(dir > 0 ? $pos.indexAfter(d) : $pos.index(d) - 1);
|
|
67113
|
+
break;
|
|
67114
|
+
}
|
|
67115
|
+
else if (d == 0) {
|
|
67116
|
+
return null;
|
|
67117
|
+
}
|
|
67118
|
+
pos += dir;
|
|
67119
|
+
let $cur = $pos.doc.resolve(pos);
|
|
67120
|
+
if (GapCursor.valid($cur))
|
|
67121
|
+
return $cur;
|
|
67122
|
+
}
|
|
67123
|
+
// And then down into the next node
|
|
67124
|
+
for (;;) {
|
|
67125
|
+
let inside = dir > 0 ? next.firstChild : next.lastChild;
|
|
67126
|
+
if (!inside) {
|
|
67127
|
+
if (next.isAtom && !next.isText && !NodeSelection.isSelectable(next)) {
|
|
67128
|
+
$pos = $pos.doc.resolve(pos + next.nodeSize * dir);
|
|
67129
|
+
mustMove = false;
|
|
67130
|
+
continue search;
|
|
67131
|
+
}
|
|
67132
|
+
break;
|
|
67133
|
+
}
|
|
67134
|
+
next = inside;
|
|
67135
|
+
pos += dir;
|
|
67136
|
+
let $cur = $pos.doc.resolve(pos);
|
|
67137
|
+
if (GapCursor.valid($cur))
|
|
67138
|
+
return $cur;
|
|
67139
|
+
}
|
|
67140
|
+
return null;
|
|
67141
|
+
}
|
|
66946
67142
|
}
|
|
66947
67143
|
}
|
|
66948
|
-
|
|
66949
|
-
|
|
66950
|
-
|
|
66951
|
-
|
|
66952
|
-
|
|
66953
|
-
|
|
66954
|
-
|
|
66955
|
-
|
|
66956
|
-
|
|
66957
|
-
|
|
66958
|
-
|
|
66959
|
-
|
|
67144
|
+
GapCursor.prototype.visible = false;
|
|
67145
|
+
GapCursor.findFrom = GapCursor.findGapCursorFrom;
|
|
67146
|
+
Selection$2.jsonID("gapcursor", GapCursor);
|
|
67147
|
+
class GapBookmark {
|
|
67148
|
+
constructor(pos) {
|
|
67149
|
+
this.pos = pos;
|
|
67150
|
+
}
|
|
67151
|
+
map(mapping) {
|
|
67152
|
+
return new GapBookmark(mapping.map(this.pos));
|
|
67153
|
+
}
|
|
67154
|
+
resolve(doc) {
|
|
67155
|
+
let $pos = doc.resolve(this.pos);
|
|
67156
|
+
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$2.near($pos);
|
|
67157
|
+
}
|
|
66960
67158
|
}
|
|
66961
|
-
function
|
|
66962
|
-
|
|
66963
|
-
for (let i = maps.length - 1; i >= 0 && result.length == 0; i--)
|
|
66964
|
-
maps[i].forEach((_from, _to, from, to) => result.push(from, to));
|
|
66965
|
-
return result;
|
|
67159
|
+
function needsGap(type) {
|
|
67160
|
+
return type.isAtom || type.spec.isolating || type.spec.createGapCursor;
|
|
66966
67161
|
}
|
|
66967
|
-
function
|
|
66968
|
-
|
|
66969
|
-
|
|
66970
|
-
|
|
66971
|
-
|
|
66972
|
-
|
|
66973
|
-
|
|
66974
|
-
|
|
67162
|
+
function closedBefore($pos) {
|
|
67163
|
+
for (let d = $pos.depth; d >= 0; d--) {
|
|
67164
|
+
let index = $pos.index(d), parent = $pos.node(d);
|
|
67165
|
+
// At the start of this parent, look at next one
|
|
67166
|
+
if (index == 0) {
|
|
67167
|
+
if (parent.type.spec.isolating)
|
|
67168
|
+
return true;
|
|
67169
|
+
continue;
|
|
67170
|
+
}
|
|
67171
|
+
// See if the node before (or its first ancestor) is closed
|
|
67172
|
+
for (let before = parent.child(index - 1);; before = before.lastChild) {
|
|
67173
|
+
if ((before.childCount == 0 && !before.inlineContent) || needsGap(before.type))
|
|
67174
|
+
return true;
|
|
67175
|
+
if (before.inlineContent)
|
|
67176
|
+
return false;
|
|
67177
|
+
}
|
|
66975
67178
|
}
|
|
66976
|
-
|
|
66977
|
-
|
|
66978
|
-
// Apply the latest event from one branch to the document and shift the event
|
|
66979
|
-
// onto the other branch.
|
|
66980
|
-
function histTransaction(history, state, redo) {
|
|
66981
|
-
let preserveItems = mustPreserveItems(state);
|
|
66982
|
-
let histOptions = historyKey.get(state).spec.config;
|
|
66983
|
-
let pop = (redo ? history.undone : history.done).popEvent(state, preserveItems);
|
|
66984
|
-
if (!pop)
|
|
66985
|
-
return null;
|
|
66986
|
-
let selection = pop.selection.resolve(pop.transform.doc);
|
|
66987
|
-
let added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);
|
|
66988
|
-
let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1);
|
|
66989
|
-
return pop.transform.setSelection(selection).setMeta(historyKey, { redo, historyState: newHist });
|
|
67179
|
+
// Hit start of document
|
|
67180
|
+
return true;
|
|
66990
67181
|
}
|
|
66991
|
-
|
|
66992
|
-
|
|
66993
|
-
|
|
66994
|
-
|
|
66995
|
-
|
|
66996
|
-
|
|
66997
|
-
|
|
66998
|
-
|
|
66999
|
-
|
|
67000
|
-
|
|
67001
|
-
|
|
67002
|
-
if (
|
|
67003
|
-
|
|
67004
|
-
|
|
67005
|
-
}
|
|
67182
|
+
function closedAfter($pos) {
|
|
67183
|
+
for (let d = $pos.depth; d >= 0; d--) {
|
|
67184
|
+
let index = $pos.indexAfter(d), parent = $pos.node(d);
|
|
67185
|
+
if (index == parent.childCount) {
|
|
67186
|
+
if (parent.type.spec.isolating)
|
|
67187
|
+
return true;
|
|
67188
|
+
continue;
|
|
67189
|
+
}
|
|
67190
|
+
for (let after = parent.child(index);; after = after.firstChild) {
|
|
67191
|
+
if ((after.childCount == 0 && !after.inlineContent) || needsGap(after.type))
|
|
67192
|
+
return true;
|
|
67193
|
+
if (after.inlineContent)
|
|
67194
|
+
return false;
|
|
67195
|
+
}
|
|
67006
67196
|
}
|
|
67007
|
-
return
|
|
67197
|
+
return true;
|
|
67008
67198
|
}
|
|
67009
|
-
const historyKey = new PluginKey("history");
|
|
67010
|
-
const closeHistoryKey = new PluginKey("closeHistory");
|
|
67011
|
-
/**
|
|
67012
|
-
Returns a plugin that enables the undo history for an editor. The
|
|
67013
|
-
plugin will track undo and redo stacks, which can be used with the
|
|
67014
|
-
[`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.
|
|
67015
67199
|
|
|
67016
|
-
|
|
67017
|
-
|
|
67018
|
-
|
|
67200
|
+
/**
|
|
67201
|
+
Create a gap cursor plugin. When enabled, this will capture clicks
|
|
67202
|
+
near and arrow-key-motion past places that don't have a normally
|
|
67203
|
+
selectable position nearby, and create a gap cursor selection for
|
|
67204
|
+
them. The cursor is drawn as an element with class
|
|
67205
|
+
`ProseMirror-gapcursor`. You can either include
|
|
67206
|
+
`style/gapcursor.css` from the package's directory or add your own
|
|
67207
|
+
styles to make it visible.
|
|
67019
67208
|
*/
|
|
67020
|
-
function
|
|
67021
|
-
config = { depth: config.depth || 100,
|
|
67022
|
-
newGroupDelay: config.newGroupDelay || 500 };
|
|
67209
|
+
function gapCursor() {
|
|
67023
67210
|
return new Plugin({
|
|
67024
|
-
key: historyKey,
|
|
67025
|
-
state: {
|
|
67026
|
-
init() {
|
|
67027
|
-
return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);
|
|
67028
|
-
},
|
|
67029
|
-
apply(tr, hist, state) {
|
|
67030
|
-
return applyTransaction(hist, state, tr, config);
|
|
67031
|
-
}
|
|
67032
|
-
},
|
|
67033
|
-
config,
|
|
67034
67211
|
props: {
|
|
67035
|
-
|
|
67036
|
-
|
|
67037
|
-
|
|
67038
|
-
|
|
67039
|
-
|
|
67040
|
-
|
|
67041
|
-
|
|
67042
|
-
return command(view.state, view.dispatch);
|
|
67043
|
-
}
|
|
67044
|
-
}
|
|
67212
|
+
decorations: drawGapCursor,
|
|
67213
|
+
createSelectionBetween(_view, $anchor, $head) {
|
|
67214
|
+
return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null;
|
|
67215
|
+
},
|
|
67216
|
+
handleClick,
|
|
67217
|
+
handleKeyDown,
|
|
67218
|
+
handleDOMEvents: { beforeinput: beforeinput }
|
|
67045
67219
|
}
|
|
67046
67220
|
});
|
|
67047
67221
|
}
|
|
67048
|
-
|
|
67049
|
-
|
|
67050
|
-
|
|
67051
|
-
|
|
67052
|
-
|
|
67053
|
-
|
|
67054
|
-
|
|
67055
|
-
|
|
67056
|
-
|
|
67222
|
+
const handleKeyDown = keydownHandler({
|
|
67223
|
+
"ArrowLeft": arrow("horiz", -1),
|
|
67224
|
+
"ArrowRight": arrow("horiz", 1),
|
|
67225
|
+
"ArrowUp": arrow("vert", -1),
|
|
67226
|
+
"ArrowDown": arrow("vert", 1)
|
|
67227
|
+
});
|
|
67228
|
+
function arrow(axis, dir) {
|
|
67229
|
+
const dirStr = axis == "vert" ? (dir > 0 ? "down" : "up") : (dir > 0 ? "right" : "left");
|
|
67230
|
+
return function (state, dispatch, view) {
|
|
67231
|
+
let sel = state.selection;
|
|
67232
|
+
let $start = dir > 0 ? sel.$to : sel.$from, mustMove = sel.empty;
|
|
67233
|
+
if (sel instanceof TextSelection) {
|
|
67234
|
+
if (!view.endOfTextblock(dirStr) || $start.depth == 0)
|
|
67235
|
+
return false;
|
|
67236
|
+
mustMove = false;
|
|
67237
|
+
$start = state.doc.resolve(dir > 0 ? $start.after() : $start.before());
|
|
67057
67238
|
}
|
|
67239
|
+
let $found = GapCursor.findGapCursorFrom($start, dir, mustMove);
|
|
67240
|
+
if (!$found)
|
|
67241
|
+
return false;
|
|
67242
|
+
if (dispatch)
|
|
67243
|
+
dispatch(state.tr.setSelection(new GapCursor($found)));
|
|
67058
67244
|
return true;
|
|
67059
67245
|
};
|
|
67060
67246
|
}
|
|
67061
|
-
|
|
67062
|
-
|
|
67063
|
-
|
|
67064
|
-
|
|
67065
|
-
|
|
67066
|
-
|
|
67067
|
-
|
|
67068
|
-
|
|
67247
|
+
function handleClick(view, pos, event) {
|
|
67248
|
+
if (!view || !view.editable)
|
|
67249
|
+
return false;
|
|
67250
|
+
let $pos = view.state.doc.resolve(pos);
|
|
67251
|
+
if (!GapCursor.valid($pos))
|
|
67252
|
+
return false;
|
|
67253
|
+
let clickPos = view.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
67254
|
+
if (clickPos && clickPos.inside > -1 && NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside)))
|
|
67255
|
+
return false;
|
|
67256
|
+
view.dispatch(view.state.tr.setSelection(new GapCursor($pos)));
|
|
67257
|
+
return true;
|
|
67258
|
+
}
|
|
67259
|
+
// This is a hack that, when a composition starts while a gap cursor
|
|
67260
|
+
// is active, quickly creates an inline context for the composition to
|
|
67261
|
+
// happen in, to avoid it being aborted by the DOM selection being
|
|
67262
|
+
// moved into a valid position.
|
|
67263
|
+
function beforeinput(view, event) {
|
|
67264
|
+
if (event.inputType != "insertCompositionText" || !(view.state.selection instanceof GapCursor))
|
|
67265
|
+
return false;
|
|
67266
|
+
let { $from } = view.state.selection;
|
|
67267
|
+
let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text);
|
|
67268
|
+
if (!insert)
|
|
67269
|
+
return false;
|
|
67270
|
+
let frag = Fragment.empty;
|
|
67271
|
+
for (let i = insert.length - 1; i >= 0; i--)
|
|
67272
|
+
frag = Fragment.from(insert[i].createAndFill(null, frag));
|
|
67273
|
+
let tr = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0));
|
|
67274
|
+
tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + 1)));
|
|
67275
|
+
view.dispatch(tr);
|
|
67276
|
+
return false;
|
|
67277
|
+
}
|
|
67278
|
+
function drawGapCursor(state) {
|
|
67279
|
+
if (!(state.selection instanceof GapCursor))
|
|
67280
|
+
return null;
|
|
67281
|
+
let node = document.createElement("div");
|
|
67282
|
+
node.className = "ProseMirror-gapcursor";
|
|
67283
|
+
return DecorationSet.create(state.doc, [Decoration.widget(state.selection.head, node, { key: "gapcursor" })]);
|
|
67284
|
+
}
|
|
67069
67285
|
|
|
67070
67286
|
//#region src/character-count/character-count.ts
|
|
67071
67287
|
/**
|
|
@@ -97660,12 +97876,12 @@ focus outline in that case.
|
|
|
97660
97876
|
toDOMStream(options) {
|
|
97661
97877
|
return streamAdapters.toDOMStream((this._closedPromiseResolve || this._error)
|
|
97662
97878
|
? this
|
|
97663
|
-
: this._values
|
|
97879
|
+
: this._values);
|
|
97664
97880
|
}
|
|
97665
97881
|
toNodeStream(options) {
|
|
97666
97882
|
return streamAdapters.toNodeStream((this._closedPromiseResolve || this._error)
|
|
97667
97883
|
? this
|
|
97668
|
-
: this._values
|
|
97884
|
+
: this._values);
|
|
97669
97885
|
}
|
|
97670
97886
|
throw(_) {
|
|
97671
97887
|
return __awaiter(this, void 0, void 0, function* () { yield this.abort(_); return ITERATOR_DONE; });
|
|
@@ -100056,7 +100272,7 @@ focus outline in that case.
|
|
|
100056
100272
|
toNodeStream() {
|
|
100057
100273
|
return streamAdapters.toNodeStream((this.isSync()
|
|
100058
100274
|
? { [Symbol.iterator]: () => this }
|
|
100059
|
-
: { [Symbol.asyncIterator]: () => this })
|
|
100275
|
+
: { [Symbol.asyncIterator]: () => this }));
|
|
100060
100276
|
}
|
|
100061
100277
|
/** @nocollapse */
|
|
100062
100278
|
// @ts-ignore
|