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