@ni/ok-components 1.10.0 → 1.10.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 +1800 -1586
- package/dist/all-components-bundle.js.map +1 -1
- package/dist/all-components-bundle.min.js +3519 -3485
- package/dist/all-components-bundle.min.js.map +1 -1
- package/dist/custom-elements.json +118 -118
- package/dist/custom-elements.md +26 -26
- package/dist/esm/fv/chip-selector/index.js +0 -4
- package/dist/esm/fv/chip-selector/index.js.map +1 -1
- package/dist/esm/fv/chip-selector/template.js +3 -1
- package/dist/esm/fv/chip-selector/template.js.map +1 -1
- package/package.json +5 -5
|
@@ -29805,7 +29805,6 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
29805
29805
|
if (!type)
|
|
29806
29806
|
throw new RangeError(`There is no mark type ${json.type} in this schema`);
|
|
29807
29807
|
let mark = type.create(json.attrs);
|
|
29808
|
-
type.checkAttrs(mark.attrs);
|
|
29809
29808
|
return mark;
|
|
29810
29809
|
}
|
|
29811
29810
|
/**
|
|
@@ -30785,11 +30784,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
30785
30784
|
*/
|
|
30786
30785
|
check() {
|
|
30787
30786
|
this.type.checkContent(this.content);
|
|
30788
|
-
this.type.
|
|
30787
|
+
checkAttrs(this.type.attrs, this.attrs, "node", this.type.name);
|
|
30789
30788
|
let copy = Mark$1.none;
|
|
30790
30789
|
for (let i = 0; i < this.marks.length; i++) {
|
|
30791
30790
|
let mark = this.marks[i];
|
|
30792
|
-
mark.type.
|
|
30791
|
+
checkAttrs(mark.type.attrs, mark.attrs, "mark", mark.type.name);
|
|
30793
30792
|
copy = mark.addToSet(copy);
|
|
30794
30793
|
}
|
|
30795
30794
|
if (!Mark$1.sameSet(copy, this.marks))
|
|
@@ -30830,7 +30829,6 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
30830
30829
|
}
|
|
30831
30830
|
let content = Fragment.fromJSON(schema, json.content);
|
|
30832
30831
|
let node = schema.nodeType(json.type).create(json.attrs, content, marks);
|
|
30833
|
-
node.type.checkAttrs(node.attrs);
|
|
30834
30832
|
return node;
|
|
30835
30833
|
}
|
|
30836
30834
|
};
|
|
@@ -30880,6 +30878,15 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
30880
30878
|
str = marks[i].type.name + "(" + str + ")";
|
|
30881
30879
|
return str;
|
|
30882
30880
|
}
|
|
30881
|
+
function checkAttrs(attrs, values, type, name) {
|
|
30882
|
+
for (let attr in values)
|
|
30883
|
+
if (!(attr in attrs))
|
|
30884
|
+
throw new RangeError(`Unsupported attribute ${attr} for ${type} of type ${name}`);
|
|
30885
|
+
for (let attr in attrs) {
|
|
30886
|
+
if (attrs[attr].validate)
|
|
30887
|
+
attrs[attr].validate(values[attr]);
|
|
30888
|
+
}
|
|
30889
|
+
}
|
|
30883
30890
|
|
|
30884
30891
|
/**
|
|
30885
30892
|
Instances of this class represent a match state of a node type's
|
|
@@ -31334,27 +31341,21 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
31334
31341
|
function computeAttrs(attrs, value) {
|
|
31335
31342
|
let built = Object.create(null);
|
|
31336
31343
|
for (let name in attrs) {
|
|
31344
|
+
let attr = attrs[name];
|
|
31337
31345
|
let given = value && value[name];
|
|
31338
31346
|
if (given === undefined) {
|
|
31339
|
-
let attr = attrs[name];
|
|
31340
31347
|
if (attr.hasDefault)
|
|
31341
31348
|
given = attr.default;
|
|
31342
31349
|
else
|
|
31343
31350
|
throw new RangeError("No value supplied for attribute " + name);
|
|
31344
31351
|
}
|
|
31352
|
+
else if (attr.validate) {
|
|
31353
|
+
attr.validate(given);
|
|
31354
|
+
}
|
|
31345
31355
|
built[name] = given;
|
|
31346
31356
|
}
|
|
31347
31357
|
return built;
|
|
31348
31358
|
}
|
|
31349
|
-
function checkAttrs(attrs, values, type, name) {
|
|
31350
|
-
for (let attr in values)
|
|
31351
|
-
if (!(attr in attrs))
|
|
31352
|
-
throw new RangeError(`Unsupported attribute ${attr} for ${type} of type ${name}`);
|
|
31353
|
-
for (let attr in attrs) {
|
|
31354
|
-
if (attrs[attr].validate)
|
|
31355
|
-
attrs[attr].validate(values[attr]);
|
|
31356
|
-
}
|
|
31357
|
-
}
|
|
31358
31359
|
function initAttrs(typeName, attrs) {
|
|
31359
31360
|
let result = Object.create(null);
|
|
31360
31361
|
if (attrs)
|
|
@@ -31526,11 +31527,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
31526
31527
|
throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`);
|
|
31527
31528
|
}
|
|
31528
31529
|
/**
|
|
31529
|
-
@internal
|
|
31530
|
+
@internal no longer useful, but called by old prosemirror-view versions
|
|
31530
31531
|
*/
|
|
31531
|
-
checkAttrs(attrs) {
|
|
31532
|
-
checkAttrs(this.attrs, attrs, "node", this.name);
|
|
31533
|
-
}
|
|
31532
|
+
checkAttrs(attrs) { }
|
|
31534
31533
|
/**
|
|
31535
31534
|
Check whether the given mark type is allowed in this node.
|
|
31536
31535
|
*/
|
|
@@ -31677,12 +31676,6 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
31677
31676
|
return set[i];
|
|
31678
31677
|
}
|
|
31679
31678
|
/**
|
|
31680
|
-
@internal
|
|
31681
|
-
*/
|
|
31682
|
-
checkAttrs(attrs) {
|
|
31683
|
-
checkAttrs(this.attrs, attrs, "mark", this.name);
|
|
31684
|
-
}
|
|
31685
|
-
/**
|
|
31686
31679
|
Queries whether a given mark type is
|
|
31687
31680
|
[excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one.
|
|
31688
31681
|
*/
|
|
@@ -32873,9 +32866,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
32873
32866
|
if (simple)
|
|
32874
32867
|
return result;
|
|
32875
32868
|
let recover = pos == (assoc < 0 ? start : end) ? null : makeRecover(i / 3, pos - start);
|
|
32876
|
-
let del =
|
|
32877
|
-
if (
|
|
32878
|
-
del |=
|
|
32869
|
+
let del = 0;
|
|
32870
|
+
if (oldSize) {
|
|
32871
|
+
del |= pos == start ? DEL_AFTER : pos == end ? DEL_BEFORE : DEL_ACROSS;
|
|
32872
|
+
if (assoc < 0 ? pos != start : pos != end)
|
|
32873
|
+
del |= DEL_SIDE;
|
|
32874
|
+
}
|
|
32879
32875
|
return new MapResult(result, del, recover);
|
|
32880
32876
|
}
|
|
32881
32877
|
diff += newSize - oldSize;
|
|
@@ -36813,15 +36809,15 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36813
36809
|
return true;
|
|
36814
36810
|
if (off == (dir < 0 ? 0 : nodeSize(node))) {
|
|
36815
36811
|
let parent = node.parentNode;
|
|
36816
|
-
if (!parent || parent
|
|
36812
|
+
if (!parent || !isElt(parent) || hasBlockDesc(node) || atomElements.test(node.nodeName) ||
|
|
36817
36813
|
node.contentEditable == "false")
|
|
36818
36814
|
return false;
|
|
36819
36815
|
off = domIndex(node) + (dir < 0 ? 0 : 1);
|
|
36820
36816
|
node = parent;
|
|
36821
36817
|
}
|
|
36822
|
-
else if (node
|
|
36818
|
+
else if (isElt(node)) {
|
|
36823
36819
|
let child = node.childNodes[off + (dir < 0 ? -1 : 0)];
|
|
36824
|
-
if (child
|
|
36820
|
+
if (isElt(child) && child.contentEditable == "false") {
|
|
36825
36821
|
if ((_a = child.pmViewDesc) === null || _a === void 0 ? void 0 : _a.ignoreForSelection)
|
|
36826
36822
|
off += dir;
|
|
36827
36823
|
else
|
|
@@ -36840,11 +36836,16 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36840
36836
|
function nodeSize(node) {
|
|
36841
36837
|
return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
|
|
36842
36838
|
}
|
|
36839
|
+
function isElt(node) { return node.nodeType == 1; }
|
|
36840
|
+
function isText(node) { return node.nodeType == 3; }
|
|
36841
|
+
function contains(parent, child) {
|
|
36842
|
+
return child ? parent.contains(isElt(child) ? child : child.parentNode) : false;
|
|
36843
|
+
}
|
|
36843
36844
|
function textNodeBefore$1(node, offset) {
|
|
36844
36845
|
for (;;) {
|
|
36845
|
-
if (node
|
|
36846
|
+
if (isText(node) && offset)
|
|
36846
36847
|
return node;
|
|
36847
|
-
if (node
|
|
36848
|
+
if (isElt(node) && offset > 0) {
|
|
36848
36849
|
if (node.contentEditable == "false")
|
|
36849
36850
|
return null;
|
|
36850
36851
|
node = node.childNodes[offset - 1];
|
|
@@ -36861,9 +36862,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36861
36862
|
}
|
|
36862
36863
|
function textNodeAfter$1(node, offset) {
|
|
36863
36864
|
for (;;) {
|
|
36864
|
-
if (node
|
|
36865
|
+
if (isText(node) && offset < node.nodeValue.length)
|
|
36865
36866
|
return node;
|
|
36866
|
-
if (node
|
|
36867
|
+
if (isElt(node) && offset < node.childNodes.length) {
|
|
36867
36868
|
if (node.contentEditable == "false")
|
|
36868
36869
|
return null;
|
|
36869
36870
|
node = node.childNodes[offset];
|
|
@@ -36987,13 +36988,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36987
36988
|
for (let parent = startDOM || view.dom;;) {
|
|
36988
36989
|
if (!parent)
|
|
36989
36990
|
break;
|
|
36990
|
-
if (parent
|
|
36991
|
+
if (!isElt(parent)) {
|
|
36991
36992
|
parent = parentNode(parent);
|
|
36992
36993
|
continue;
|
|
36993
36994
|
}
|
|
36994
|
-
let
|
|
36995
|
-
let
|
|
36996
|
-
let bounding = atTop ? windowRect(doc) : clientRect(elt);
|
|
36995
|
+
let atTop = parent == doc.body;
|
|
36996
|
+
let bounding = atTop ? windowRect(doc) : clientRect(parent);
|
|
36997
36997
|
let moveX = 0, moveY = 0;
|
|
36998
36998
|
if (rect.top < bounding.top + getSide$1(scrollThreshold, "top"))
|
|
36999
36999
|
moveY = -(bounding.top - rect.top + getSide$1(scrollMargin, "top"));
|
|
@@ -37010,12 +37010,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37010
37010
|
doc.defaultView.scrollBy(moveX, moveY);
|
|
37011
37011
|
}
|
|
37012
37012
|
else {
|
|
37013
|
-
let startX =
|
|
37013
|
+
let startX = parent.scrollLeft, startY = parent.scrollTop;
|
|
37014
37014
|
if (moveY)
|
|
37015
|
-
|
|
37015
|
+
parent.scrollTop += moveY;
|
|
37016
37016
|
if (moveX)
|
|
37017
|
-
|
|
37018
|
-
let dX =
|
|
37017
|
+
parent.scrollLeft += moveX;
|
|
37018
|
+
let dX = parent.scrollLeft - startX, dY = parent.scrollTop - startY;
|
|
37019
37019
|
rect = { left: rect.left - dX, top: rect.top - dY, right: rect.right - dX, bottom: rect.bottom - dY };
|
|
37020
37020
|
}
|
|
37021
37021
|
}
|
|
@@ -37090,14 +37090,15 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37090
37090
|
}
|
|
37091
37091
|
}
|
|
37092
37092
|
function findOffsetInNode(node, coords) {
|
|
37093
|
-
let closest
|
|
37093
|
+
let closest;
|
|
37094
|
+
let dxClosest = 2e8, coordsClosest, offset = 0;
|
|
37094
37095
|
let rowBot = coords.top, rowTop = coords.top;
|
|
37095
37096
|
let firstBelow, coordsBelow;
|
|
37096
37097
|
for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {
|
|
37097
37098
|
let rects;
|
|
37098
|
-
if (child
|
|
37099
|
+
if (isElt(child))
|
|
37099
37100
|
rects = child.getClientRects();
|
|
37100
|
-
else if (child
|
|
37101
|
+
else if (isText(child))
|
|
37101
37102
|
rects = textRange(child).getClientRects();
|
|
37102
37103
|
else
|
|
37103
37104
|
continue;
|
|
@@ -37111,11 +37112,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37111
37112
|
if (dx < dxClosest) {
|
|
37112
37113
|
closest = child;
|
|
37113
37114
|
dxClosest = dx;
|
|
37114
|
-
coordsClosest = dx && closest
|
|
37115
|
+
coordsClosest = dx && isText(closest) ? {
|
|
37115
37116
|
left: rect.right < coords.left ? rect.right : rect.left,
|
|
37116
37117
|
top: coords.top
|
|
37117
37118
|
} : coords;
|
|
37118
|
-
if (child
|
|
37119
|
+
if (isElt(child) && dx)
|
|
37119
37120
|
offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);
|
|
37120
37121
|
continue;
|
|
37121
37122
|
}
|
|
@@ -37134,9 +37135,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37134
37135
|
coordsClosest = coordsBelow;
|
|
37135
37136
|
dxClosest = 0;
|
|
37136
37137
|
}
|
|
37137
|
-
if (closest && closest
|
|
37138
|
+
if (closest && isText(closest))
|
|
37138
37139
|
return findOffsetInText(closest, coordsClosest);
|
|
37139
|
-
if (!closest ||
|
|
37140
|
+
if (!closest || dxClosest)
|
|
37140
37141
|
return { node, offset };
|
|
37141
37142
|
return findOffsetInNode(closest, coordsClosest);
|
|
37142
37143
|
}
|
|
@@ -37169,7 +37170,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37169
37170
|
}
|
|
37170
37171
|
function posFromElement(view, elt, coords) {
|
|
37171
37172
|
let { node, offset } = findOffsetInNode(elt, coords), bias = -1;
|
|
37172
|
-
if (node
|
|
37173
|
+
if (isElt(node) && !node.firstChild) {
|
|
37173
37174
|
let rect = node.getBoundingClientRect();
|
|
37174
37175
|
bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1;
|
|
37175
37176
|
}
|
|
@@ -37189,7 +37190,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37189
37190
|
let desc = view.docView.nearestDesc(cur, true), rect;
|
|
37190
37191
|
if (!desc)
|
|
37191
37192
|
return null;
|
|
37192
|
-
if (desc.dom
|
|
37193
|
+
if (isElt(desc.dom) && (desc.node.isBlock && desc.parent || !desc.contentDOM) &&
|
|
37193
37194
|
// Ignore elements with zero-size bounding rectangles
|
|
37194
37195
|
((rect = desc.dom.getBoundingClientRect()).width || rect.height)) {
|
|
37195
37196
|
if (desc.node.isBlock && desc.parent && !/^T(R|BODY|HEAD|FOOT)$/.test(desc.dom.nodeName)) {
|
|
@@ -37216,7 +37217,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37216
37217
|
if (len && box.top < box.bottom) {
|
|
37217
37218
|
for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) {
|
|
37218
37219
|
let child = element.childNodes[i];
|
|
37219
|
-
if (child
|
|
37220
|
+
if (isElt(child)) {
|
|
37220
37221
|
let rects = child.getClientRects();
|
|
37221
37222
|
for (let j = 0; j < rects.length; j++) {
|
|
37222
37223
|
let rect = rects[j];
|
|
@@ -37239,7 +37240,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37239
37240
|
let elt = (view.root.elementFromPoint ? view.root : doc)
|
|
37240
37241
|
.elementFromPoint(coords.left, coords.top);
|
|
37241
37242
|
let pos;
|
|
37242
|
-
if (!elt || !view.dom.contains(elt
|
|
37243
|
+
if (!elt || !view.dom.contains(elt)) {
|
|
37243
37244
|
let box = view.dom.getBoundingClientRect();
|
|
37244
37245
|
if (!inRect(coords, box))
|
|
37245
37246
|
return null;
|
|
@@ -37255,7 +37256,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37255
37256
|
}
|
|
37256
37257
|
elt = targetKludge(elt, coords);
|
|
37257
37258
|
if (node) {
|
|
37258
|
-
if (gecko && node
|
|
37259
|
+
if (gecko && isElt(node)) {
|
|
37259
37260
|
// Firefox will sometimes return offsets into <input> nodes, which
|
|
37260
37261
|
// have no actual children, from caretPositionFromPoint (#953)
|
|
37261
37262
|
offset = Math.min(offset, node.childNodes.length);
|
|
@@ -37270,18 +37271,18 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37270
37271
|
}
|
|
37271
37272
|
let prev;
|
|
37272
37273
|
// When clicking above the right side of an uneditable node, Chrome will report a cursor position after that node.
|
|
37273
|
-
if (webkit && offset && node
|
|
37274
|
+
if (webkit && offset && isElt(node) && isElt(prev = node.childNodes[offset - 1]) &&
|
|
37274
37275
|
prev.contentEditable == "false" && prev.getBoundingClientRect().top >= coords.top)
|
|
37275
37276
|
offset--;
|
|
37276
37277
|
// Suspiciously specific kludge to work around caret*FromPoint
|
|
37277
37278
|
// never returning a position at the end of the document
|
|
37278
|
-
if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild
|
|
37279
|
+
if (node == view.dom && offset == node.childNodes.length - 1 && isElt(node.lastChild) &&
|
|
37279
37280
|
coords.top > node.lastChild.getBoundingClientRect().bottom)
|
|
37280
37281
|
pos = view.state.doc.content.size;
|
|
37281
37282
|
// Ignore positions directly after a BR, since caret*FromPoint
|
|
37282
37283
|
// 'round up' positions that would be more accurately placed
|
|
37283
37284
|
// before the BR node.
|
|
37284
|
-
else if (offset == 0 || node
|
|
37285
|
+
else if (offset == 0 || !isElt(node) || node.childNodes[offset - 1].nodeName != "BR")
|
|
37285
37286
|
pos = posFromCaret(view, node, offset, coords);
|
|
37286
37287
|
}
|
|
37287
37288
|
if (pos == null)
|
|
@@ -37307,7 +37308,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37307
37308
|
function coordsAtPos(view, pos, side) {
|
|
37308
37309
|
let { node, offset, atom } = view.docView.domFromPos(pos, side < 0 ? -1 : 1);
|
|
37309
37310
|
let supportEmptyRange = webkit || gecko;
|
|
37310
|
-
if (node
|
|
37311
|
+
if (isText(node)) {
|
|
37311
37312
|
// These browsers support querying empty text ranges. Prefer that in
|
|
37312
37313
|
// bidi context or when at the end of a node.
|
|
37313
37314
|
if (supportEmptyRange && (BIDI.test(node.nodeValue) || (side < 0 ? !offset : offset == node.nodeValue.length))) {
|
|
@@ -37349,12 +37350,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37349
37350
|
if (!$dom.parent.inlineContent) {
|
|
37350
37351
|
if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
|
|
37351
37352
|
let before = node.childNodes[offset - 1];
|
|
37352
|
-
if (before
|
|
37353
|
+
if (isElt(before))
|
|
37353
37354
|
return flattenH(before.getBoundingClientRect(), false);
|
|
37354
37355
|
}
|
|
37355
37356
|
if (atom == null && offset < nodeSize(node)) {
|
|
37356
37357
|
let after = node.childNodes[offset];
|
|
37357
|
-
if (after
|
|
37358
|
+
if (isElt(after))
|
|
37358
37359
|
return flattenH(after.getBoundingClientRect(), true);
|
|
37359
37360
|
}
|
|
37360
37361
|
return flattenH(node.getBoundingClientRect(), side >= 0);
|
|
@@ -37362,10 +37363,10 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37362
37363
|
// Inline, not in text node (this is not Bidi-safe)
|
|
37363
37364
|
if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
|
|
37364
37365
|
let before = node.childNodes[offset - 1];
|
|
37365
|
-
let target = before
|
|
37366
|
+
let target = isText(before) ? textRange(before, nodeSize(before) - (supportEmptyRange ? 0 : 1))
|
|
37366
37367
|
// BR nodes tend to only return the rectangle before them.
|
|
37367
37368
|
// Only use them if they are the last element in their parent
|
|
37368
|
-
: before
|
|
37369
|
+
: isElt(before) && (before.nodeName != "BR" || !before.nextSibling) ? before : null;
|
|
37369
37370
|
if (target)
|
|
37370
37371
|
return flattenV(singleRect(target, 1), false);
|
|
37371
37372
|
}
|
|
@@ -37373,13 +37374,13 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37373
37374
|
let after = node.childNodes[offset];
|
|
37374
37375
|
while (after.pmViewDesc && after.pmViewDesc.ignoreForCoords)
|
|
37375
37376
|
after = after.nextSibling;
|
|
37376
|
-
let target = !after ? null : after
|
|
37377
|
-
: after
|
|
37377
|
+
let target = !after ? null : isText(after) ? textRange(after, 0, (supportEmptyRange ? 0 : 1))
|
|
37378
|
+
: isElt(after) ? after : null;
|
|
37378
37379
|
if (target)
|
|
37379
37380
|
return flattenV(singleRect(target, -1), true);
|
|
37380
37381
|
}
|
|
37381
37382
|
// All else failed, just try to get a rectangle for the target node
|
|
37382
|
-
return flattenV(singleRect(node
|
|
37383
|
+
return flattenV(singleRect(isText(node) ? textRange(node) : node, -side), side >= 0);
|
|
37383
37384
|
}
|
|
37384
37385
|
function flattenV(rect, left) {
|
|
37385
37386
|
if (rect.width == 0)
|
|
@@ -37429,9 +37430,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37429
37430
|
let coords = coordsAtPos(view, $pos.pos, 1);
|
|
37430
37431
|
for (let child = dom.firstChild; child; child = child.nextSibling) {
|
|
37431
37432
|
let boxes;
|
|
37432
|
-
if (child
|
|
37433
|
+
if (isElt(child))
|
|
37433
37434
|
boxes = child.getClientRects();
|
|
37434
|
-
else if (child
|
|
37435
|
+
else if (isText(child))
|
|
37435
37436
|
boxes = textRange(child, 0, child.nodeValue.length).getClientRects();
|
|
37436
37437
|
else
|
|
37437
37438
|
continue;
|
|
@@ -37471,8 +37472,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37471
37472
|
sel.modify("move", dir, "character");
|
|
37472
37473
|
let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom;
|
|
37473
37474
|
let { focusNode: newNode, focusOffset: newOff } = view.domSelectionRange();
|
|
37474
|
-
let result = newNode && !
|
|
37475
|
-
(oldNode == newNode && oldOff == newOff);
|
|
37475
|
+
let result = newNode && !contains(parentDOM, newNode) || (oldNode == newNode && oldOff == newOff);
|
|
37476
37476
|
// Restore the previous selection
|
|
37477
37477
|
try {
|
|
37478
37478
|
sel.collapse(anchorNode, anchorOffset);
|
|
@@ -37580,7 +37580,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37580
37580
|
localPosFromDOM(dom, offset, bias) {
|
|
37581
37581
|
// If the DOM position is in the content, use the child desc after
|
|
37582
37582
|
// it to figure out a position.
|
|
37583
|
-
if (this.contentDOM && this.contentDOM
|
|
37583
|
+
if (this.contentDOM && contains(this.contentDOM, dom)) {
|
|
37584
37584
|
if (bias < 0) {
|
|
37585
37585
|
let domBefore, desc;
|
|
37586
37586
|
if (dom == this.contentDOM) {
|
|
@@ -37618,7 +37618,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37618
37618
|
atEnd = offset > domIndex(this.contentDOM);
|
|
37619
37619
|
}
|
|
37620
37620
|
else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
|
|
37621
|
-
atEnd = dom.compareDocumentPosition(this.contentDOM) &
|
|
37621
|
+
atEnd = !!(dom.compareDocumentPosition(this.contentDOM) & 4);
|
|
37622
37622
|
}
|
|
37623
37623
|
else if (this.dom.firstChild) {
|
|
37624
37624
|
if (offset == 0)
|
|
@@ -37648,7 +37648,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37648
37648
|
if (desc && (!onlyNodes || desc.node)) {
|
|
37649
37649
|
// If dom is outside of this desc's nodeDOM, don't count it.
|
|
37650
37650
|
if (first && (nodeDOM = desc.nodeDOM) &&
|
|
37651
|
-
!(nodeDOM
|
|
37651
|
+
!(isElt(nodeDOM) ? contains(nodeDOM, dom) : nodeDOM == dom))
|
|
37652
37652
|
first = false;
|
|
37653
37653
|
else
|
|
37654
37654
|
return desc;
|
|
@@ -37698,7 +37698,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37698
37698
|
let i = 0, offset = 0;
|
|
37699
37699
|
for (let curPos = 0; i < this.children.length; i++) {
|
|
37700
37700
|
let child = this.children[i], end = curPos + child.size;
|
|
37701
|
-
if (end > pos
|
|
37701
|
+
if (end > pos) {
|
|
37702
37702
|
offset = pos - curPos;
|
|
37703
37703
|
break;
|
|
37704
37704
|
}
|
|
@@ -37708,7 +37708,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37708
37708
|
if (offset)
|
|
37709
37709
|
return this.children[i].domFromPos(offset - this.children[i].border, side);
|
|
37710
37710
|
// Go back if there were any zero-length widgets with side >= 0 before this point
|
|
37711
|
-
for (
|
|
37711
|
+
for (; i > 0; i--) {
|
|
37712
|
+
let prev = this.children[i - 1];
|
|
37713
|
+
if (prev.size || !(prev instanceof BufferHackViewDesc || prev instanceof WidgetViewDesc && prev.side >= 0))
|
|
37714
|
+
break;
|
|
37715
|
+
}
|
|
37712
37716
|
// Scan towards the first useable node
|
|
37713
37717
|
if (side <= 0) {
|
|
37714
37718
|
let prev, enter = true;
|
|
@@ -37785,7 +37789,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37785
37789
|
}
|
|
37786
37790
|
domAfterPos(pos) {
|
|
37787
37791
|
let { node, offset } = this.domFromPos(pos, 0);
|
|
37788
|
-
if (node
|
|
37792
|
+
if (!isElt(node) || offset == node.childNodes.length)
|
|
37789
37793
|
throw new RangeError("No node after pos " + pos);
|
|
37790
37794
|
return node.childNodes[offset];
|
|
37791
37795
|
}
|
|
@@ -37814,7 +37818,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37814
37818
|
// reported position in such situations (#1092).
|
|
37815
37819
|
if ((gecko || safari) && anchor == head) {
|
|
37816
37820
|
let { node, offset } = anchorDOM;
|
|
37817
|
-
if (node
|
|
37821
|
+
if (isText(node)) {
|
|
37818
37822
|
brKludge = !!(offset && node.nodeValue[offset - 1] == "\n");
|
|
37819
37823
|
// Issue #1128
|
|
37820
37824
|
if (brKludge && offset == node.nodeValue.length) {
|
|
@@ -37837,7 +37841,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37837
37841
|
}
|
|
37838
37842
|
// Firefox can act strangely when the selection is in front of an
|
|
37839
37843
|
// uneditable node. See #1163 and https://bugzilla.mozilla.org/show_bug.cgi?id=1709536
|
|
37840
|
-
if (gecko && selRange.focusNode && selRange.focusNode != headDOM.node && selRange.focusNode
|
|
37844
|
+
if (gecko && selRange.focusNode && selRange.focusNode != headDOM.node && isElt(selRange.focusNode)) {
|
|
37841
37845
|
let after = selRange.focusNode.childNodes[selRange.focusOffset];
|
|
37842
37846
|
if (after && after.contentEditable == "false")
|
|
37843
37847
|
force = true;
|
|
@@ -37936,14 +37940,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37936
37940
|
return self.parent.posBeforeChild(self);
|
|
37937
37941
|
});
|
|
37938
37942
|
if (!widget.type.spec.raw) {
|
|
37939
|
-
|
|
37940
|
-
|
|
37941
|
-
|
|
37942
|
-
|
|
37943
|
-
|
|
37944
|
-
|
|
37945
|
-
dom.contentEditable = "false";
|
|
37946
|
-
dom.classList.add("ProseMirror-widget");
|
|
37943
|
+
let elt = isElt(dom) ? dom : document.createElement("span");
|
|
37944
|
+
if (elt != dom)
|
|
37945
|
+
elt.appendChild(dom);
|
|
37946
|
+
if (!elt.hasAttribute("contenteditable"))
|
|
37947
|
+
elt.contentEditable = "false";
|
|
37948
|
+
elt.classList.add("ProseMirror-widget");
|
|
37947
37949
|
}
|
|
37948
37950
|
super(parent, [], dom, null);
|
|
37949
37951
|
this.widget = widget;
|
|
@@ -38079,7 +38081,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38079
38081
|
if (node.isText) {
|
|
38080
38082
|
if (!dom)
|
|
38081
38083
|
dom = document.createTextNode(node.text);
|
|
38082
|
-
else if (dom
|
|
38084
|
+
else if (!isText(dom))
|
|
38083
38085
|
throw new RangeError("Text must be rendered as a DOM text node");
|
|
38084
38086
|
}
|
|
38085
38087
|
else if (!dom) {
|
|
@@ -38131,7 +38133,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38131
38133
|
}
|
|
38132
38134
|
if (!rule.contentElement) {
|
|
38133
38135
|
let found = addedNodes &&
|
|
38134
|
-
addedNodes.find(n => n
|
|
38136
|
+
addedNodes.find(n => isElt(n) && addedNodes.indexOf(n.parentNode) < 0 && this.dom.contains(n));
|
|
38135
38137
|
if (found)
|
|
38136
38138
|
rule.contentElement = found;
|
|
38137
38139
|
else
|
|
@@ -38156,6 +38158,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38156
38158
|
let localComposition = composition && composition.pos > -1 ? composition : null;
|
|
38157
38159
|
let compositionInChild = composition && composition.pos < 0;
|
|
38158
38160
|
let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
|
|
38161
|
+
let addBuffers = this.node.inlineContent, atBufferPos = addBuffers && this.node.isBlock;
|
|
38159
38162
|
iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => {
|
|
38160
38163
|
if (widget.spec.marks)
|
|
38161
38164
|
updater.syncToMarks(widget.spec.marks, inline, view, i);
|
|
@@ -38167,6 +38170,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38167
38170
|
}, (child, outerDeco, innerDeco, i) => {
|
|
38168
38171
|
// Make sure the wrapping mark descs match the node's marks.
|
|
38169
38172
|
updater.syncToMarks(child.marks, inline, view, i);
|
|
38173
|
+
if (atBufferPos && child.isAtom && !child.isText)
|
|
38174
|
+
updater.addHackNode("IMG", updater.top);
|
|
38170
38175
|
// Try several strategies for drawing this node
|
|
38171
38176
|
let compIndex;
|
|
38172
38177
|
if (updater.findNodeMatch(child, outerDeco, innerDeco, i)) ;
|
|
@@ -38180,6 +38185,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38180
38185
|
updater.addNode(child, outerDeco, innerDeco, view, off);
|
|
38181
38186
|
}
|
|
38182
38187
|
off += child.nodeSize;
|
|
38188
|
+
if (addBuffers)
|
|
38189
|
+
atBufferPos = child.isAtom && !child.isText;
|
|
38183
38190
|
});
|
|
38184
38191
|
// Drop all remaining descs after the current position.
|
|
38185
38192
|
updater.syncToMarks([], inline, view, 0);
|
|
@@ -38258,7 +38265,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38258
38265
|
updateOuterDeco(outerDeco) {
|
|
38259
38266
|
if (sameOuterDeco(outerDeco, this.outerDeco))
|
|
38260
38267
|
return;
|
|
38261
|
-
let needsWrap = this.nodeDOM
|
|
38268
|
+
let needsWrap = !isElt(this.nodeDOM);
|
|
38262
38269
|
let oldDOM = this.dom;
|
|
38263
38270
|
this.dom = patchOuterDeco(this.dom, this.nodeDOM, computeOuterDeco(this.outerDeco, this.node, needsWrap), computeOuterDeco(outerDeco, this.node, needsWrap));
|
|
38264
38271
|
if (this.dom != oldDOM) {
|
|
@@ -38269,7 +38276,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38269
38276
|
}
|
|
38270
38277
|
// Mark this node as being the selected node.
|
|
38271
38278
|
selectNode() {
|
|
38272
|
-
if (this.nodeDOM
|
|
38279
|
+
if (isElt(this.nodeDOM)) {
|
|
38273
38280
|
this.nodeDOM.classList.add("ProseMirror-selectednode");
|
|
38274
38281
|
if (this.contentDOM || !this.node.type.spec.draggable)
|
|
38275
38282
|
this.nodeDOM.draggable = true;
|
|
@@ -38277,7 +38284,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38277
38284
|
}
|
|
38278
38285
|
// Remove selected node marking from this node.
|
|
38279
38286
|
deselectNode() {
|
|
38280
|
-
if (this.nodeDOM
|
|
38287
|
+
if (isElt(this.nodeDOM)) {
|
|
38281
38288
|
this.nodeDOM.classList.remove("ProseMirror-selectednode");
|
|
38282
38289
|
if (this.contentDOM || !this.node.type.spec.draggable)
|
|
38283
38290
|
this.nodeDOM.removeAttribute("draggable");
|
|
@@ -38348,9 +38355,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38348
38355
|
get domAtom() { return false; }
|
|
38349
38356
|
isText(text) { return this.node.text == text; }
|
|
38350
38357
|
}
|
|
38351
|
-
// A dummy desc used to tag
|
|
38358
|
+
// A dummy desc used to tag extra BR or IMG nodes created to work
|
|
38352
38359
|
// around contentEditable terribleness.
|
|
38353
|
-
class
|
|
38360
|
+
class BufferHackViewDesc extends ViewDesc {
|
|
38354
38361
|
parseRule() { return { ignore: true }; }
|
|
38355
38362
|
matchesHack(nodeName) { return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName; }
|
|
38356
38363
|
get domAtom() { return true; }
|
|
@@ -38523,7 +38530,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38523
38530
|
}
|
|
38524
38531
|
}
|
|
38525
38532
|
function applyOuterDeco(dom, deco, node) {
|
|
38526
|
-
return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom
|
|
38533
|
+
return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, !isElt(dom)));
|
|
38527
38534
|
}
|
|
38528
38535
|
function sameOuterDeco(a, b) {
|
|
38529
38536
|
if (a.length != b.length)
|
|
@@ -38786,7 +38793,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38786
38793
|
}
|
|
38787
38794
|
if (nodeName == "BR")
|
|
38788
38795
|
dom.className = "ProseMirror-trailingBreak";
|
|
38789
|
-
let hack = new
|
|
38796
|
+
let hack = new BufferHackViewDesc(this.top, [], dom, null);
|
|
38790
38797
|
if (parent != this.top)
|
|
38791
38798
|
parent.children.push(hack);
|
|
38792
38799
|
else
|
|
@@ -38795,7 +38802,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38795
38802
|
}
|
|
38796
38803
|
}
|
|
38797
38804
|
isLocked(node) {
|
|
38798
|
-
return this.lock && (node == this.lock || node
|
|
38805
|
+
return this.lock && (node == this.lock || isElt(node) && node.contains(this.lock.parentNode));
|
|
38799
38806
|
}
|
|
38800
38807
|
}
|
|
38801
38808
|
// Iterate from the end of the fragment and array of descs to find
|
|
@@ -38997,12 +39004,27 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38997
39004
|
anchor = head;
|
|
38998
39005
|
while (nearestDesc && !nearestDesc.node)
|
|
38999
39006
|
nearestDesc = nearestDesc.parent;
|
|
39000
|
-
|
|
39001
|
-
|
|
39002
|
-
|
|
39007
|
+
if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) &&
|
|
39008
|
+
nearestDesc.parent &&
|
|
39009
|
+
!(nearestDesc.node.isInline && isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) {
|
|
39003
39010
|
let pos = nearestDesc.posBefore;
|
|
39004
39011
|
selection = new NodeSelection(head == pos ? $head : doc.resolve(pos));
|
|
39005
39012
|
}
|
|
39013
|
+
else if (gecko && origin == "key" && head > view.state.selection.to &&
|
|
39014
|
+
isElt(domSel.focusNode) && domSel.focusOffset == domSel.focusNode.childNodes.length &&
|
|
39015
|
+
nearestDesc && nearestDesc.posAtStart > view.state.selection.to) {
|
|
39016
|
+
// Firefox will jump across scrollable wrapper nodes on keyboard
|
|
39017
|
+
// cursor motion (#1594). This tries to detect this situation
|
|
39018
|
+
// and work around it.
|
|
39019
|
+
for (let scan = domSel.focusNode;; scan = scan.parentNode) {
|
|
39020
|
+
if (getComputedStyle(scan).overflow != "visible") {
|
|
39021
|
+
selection = Selection$2.findFrom(doc.resolve(nearestDesc.posAtStart), 1);
|
|
39022
|
+
break;
|
|
39023
|
+
}
|
|
39024
|
+
if (scan == nearestDesc.dom || scan.nextSibling || !scan.parentNode || !isElt(scan.parentNode))
|
|
39025
|
+
break;
|
|
39026
|
+
}
|
|
39027
|
+
}
|
|
39006
39028
|
}
|
|
39007
39029
|
else {
|
|
39008
39030
|
if (domSel instanceof view.dom.ownerDocument.defaultView.Selection && domSel.rangeCount > 1) {
|
|
@@ -39188,8 +39210,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39188
39210
|
// Firefox will raise 'permission denied' errors when accessing
|
|
39189
39211
|
// properties of `sel.anchorNode` when it's in a generated CSS
|
|
39190
39212
|
// element.
|
|
39191
|
-
return view.dom
|
|
39192
|
-
(view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode));
|
|
39213
|
+
return contains(view.dom, sel.anchorNode) && (view.editable || contains(view.dom, sel.focusNode));
|
|
39193
39214
|
}
|
|
39194
39215
|
catch (_) {
|
|
39195
39216
|
return false;
|
|
@@ -39240,15 +39261,14 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39240
39261
|
if (NodeSelection.isSelectable(node)) {
|
|
39241
39262
|
return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head));
|
|
39242
39263
|
}
|
|
39243
|
-
else
|
|
39264
|
+
else {
|
|
39244
39265
|
// Chrome and Safari will introduce extra pointless cursor
|
|
39245
|
-
// positions around inline uneditable nodes,
|
|
39246
|
-
//
|
|
39266
|
+
// positions around inline uneditable nodes (#937), and
|
|
39267
|
+
// Firefox will sometimes just plain refuse to move across
|
|
39268
|
+
// them (#1592), so in this situation we move the cursor
|
|
39269
|
+
// ourselves.
|
|
39247
39270
|
return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize)));
|
|
39248
39271
|
}
|
|
39249
|
-
else {
|
|
39250
|
-
return false;
|
|
39251
|
-
}
|
|
39252
39272
|
}
|
|
39253
39273
|
}
|
|
39254
39274
|
else if (sel instanceof NodeSelection && sel.node.isInline) {
|
|
@@ -39261,12 +39281,10 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39261
39281
|
return false;
|
|
39262
39282
|
}
|
|
39263
39283
|
}
|
|
39264
|
-
function nodeLen(node) {
|
|
39265
|
-
return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
|
|
39266
|
-
}
|
|
39267
39284
|
function isIgnorable(dom, dir) {
|
|
39268
39285
|
let desc = dom.pmViewDesc;
|
|
39269
|
-
return desc
|
|
39286
|
+
return desc ? desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR")
|
|
39287
|
+
: isElt(dom) && dom.contentEditable == "false";
|
|
39270
39288
|
}
|
|
39271
39289
|
function skipIgnoredNodes(view, dir) {
|
|
39272
39290
|
return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view);
|
|
@@ -39282,25 +39300,23 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39282
39300
|
// Gecko will do odd things when the selection is directly in front
|
|
39283
39301
|
// of a non-editable node, so in that case, move it into the next
|
|
39284
39302
|
// node if possible. Issue prosemirror/prosemirror#832.
|
|
39285
|
-
if (gecko && node
|
|
39303
|
+
if (gecko && isElt(node) && offset < nodeSize(node) && isIgnorable(node.childNodes[offset], -1))
|
|
39286
39304
|
force = true;
|
|
39287
39305
|
for (;;) {
|
|
39288
39306
|
if (offset > 0) {
|
|
39289
|
-
if (node
|
|
39307
|
+
if (!isElt(node))
|
|
39290
39308
|
break;
|
|
39309
|
+
let before = node.childNodes[offset - 1];
|
|
39310
|
+
if (isIgnorable(before, -1)) {
|
|
39311
|
+
moveNode = node;
|
|
39312
|
+
moveOffset = --offset;
|
|
39313
|
+
}
|
|
39314
|
+
else if (isText(before)) {
|
|
39315
|
+
node = before;
|
|
39316
|
+
offset = node.nodeValue.length;
|
|
39291
39317
|
}
|
|
39292
39318
|
else {
|
|
39293
|
-
|
|
39294
|
-
if (isIgnorable(before, -1)) {
|
|
39295
|
-
moveNode = node;
|
|
39296
|
-
moveOffset = --offset;
|
|
39297
|
-
}
|
|
39298
|
-
else if (before.nodeType == 3) {
|
|
39299
|
-
node = before;
|
|
39300
|
-
offset = node.nodeValue.length;
|
|
39301
|
-
}
|
|
39302
|
-
else
|
|
39303
|
-
break;
|
|
39319
|
+
break;
|
|
39304
39320
|
}
|
|
39305
39321
|
}
|
|
39306
39322
|
else if (isBlockNode(node)) {
|
|
@@ -39321,7 +39337,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39321
39337
|
}
|
|
39322
39338
|
else {
|
|
39323
39339
|
node = prev;
|
|
39324
|
-
offset =
|
|
39340
|
+
offset = nodeSize(node);
|
|
39325
39341
|
}
|
|
39326
39342
|
}
|
|
39327
39343
|
}
|
|
@@ -39337,19 +39353,20 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39337
39353
|
let node = sel.focusNode, offset = sel.focusOffset;
|
|
39338
39354
|
if (!node)
|
|
39339
39355
|
return;
|
|
39340
|
-
let len =
|
|
39356
|
+
let len = nodeSize(node);
|
|
39341
39357
|
let moveNode, moveOffset;
|
|
39342
39358
|
for (;;) {
|
|
39343
39359
|
if (offset < len) {
|
|
39344
|
-
if (node
|
|
39360
|
+
if (!isElt(node))
|
|
39345
39361
|
break;
|
|
39346
39362
|
let after = node.childNodes[offset];
|
|
39347
39363
|
if (isIgnorable(after, 1)) {
|
|
39348
39364
|
moveNode = node;
|
|
39349
39365
|
moveOffset = ++offset;
|
|
39350
39366
|
}
|
|
39351
|
-
else
|
|
39367
|
+
else {
|
|
39352
39368
|
break;
|
|
39369
|
+
}
|
|
39353
39370
|
}
|
|
39354
39371
|
else if (isBlockNode(node)) {
|
|
39355
39372
|
break;
|
|
@@ -39370,7 +39387,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39370
39387
|
else {
|
|
39371
39388
|
node = next;
|
|
39372
39389
|
offset = 0;
|
|
39373
|
-
len =
|
|
39390
|
+
len = nodeSize(node);
|
|
39374
39391
|
}
|
|
39375
39392
|
}
|
|
39376
39393
|
}
|
|
@@ -39388,9 +39405,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39388
39405
|
}
|
|
39389
39406
|
while (node && offset < node.childNodes.length) {
|
|
39390
39407
|
let next = node.childNodes[offset];
|
|
39391
|
-
if (next
|
|
39408
|
+
if (isText(next))
|
|
39392
39409
|
return next;
|
|
39393
|
-
if (next
|
|
39410
|
+
if (isElt(next) && next.contentEditable == "false")
|
|
39394
39411
|
break;
|
|
39395
39412
|
node = next;
|
|
39396
39413
|
offset = 0;
|
|
@@ -39403,16 +39420,16 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39403
39420
|
}
|
|
39404
39421
|
while (node && offset) {
|
|
39405
39422
|
let next = node.childNodes[offset - 1];
|
|
39406
|
-
if (next
|
|
39423
|
+
if (isText(next))
|
|
39407
39424
|
return next;
|
|
39408
|
-
if (next
|
|
39425
|
+
if (isElt(next) && next.contentEditable == "false")
|
|
39409
39426
|
break;
|
|
39410
39427
|
node = next;
|
|
39411
39428
|
offset = node.childNodes.length;
|
|
39412
39429
|
}
|
|
39413
39430
|
}
|
|
39414
39431
|
function setSelFocus(view, node, offset) {
|
|
39415
|
-
if (node
|
|
39432
|
+
if (!isText(node)) {
|
|
39416
39433
|
let before, after;
|
|
39417
39434
|
if (after = textNodeAfter(node, offset)) {
|
|
39418
39435
|
node = after;
|
|
@@ -39522,8 +39539,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39522
39539
|
if (!safari || view.state.selection.$head.parentOffset > 0)
|
|
39523
39540
|
return false;
|
|
39524
39541
|
let { focusNode, focusOffset } = view.domSelectionRange();
|
|
39525
|
-
if (focusNode && focusNode
|
|
39526
|
-
focusNode.firstChild && focusNode.firstChild.contentEditable == "false") {
|
|
39542
|
+
if (focusNode && isElt(focusNode) && focusOffset == 0 &&
|
|
39543
|
+
focusNode.firstChild && isElt(focusNode.firstChild) && focusNode.firstChild.contentEditable == "false") {
|
|
39527
39544
|
let child = focusNode.firstChild;
|
|
39528
39545
|
switchEditable(view, child, "true");
|
|
39529
39546
|
setTimeout(() => switchEditable(view, child, "false"), 20);
|
|
@@ -39594,7 +39611,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39594
39611
|
let doc = detachedDoc(), wrap = doc.createElement("div");
|
|
39595
39612
|
wrap.appendChild(serializer.serializeFragment(content, { document: doc }));
|
|
39596
39613
|
let firstChild = wrap.firstChild, needsWrap, wrappers = 0;
|
|
39597
|
-
while (firstChild && firstChild
|
|
39614
|
+
while (firstChild && isElt(firstChild) && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) {
|
|
39598
39615
|
for (let i = needsWrap.length - 1; i >= 0; i--) {
|
|
39599
39616
|
let wrapper = doc.createElement(needsWrap[i]);
|
|
39600
39617
|
while (wrap.firstChild)
|
|
@@ -39604,7 +39621,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39604
39621
|
}
|
|
39605
39622
|
firstChild = wrap.firstChild;
|
|
39606
39623
|
}
|
|
39607
|
-
if (firstChild && firstChild
|
|
39624
|
+
if (firstChild && isElt(firstChild))
|
|
39608
39625
|
firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`);
|
|
39609
39626
|
let text = view.someProp("clipboardTextSerializer", f => f(slice, view)) ||
|
|
39610
39627
|
slice.content.textBetween(0, slice.content.size, "\n\n");
|
|
@@ -39650,7 +39667,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39650
39667
|
if (sliceData && sliceData[3])
|
|
39651
39668
|
for (let i = +sliceData[3]; i > 0; i--) {
|
|
39652
39669
|
let child = dom.firstChild;
|
|
39653
|
-
while (child && child
|
|
39670
|
+
while (child && !isElt(child))
|
|
39654
39671
|
child = child.nextSibling;
|
|
39655
39672
|
if (!child)
|
|
39656
39673
|
break;
|
|
@@ -39855,12 +39872,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39855
39872
|
if (!type || type.hasRequiredAttrs())
|
|
39856
39873
|
break;
|
|
39857
39874
|
try {
|
|
39858
|
-
type.
|
|
39875
|
+
content = Fragment.from(type.create(array[i + 1], content));
|
|
39859
39876
|
}
|
|
39860
39877
|
catch (e) {
|
|
39861
39878
|
break;
|
|
39862
39879
|
}
|
|
39863
|
-
content = Fragment.from(type.create(array[i + 1], content));
|
|
39864
39880
|
openStart++;
|
|
39865
39881
|
openEnd++;
|
|
39866
39882
|
}
|
|
@@ -40192,7 +40208,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40192
40208
|
}
|
|
40193
40209
|
const target = flushed ? null : event.target;
|
|
40194
40210
|
const targetDesc = target ? view.docView.nearestDesc(target, true) : null;
|
|
40195
|
-
this.target = targetDesc && targetDesc.nodeDOM
|
|
40211
|
+
this.target = targetDesc && isElt(targetDesc.nodeDOM) ? targetDesc.nodeDOM : null;
|
|
40196
40212
|
let { selection } = view.state;
|
|
40197
40213
|
if (event.button == 0 &&
|
|
40198
40214
|
(targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
|
|
@@ -40340,7 +40356,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40340
40356
|
if (!view.composing) {
|
|
40341
40357
|
view.domObserver.flush();
|
|
40342
40358
|
let { state } = view, $pos = state.selection.$to;
|
|
40343
|
-
if (state.selection instanceof TextSelection &&
|
|
40359
|
+
if (state.selection instanceof TextSelection && state.selection.empty &&
|
|
40344
40360
|
(state.storedMarks ||
|
|
40345
40361
|
(!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)) ||
|
|
40346
40362
|
chrome && windows$1 && selectionBeforeUneditable(view))) { // Issue #1500
|
|
@@ -40356,11 +40372,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40356
40372
|
// inside if necessary.
|
|
40357
40373
|
if (gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) {
|
|
40358
40374
|
let sel = view.domSelectionRange();
|
|
40359
|
-
for (let node = sel.focusNode, offset = sel.focusOffset; node && node
|
|
40375
|
+
for (let node = sel.focusNode, offset = sel.focusOffset; node && isElt(node) && offset != 0;) {
|
|
40360
40376
|
let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1];
|
|
40361
40377
|
if (!before)
|
|
40362
40378
|
break;
|
|
40363
|
-
if (before
|
|
40379
|
+
if (isText(before)) {
|
|
40364
40380
|
let sel = view.domSelection();
|
|
40365
40381
|
if (sel)
|
|
40366
40382
|
sel.collapse(before, before.nodeValue.length);
|
|
@@ -40379,10 +40395,10 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40379
40395
|
};
|
|
40380
40396
|
function selectionBeforeUneditable(view) {
|
|
40381
40397
|
let { focusNode, focusOffset } = view.domSelectionRange();
|
|
40382
|
-
if (!focusNode || focusNode
|
|
40398
|
+
if (!focusNode || !isElt(focusNode) || focusOffset >= focusNode.childNodes.length)
|
|
40383
40399
|
return false;
|
|
40384
40400
|
let next = focusNode.childNodes[focusOffset];
|
|
40385
|
-
return next
|
|
40401
|
+
return isElt(next) && next.contentEditable == "false";
|
|
40386
40402
|
}
|
|
40387
40403
|
editHandlers.compositionend = (view, event) => {
|
|
40388
40404
|
if (view.composing) {
|
|
@@ -40584,7 +40600,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40584
40600
|
else if (mouseDown && mouseDown.mightDrag) {
|
|
40585
40601
|
node = NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos);
|
|
40586
40602
|
}
|
|
40587
|
-
else if (event.target && event.target
|
|
40603
|
+
else if (event.target && isElt(event.target)) {
|
|
40588
40604
|
let desc = view.docView.nearestDesc(event.target, true);
|
|
40589
40605
|
if (desc && desc.node.type.spec.draggable && desc != view.docView)
|
|
40590
40606
|
node = NodeSelection.create(view.state.doc, desc.posBefore);
|
|
@@ -41555,7 +41571,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41555
41571
|
let desc = container && this.view.docView.nearestDesc(container);
|
|
41556
41572
|
if (desc && desc.ignoreMutation({
|
|
41557
41573
|
type: "selection",
|
|
41558
|
-
target: container
|
|
41574
|
+
target: isText(container) ? container.parentNode : container
|
|
41559
41575
|
})) {
|
|
41560
41576
|
this.setCurSelection();
|
|
41561
41577
|
return true;
|
|
@@ -41597,7 +41613,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41597
41613
|
for (let node of added)
|
|
41598
41614
|
if (node.nodeName == "BR" && node.parentNode) {
|
|
41599
41615
|
let after = node.nextSibling;
|
|
41600
|
-
while (after && after
|
|
41616
|
+
while (after && isElt(after)) {
|
|
41601
41617
|
if (after.contentEditable == "false") {
|
|
41602
41618
|
node.parentNode.removeChild(node);
|
|
41603
41619
|
break;
|
|
@@ -41670,7 +41686,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41670
41686
|
for (let i = 0; i < mut.addedNodes.length; i++) {
|
|
41671
41687
|
let node = mut.addedNodes[i];
|
|
41672
41688
|
added.push(node);
|
|
41673
|
-
if (node
|
|
41689
|
+
if (isText(node))
|
|
41674
41690
|
this.lastChangedTextNode = node;
|
|
41675
41691
|
}
|
|
41676
41692
|
if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target))
|
|
@@ -41785,8 +41801,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41785
41801
|
let parent = nextCell;
|
|
41786
41802
|
for (;;) {
|
|
41787
41803
|
let first = parent.firstChild;
|
|
41788
|
-
if (!first || first
|
|
41789
|
-
/^(BR|IMG)$/.test(first.nodeName))
|
|
41804
|
+
if (!first || !isElt(first) || first.contentEditable == "false" || /^(BR|IMG)$/.test(first.nodeName))
|
|
41790
41805
|
break;
|
|
41791
41806
|
parent = first;
|
|
41792
41807
|
}
|
|
@@ -41811,7 +41826,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41811
41826
|
let domSel = view.domSelectionRange();
|
|
41812
41827
|
let find;
|
|
41813
41828
|
let anchor = domSel.anchorNode;
|
|
41814
|
-
if (anchor && view.dom
|
|
41829
|
+
if (anchor && contains(view.dom, anchor)) {
|
|
41815
41830
|
find = [{ node: anchor, offset: domSel.anchorOffset }];
|
|
41816
41831
|
if (!selectionCollapsed(domSel))
|
|
41817
41832
|
find.push({ node: domSel.focusNode, offset: domSel.focusOffset });
|
|
@@ -41919,7 +41934,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41919
41934
|
if (change)
|
|
41920
41935
|
view.input.domChangeCount++;
|
|
41921
41936
|
if ((ios && view.input.lastIOSEnter > Date.now() - 225 || android) &&
|
|
41922
|
-
addedNodes.some(n => n
|
|
41937
|
+
addedNodes.some(n => isElt(n) && !isInline.test(n.nodeName)) &&
|
|
41923
41938
|
(!change || change.endA >= change.endB) &&
|
|
41924
41939
|
view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
|
|
41925
41940
|
view.input.lastIOSEnter = 0;
|
|
@@ -41977,9 +41992,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41977
41992
|
// as being an iOS enter press), just dispatch an Enter key instead.
|
|
41978
41993
|
if (((ios && view.input.lastIOSEnter > Date.now() - 225 &&
|
|
41979
41994
|
(!inlineChange || addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P"))) ||
|
|
41980
|
-
(!inlineChange && $from.pos
|
|
41981
|
-
(!$from.sameParent($to) || !$from.parent.inlineContent) &&
|
|
41982
|
-
$from.pos < $to.pos && !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")))) &&
|
|
41995
|
+
(!inlineChange && looksLikeEnter(parse.doc, $from.pos, $to.pos))) &&
|
|
41983
41996
|
view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
|
|
41984
41997
|
view.input.lastIOSEnter = 0;
|
|
41985
41998
|
return;
|
|
@@ -42130,6 +42143,16 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42130
42143
|
// The fragments after the join point must match
|
|
42131
42144
|
return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content);
|
|
42132
42145
|
}
|
|
42146
|
+
function looksLikeEnter(content, from, to) {
|
|
42147
|
+
let newTextlines = 0, newLeaves = 0;
|
|
42148
|
+
content.nodesBetween(from, to, (node, pos) => {
|
|
42149
|
+
if (node.isTextblock && pos >= from && pos < to)
|
|
42150
|
+
newTextlines++;
|
|
42151
|
+
else if (node.isText ? /\S/.test(node.text.slice(Math.max(0, from - pos), Math.min(node.nodeSize, to - pos))) : node.isLeaf)
|
|
42152
|
+
newLeaves++;
|
|
42153
|
+
});
|
|
42154
|
+
return newLeaves == 0 && newTextlines == 1;
|
|
42155
|
+
}
|
|
42133
42156
|
function skipClosingAndOpening($pos, fromEnd, mayOpen) {
|
|
42134
42157
|
let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos;
|
|
42135
42158
|
while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) {
|
|
@@ -42390,11 +42413,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42390
42413
|
*/
|
|
42391
42414
|
scrollToSelection() {
|
|
42392
42415
|
let startDOM = this.domSelectionRange().focusNode;
|
|
42393
|
-
if (!startDOM || !this.dom
|
|
42416
|
+
if (!startDOM || !contains(this.dom, startDOM)) ;
|
|
42394
42417
|
else if (this.someProp("handleScrollToSelection", f => f(this))) ;
|
|
42395
42418
|
else if (this.state.selection instanceof NodeSelection) {
|
|
42396
42419
|
let target = this.docView.domAfterPos(this.state.selection.from);
|
|
42397
|
-
if (target
|
|
42420
|
+
if (isElt(target))
|
|
42398
42421
|
scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
|
|
42399
42422
|
}
|
|
42400
42423
|
else {
|
|
@@ -42659,7 +42682,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42659
42682
|
@internal
|
|
42660
42683
|
*/
|
|
42661
42684
|
domSelectionRange() {
|
|
42662
|
-
let sel = this.domSelection();
|
|
42685
|
+
let sel = this.dom.isConnected !== false && this.domSelection();
|
|
42663
42686
|
if (!sel)
|
|
42664
42687
|
return { focusNode: null, focusOffset: 0, anchorNode: null, anchorOffset: 0 };
|
|
42665
42688
|
return safari && this.root.nodeType === 11 &&
|
|
@@ -42990,399 +43013,1030 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42990
43013
|
};
|
|
42991
43014
|
}
|
|
42992
43015
|
|
|
42993
|
-
|
|
42994
|
-
|
|
42995
|
-
|
|
42996
|
-
|
|
42997
|
-
|
|
42998
|
-
|
|
42999
|
-
|
|
43000
|
-
|
|
43001
|
-
|
|
43002
|
-
|
|
43003
|
-
|
|
43004
|
-
|
|
43005
|
-
|
|
43006
|
-
|
|
43007
|
-
|
|
43008
|
-
plugins: state.plugins,
|
|
43009
|
-
schema: state.schema,
|
|
43010
|
-
reconfigure: state.reconfigure.bind(state),
|
|
43011
|
-
toJSON: state.toJSON.bind(state),
|
|
43012
|
-
get storedMarks() {
|
|
43013
|
-
return storedMarks;
|
|
43014
|
-
},
|
|
43015
|
-
get selection() {
|
|
43016
|
-
return selection;
|
|
43017
|
-
},
|
|
43018
|
-
get doc() {
|
|
43019
|
-
return doc;
|
|
43020
|
-
},
|
|
43021
|
-
get tr() {
|
|
43022
|
-
selection = transaction.selection;
|
|
43023
|
-
doc = transaction.doc;
|
|
43024
|
-
storedMarks = transaction.storedMarks;
|
|
43025
|
-
return transaction;
|
|
43026
|
-
}
|
|
43027
|
-
};
|
|
43028
|
-
}
|
|
43029
|
-
//#endregion
|
|
43030
|
-
//#region src/CommandManager.ts
|
|
43031
|
-
var CommandManager = class CommandManager {
|
|
43032
|
-
constructor(props) {
|
|
43033
|
-
this.editor = props.editor;
|
|
43034
|
-
this.rawCommands = this.editor.extensionManager.commands;
|
|
43035
|
-
this.customState = props.state;
|
|
43036
|
-
}
|
|
43037
|
-
get hasCustomState() {
|
|
43038
|
-
return !!this.customState;
|
|
43039
|
-
}
|
|
43040
|
-
get state() {
|
|
43041
|
-
return this.customState || this.editor.state;
|
|
43042
|
-
}
|
|
43043
|
-
get commands() {
|
|
43044
|
-
const { rawCommands, editor, state } = this;
|
|
43045
|
-
const { view } = editor;
|
|
43046
|
-
const { tr } = state;
|
|
43047
|
-
const props = this.buildProps(tr);
|
|
43048
|
-
return Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43049
|
-
const method = (...args) => {
|
|
43050
|
-
const callback = command(...args)(props);
|
|
43051
|
-
if (!tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
|
|
43052
|
-
return callback;
|
|
43053
|
-
};
|
|
43054
|
-
return [name, method];
|
|
43055
|
-
}));
|
|
43056
|
-
}
|
|
43057
|
-
get chain() {
|
|
43058
|
-
return () => this.createChain();
|
|
43059
|
-
}
|
|
43060
|
-
get can() {
|
|
43061
|
-
return () => this.createCan();
|
|
43062
|
-
}
|
|
43063
|
-
createChain(startTr, shouldDispatch = true) {
|
|
43064
|
-
const { rawCommands, editor, state } = this;
|
|
43065
|
-
const { view } = editor;
|
|
43066
|
-
const callbacks = [];
|
|
43067
|
-
const hasStartTransaction = !!startTr;
|
|
43068
|
-
const tr = startTr || state.tr;
|
|
43069
|
-
const run = () => {
|
|
43070
|
-
if (!hasStartTransaction && shouldDispatch && !tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
|
|
43071
|
-
return callbacks.every((callback) => callback === true);
|
|
43072
|
-
};
|
|
43073
|
-
const chain = {
|
|
43074
|
-
...Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43075
|
-
const chainedCommand = (...args) => {
|
|
43076
|
-
const props = this.buildProps(tr, shouldDispatch);
|
|
43077
|
-
const callback = command(...args)(props);
|
|
43078
|
-
callbacks.push(callback);
|
|
43079
|
-
return chain;
|
|
43080
|
-
};
|
|
43081
|
-
return [name, chainedCommand];
|
|
43082
|
-
})),
|
|
43083
|
-
run
|
|
43084
|
-
};
|
|
43085
|
-
return chain;
|
|
43086
|
-
}
|
|
43087
|
-
/**
|
|
43088
|
-
* Creates a chain that safely returns `false` when run.
|
|
43089
|
-
* @returns A non-dispatching command chain.
|
|
43090
|
-
* @example
|
|
43091
|
-
* const chain = CommandManager.createFakeChain()
|
|
43092
|
-
* chain.focus().run() // false
|
|
43093
|
-
*/
|
|
43094
|
-
static createFakeChain() {
|
|
43095
|
-
const chain = new Proxy({}, { get: (_target, property) => {
|
|
43096
|
-
if (property === "then") return;
|
|
43097
|
-
if (property === "run") return () => false;
|
|
43098
|
-
return () => chain;
|
|
43099
|
-
} });
|
|
43100
|
-
return chain;
|
|
43101
|
-
}
|
|
43102
|
-
createCan(startTr) {
|
|
43103
|
-
const { rawCommands, state } = this;
|
|
43104
|
-
const dispatch = false;
|
|
43105
|
-
const tr = startTr || state.tr;
|
|
43106
|
-
const props = this.buildProps(tr, dispatch);
|
|
43107
|
-
return {
|
|
43108
|
-
...Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43109
|
-
return [name, (...args) => command(...args)({
|
|
43110
|
-
...props,
|
|
43111
|
-
dispatch: void 0
|
|
43112
|
-
})];
|
|
43113
|
-
})),
|
|
43114
|
-
chain: () => this.createChain(tr, dispatch)
|
|
43115
|
-
};
|
|
43116
|
-
}
|
|
43117
|
-
/**
|
|
43118
|
-
* Creates capability checks that safely return `false`.
|
|
43119
|
-
* @returns A non-dispatching capability checker.
|
|
43120
|
-
* @example
|
|
43121
|
-
* const can = CommandManager.createFallbackCan()
|
|
43122
|
-
* can.focus() // false
|
|
43123
|
-
*/
|
|
43124
|
-
static createFallbackCan() {
|
|
43125
|
-
const chain = CommandManager.createFakeChain();
|
|
43126
|
-
return new Proxy({ chain: () => chain }, { get: (target, property) => {
|
|
43127
|
-
if (property === "then") return;
|
|
43128
|
-
if (property === "chain") return target.chain;
|
|
43129
|
-
return () => false;
|
|
43130
|
-
} });
|
|
43131
|
-
}
|
|
43132
|
-
buildProps(tr, shouldDispatch = true) {
|
|
43133
|
-
const { rawCommands, editor, state } = this;
|
|
43134
|
-
const { view } = editor;
|
|
43135
|
-
const props = {
|
|
43136
|
-
tr,
|
|
43137
|
-
editor,
|
|
43138
|
-
view,
|
|
43139
|
-
state: createChainableState({
|
|
43140
|
-
state,
|
|
43141
|
-
transaction: tr
|
|
43142
|
-
}),
|
|
43143
|
-
dispatch: shouldDispatch ? () => void 0 : void 0,
|
|
43144
|
-
chain: () => this.createChain(tr, shouldDispatch),
|
|
43145
|
-
can: () => this.createCan(tr),
|
|
43146
|
-
get commands() {
|
|
43147
|
-
return Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43148
|
-
return [name, (...args) => command(...args)(props)];
|
|
43149
|
-
}));
|
|
43150
|
-
}
|
|
43151
|
-
};
|
|
43152
|
-
return props;
|
|
43153
|
-
}
|
|
43154
|
-
};
|
|
43155
|
-
//#endregion
|
|
43156
|
-
//#region src/commands/blur.ts
|
|
43157
|
-
const blur = () => ({ editor, view }) => {
|
|
43158
|
-
requestAnimationFrame(() => {
|
|
43159
|
-
if (!editor.isDestroyed) {
|
|
43160
|
-
var _window;
|
|
43161
|
-
view.dom.blur();
|
|
43162
|
-
(_window = window) === null || _window === void 0 || (_window = _window.getSelection()) === null || _window === void 0 || _window.removeAllRanges();
|
|
43163
|
-
}
|
|
43164
|
-
});
|
|
43165
|
-
return true;
|
|
43166
|
-
};
|
|
43167
|
-
//#endregion
|
|
43168
|
-
//#region src/commands/clearContent.ts
|
|
43169
|
-
const clearContent = (emitUpdate = true) => ({ commands }) => {
|
|
43170
|
-
return commands.setContent("", { emitUpdate });
|
|
43171
|
-
};
|
|
43172
|
-
//#endregion
|
|
43173
|
-
//#region src/commands/clearNodes.ts
|
|
43174
|
-
const clearNodes = () => ({ state, tr, dispatch }) => {
|
|
43175
|
-
const { selection } = tr;
|
|
43176
|
-
const { ranges } = selection;
|
|
43177
|
-
if (!dispatch) return true;
|
|
43178
|
-
ranges.forEach(({ $from, $to }) => {
|
|
43179
|
-
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
43180
|
-
if (node.type.isText) return;
|
|
43181
|
-
const { doc, mapping } = tr;
|
|
43182
|
-
const $mappedFrom = doc.resolve(mapping.map(pos));
|
|
43183
|
-
const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize));
|
|
43184
|
-
const nodeRange = $mappedFrom.blockRange($mappedTo);
|
|
43185
|
-
if (!nodeRange) return;
|
|
43186
|
-
const targetLiftDepth = liftTarget(nodeRange);
|
|
43187
|
-
if (node.type.isTextblock) {
|
|
43188
|
-
const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index());
|
|
43189
|
-
tr.setNodeMarkup(nodeRange.start, defaultType);
|
|
43190
|
-
}
|
|
43191
|
-
if (targetLiftDepth || targetLiftDepth === 0) tr.lift(nodeRange, targetLiftDepth);
|
|
43192
|
-
});
|
|
43193
|
-
});
|
|
43194
|
-
return true;
|
|
43195
|
-
};
|
|
43196
|
-
//#endregion
|
|
43197
|
-
//#region src/commands/command.ts
|
|
43198
|
-
const command = (fn) => (props) => {
|
|
43199
|
-
return fn(props);
|
|
43200
|
-
};
|
|
43201
|
-
//#endregion
|
|
43202
|
-
//#region src/commands/createParagraphNear.ts
|
|
43203
|
-
const createParagraphNear$1 = () => ({ state, dispatch }) => {
|
|
43204
|
-
return createParagraphNear(state, dispatch);
|
|
43205
|
-
};
|
|
43206
|
-
//#endregion
|
|
43207
|
-
//#region src/commands/cut.ts
|
|
43208
|
-
const cut = (originRange, targetPos) => ({ editor, tr }) => {
|
|
43209
|
-
const { state } = editor;
|
|
43210
|
-
const contentSlice = state.doc.slice(originRange.from, originRange.to);
|
|
43211
|
-
tr.deleteRange(originRange.from, originRange.to);
|
|
43212
|
-
const newPos = tr.mapping.map(targetPos);
|
|
43213
|
-
tr.insert(newPos, contentSlice.content);
|
|
43214
|
-
tr.setSelection(new TextSelection(tr.doc.resolve(Math.max(newPos - 1, 0))));
|
|
43215
|
-
return true;
|
|
43216
|
-
};
|
|
43217
|
-
//#endregion
|
|
43218
|
-
//#region src/commands/deleteCurrentNode.ts
|
|
43219
|
-
const deleteCurrentNode = () => ({ tr, dispatch }) => {
|
|
43220
|
-
const { selection } = tr;
|
|
43221
|
-
const currentNode = selection.$anchor.node();
|
|
43222
|
-
if (currentNode.content.size > 0) return false;
|
|
43223
|
-
const $pos = tr.selection.$anchor;
|
|
43224
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === currentNode.type) {
|
|
43225
|
-
if (dispatch) {
|
|
43226
|
-
const from = $pos.before(depth);
|
|
43227
|
-
const to = $pos.after(depth);
|
|
43228
|
-
tr.delete(from, to).scrollIntoView();
|
|
43229
|
-
}
|
|
43230
|
-
return true;
|
|
43231
|
-
}
|
|
43232
|
-
return false;
|
|
43233
|
-
};
|
|
43234
|
-
//#endregion
|
|
43235
|
-
//#region src/helpers/getNodeType.ts
|
|
43236
|
-
function getNodeType(nameOrType, schema) {
|
|
43237
|
-
if (typeof nameOrType === "string") {
|
|
43238
|
-
if (!schema.nodes[nameOrType]) throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`);
|
|
43239
|
-
return schema.nodes[nameOrType];
|
|
43240
|
-
}
|
|
43241
|
-
return nameOrType;
|
|
43242
|
-
}
|
|
43243
|
-
//#endregion
|
|
43244
|
-
//#region src/commands/deleteNode.ts
|
|
43245
|
-
const deleteNode = (typeOrName) => ({ tr, state, dispatch }) => {
|
|
43246
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
43247
|
-
const $pos = tr.selection.$anchor;
|
|
43248
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === type) {
|
|
43249
|
-
if (dispatch) {
|
|
43250
|
-
const from = $pos.before(depth);
|
|
43251
|
-
const to = $pos.after(depth);
|
|
43252
|
-
tr.delete(from, to).scrollIntoView();
|
|
43253
|
-
}
|
|
43254
|
-
return true;
|
|
43255
|
-
}
|
|
43256
|
-
return false;
|
|
43016
|
+
var GOOD_LEAF_SIZE = 200;
|
|
43017
|
+
|
|
43018
|
+
// :: class<T> A rope sequence is a persistent sequence data structure
|
|
43019
|
+
// that supports appending, prepending, and slicing without doing a
|
|
43020
|
+
// full copy. It is represented as a mostly-balanced tree.
|
|
43021
|
+
var RopeSequence = function RopeSequence () {};
|
|
43022
|
+
|
|
43023
|
+
RopeSequence.prototype.append = function append (other) {
|
|
43024
|
+
if (!other.length) { return this }
|
|
43025
|
+
other = RopeSequence.from(other);
|
|
43026
|
+
|
|
43027
|
+
return (!this.length && other) ||
|
|
43028
|
+
(other.length < GOOD_LEAF_SIZE && this.leafAppend(other)) ||
|
|
43029
|
+
(this.length < GOOD_LEAF_SIZE && other.leafPrepend(this)) ||
|
|
43030
|
+
this.appendInner(other)
|
|
43257
43031
|
};
|
|
43258
|
-
|
|
43259
|
-
|
|
43260
|
-
|
|
43261
|
-
|
|
43262
|
-
|
|
43263
|
-
|
|
43032
|
+
|
|
43033
|
+
// :: (union<[T], RopeSequence<T>>) → RopeSequence<T>
|
|
43034
|
+
// Prepend an array or other rope to this one, returning a new rope.
|
|
43035
|
+
RopeSequence.prototype.prepend = function prepend (other) {
|
|
43036
|
+
if (!other.length) { return this }
|
|
43037
|
+
return RopeSequence.from(other).append(this)
|
|
43264
43038
|
};
|
|
43265
|
-
|
|
43266
|
-
|
|
43267
|
-
|
|
43268
|
-
* Check if a node has text content based on its content specification.
|
|
43269
|
-
* Returns true if the node's content spec matches text* or text+ patterns.
|
|
43270
|
-
*/
|
|
43271
|
-
const hasTextContent = (nodeSpec) => {
|
|
43272
|
-
if (!nodeSpec.content) return false;
|
|
43273
|
-
return /^text(\*|\+)/.test(nodeSpec.content);
|
|
43039
|
+
|
|
43040
|
+
RopeSequence.prototype.appendInner = function appendInner (other) {
|
|
43041
|
+
return new Append(this, other)
|
|
43274
43042
|
};
|
|
43275
|
-
|
|
43276
|
-
|
|
43277
|
-
|
|
43278
|
-
|
|
43279
|
-
|
|
43280
|
-
|
|
43281
|
-
|
|
43282
|
-
|
|
43283
|
-
|
|
43284
|
-
const expandSelectionForSide = ($pos, schema, side) => {
|
|
43285
|
-
if (!$pos.parent.isInline) return $pos.pos;
|
|
43286
|
-
if (side === "left" && $pos.pos > $pos.start() || side === "right" && $pos.pos < $pos.end()) return $pos.pos;
|
|
43287
|
-
const parentContent = schema.nodes[$pos.parent.type.name].spec;
|
|
43288
|
-
if (!hasTextContent(parentContent)) return $pos.pos;
|
|
43289
|
-
return side === "left" ? $pos.start() - 1 : $pos.end() + 1;
|
|
43043
|
+
|
|
43044
|
+
// :: (?number, ?number) → RopeSequence<T>
|
|
43045
|
+
// Create a rope repesenting a sub-sequence of this rope.
|
|
43046
|
+
RopeSequence.prototype.slice = function slice (from, to) {
|
|
43047
|
+
if ( from === void 0 ) from = 0;
|
|
43048
|
+
if ( to === void 0 ) to = this.length;
|
|
43049
|
+
|
|
43050
|
+
if (from >= to) { return RopeSequence.empty }
|
|
43051
|
+
return this.sliceInner(Math.max(0, from), Math.min(this.length, to))
|
|
43290
43052
|
};
|
|
43291
|
-
|
|
43292
|
-
|
|
43293
|
-
|
|
43294
|
-
|
|
43295
|
-
|
|
43296
|
-
|
|
43297
|
-
const expandSelectionForInlineText = ($from, $to, schema) => {
|
|
43298
|
-
return {
|
|
43299
|
-
from: expandSelectionForSide($from, schema, "left"),
|
|
43300
|
-
to: expandSelectionForSide($to, schema, "right")
|
|
43301
|
-
};
|
|
43053
|
+
|
|
43054
|
+
// :: (number) → T
|
|
43055
|
+
// Retrieve the element at the given position from this rope.
|
|
43056
|
+
RopeSequence.prototype.get = function get (i) {
|
|
43057
|
+
if (i < 0 || i >= this.length) { return undefined }
|
|
43058
|
+
return this.getInner(i)
|
|
43302
43059
|
};
|
|
43303
|
-
|
|
43304
|
-
|
|
43305
|
-
|
|
43306
|
-
|
|
43307
|
-
|
|
43308
|
-
|
|
43309
|
-
|
|
43310
|
-
|
|
43311
|
-
|
|
43312
|
-
|
|
43313
|
-
|
|
43314
|
-
|
|
43315
|
-
|
|
43316
|
-
|
|
43317
|
-
tr.scrollIntoView();
|
|
43318
|
-
dispatch(tr);
|
|
43319
|
-
}
|
|
43320
|
-
return true;
|
|
43060
|
+
|
|
43061
|
+
// :: ((element: T, index: number) → ?bool, ?number, ?number)
|
|
43062
|
+
// Call the given function for each element between the given
|
|
43063
|
+
// indices. This tends to be more efficient than looping over the
|
|
43064
|
+
// indices and calling `get`, because it doesn't have to descend the
|
|
43065
|
+
// tree for every element.
|
|
43066
|
+
RopeSequence.prototype.forEach = function forEach (f, from, to) {
|
|
43067
|
+
if ( from === void 0 ) from = 0;
|
|
43068
|
+
if ( to === void 0 ) to = this.length;
|
|
43069
|
+
|
|
43070
|
+
if (from <= to)
|
|
43071
|
+
{ this.forEachInner(f, from, to, 0); }
|
|
43072
|
+
else
|
|
43073
|
+
{ this.forEachInvertedInner(f, from, to, 0); }
|
|
43321
43074
|
};
|
|
43322
|
-
|
|
43323
|
-
|
|
43324
|
-
|
|
43325
|
-
|
|
43075
|
+
|
|
43076
|
+
// :: ((element: T, index: number) → U, ?number, ?number) → [U]
|
|
43077
|
+
// Map the given functions over the elements of the rope, producing
|
|
43078
|
+
// a flat array.
|
|
43079
|
+
RopeSequence.prototype.map = function map (f, from, to) {
|
|
43080
|
+
if ( from === void 0 ) from = 0;
|
|
43081
|
+
if ( to === void 0 ) to = this.length;
|
|
43082
|
+
|
|
43083
|
+
var result = [];
|
|
43084
|
+
this.forEach(function (elt, i) { return result.push(f(elt, i)); }, from, to);
|
|
43085
|
+
return result
|
|
43326
43086
|
};
|
|
43327
|
-
|
|
43328
|
-
|
|
43329
|
-
|
|
43330
|
-
|
|
43087
|
+
|
|
43088
|
+
// :: (?union<[T], RopeSequence<T>>) → RopeSequence<T>
|
|
43089
|
+
// Create a rope representing the given array, or return the rope
|
|
43090
|
+
// itself if a rope was given.
|
|
43091
|
+
RopeSequence.from = function from (values) {
|
|
43092
|
+
if (values instanceof RopeSequence) { return values }
|
|
43093
|
+
return values && values.length ? new Leaf(values) : RopeSequence.empty
|
|
43331
43094
|
};
|
|
43332
|
-
|
|
43333
|
-
|
|
43334
|
-
|
|
43335
|
-
|
|
43336
|
-
|
|
43337
|
-
|
|
43338
|
-
|
|
43339
|
-
|
|
43340
|
-
|
|
43341
|
-
|
|
43342
|
-
|
|
43343
|
-
|
|
43344
|
-
|
|
43345
|
-
|
|
43346
|
-
|
|
43347
|
-
|
|
43348
|
-
|
|
43349
|
-
|
|
43350
|
-
|
|
43351
|
-
|
|
43352
|
-
|
|
43353
|
-
|
|
43354
|
-
|
|
43355
|
-
|
|
43356
|
-
|
|
43357
|
-
|
|
43358
|
-
|
|
43359
|
-
|
|
43360
|
-
|
|
43361
|
-
|
|
43362
|
-
|
|
43363
|
-
|
|
43364
|
-
|
|
43365
|
-
|
|
43366
|
-
|
|
43367
|
-
|
|
43368
|
-
|
|
43369
|
-
|
|
43370
|
-
|
|
43371
|
-
|
|
43372
|
-
|
|
43373
|
-
|
|
43374
|
-
|
|
43375
|
-
|
|
43376
|
-
|
|
43377
|
-
|
|
43378
|
-
|
|
43379
|
-
|
|
43380
|
-
|
|
43381
|
-
|
|
43382
|
-
|
|
43383
|
-
|
|
43384
|
-
|
|
43385
|
-
|
|
43095
|
+
|
|
43096
|
+
var Leaf = /*@__PURE__*/(function (RopeSequence) {
|
|
43097
|
+
function Leaf(values) {
|
|
43098
|
+
RopeSequence.call(this);
|
|
43099
|
+
this.values = values;
|
|
43100
|
+
}
|
|
43101
|
+
|
|
43102
|
+
if ( RopeSequence ) Leaf.__proto__ = RopeSequence;
|
|
43103
|
+
Leaf.prototype = Object.create( RopeSequence && RopeSequence.prototype );
|
|
43104
|
+
Leaf.prototype.constructor = Leaf;
|
|
43105
|
+
|
|
43106
|
+
var prototypeAccessors = { length: { configurable: true },depth: { configurable: true } };
|
|
43107
|
+
|
|
43108
|
+
Leaf.prototype.flatten = function flatten () {
|
|
43109
|
+
return this.values
|
|
43110
|
+
};
|
|
43111
|
+
|
|
43112
|
+
Leaf.prototype.sliceInner = function sliceInner (from, to) {
|
|
43113
|
+
if (from == 0 && to == this.length) { return this }
|
|
43114
|
+
return new Leaf(this.values.slice(from, to))
|
|
43115
|
+
};
|
|
43116
|
+
|
|
43117
|
+
Leaf.prototype.getInner = function getInner (i) {
|
|
43118
|
+
return this.values[i]
|
|
43119
|
+
};
|
|
43120
|
+
|
|
43121
|
+
Leaf.prototype.forEachInner = function forEachInner (f, from, to, start) {
|
|
43122
|
+
for (var i = from; i < to; i++)
|
|
43123
|
+
{ if (f(this.values[i], start + i) === false) { return false } }
|
|
43124
|
+
};
|
|
43125
|
+
|
|
43126
|
+
Leaf.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
|
|
43127
|
+
for (var i = from - 1; i >= to; i--)
|
|
43128
|
+
{ if (f(this.values[i], start + i) === false) { return false } }
|
|
43129
|
+
};
|
|
43130
|
+
|
|
43131
|
+
Leaf.prototype.leafAppend = function leafAppend (other) {
|
|
43132
|
+
if (this.length + other.length <= GOOD_LEAF_SIZE)
|
|
43133
|
+
{ return new Leaf(this.values.concat(other.flatten())) }
|
|
43134
|
+
};
|
|
43135
|
+
|
|
43136
|
+
Leaf.prototype.leafPrepend = function leafPrepend (other) {
|
|
43137
|
+
if (this.length + other.length <= GOOD_LEAF_SIZE)
|
|
43138
|
+
{ return new Leaf(other.flatten().concat(this.values)) }
|
|
43139
|
+
};
|
|
43140
|
+
|
|
43141
|
+
prototypeAccessors.length.get = function () { return this.values.length };
|
|
43142
|
+
|
|
43143
|
+
prototypeAccessors.depth.get = function () { return 0 };
|
|
43144
|
+
|
|
43145
|
+
Object.defineProperties( Leaf.prototype, prototypeAccessors );
|
|
43146
|
+
|
|
43147
|
+
return Leaf;
|
|
43148
|
+
}(RopeSequence));
|
|
43149
|
+
|
|
43150
|
+
// :: RopeSequence
|
|
43151
|
+
// The empty rope sequence.
|
|
43152
|
+
RopeSequence.empty = new Leaf([]);
|
|
43153
|
+
|
|
43154
|
+
var Append = /*@__PURE__*/(function (RopeSequence) {
|
|
43155
|
+
function Append(left, right) {
|
|
43156
|
+
RopeSequence.call(this);
|
|
43157
|
+
this.left = left;
|
|
43158
|
+
this.right = right;
|
|
43159
|
+
this.length = left.length + right.length;
|
|
43160
|
+
this.depth = Math.max(left.depth, right.depth) + 1;
|
|
43161
|
+
}
|
|
43162
|
+
|
|
43163
|
+
if ( RopeSequence ) Append.__proto__ = RopeSequence;
|
|
43164
|
+
Append.prototype = Object.create( RopeSequence && RopeSequence.prototype );
|
|
43165
|
+
Append.prototype.constructor = Append;
|
|
43166
|
+
|
|
43167
|
+
Append.prototype.flatten = function flatten () {
|
|
43168
|
+
return this.left.flatten().concat(this.right.flatten())
|
|
43169
|
+
};
|
|
43170
|
+
|
|
43171
|
+
Append.prototype.getInner = function getInner (i) {
|
|
43172
|
+
return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length)
|
|
43173
|
+
};
|
|
43174
|
+
|
|
43175
|
+
Append.prototype.forEachInner = function forEachInner (f, from, to, start) {
|
|
43176
|
+
var leftLen = this.left.length;
|
|
43177
|
+
if (from < leftLen &&
|
|
43178
|
+
this.left.forEachInner(f, from, Math.min(to, leftLen), start) === false)
|
|
43179
|
+
{ return false }
|
|
43180
|
+
if (to > leftLen &&
|
|
43181
|
+
this.right.forEachInner(f, Math.max(from - leftLen, 0), Math.min(this.length, to) - leftLen, start + leftLen) === false)
|
|
43182
|
+
{ return false }
|
|
43183
|
+
};
|
|
43184
|
+
|
|
43185
|
+
Append.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
|
|
43186
|
+
var leftLen = this.left.length;
|
|
43187
|
+
if (from > leftLen &&
|
|
43188
|
+
this.right.forEachInvertedInner(f, from - leftLen, Math.max(to, leftLen) - leftLen, start + leftLen) === false)
|
|
43189
|
+
{ return false }
|
|
43190
|
+
if (to < leftLen &&
|
|
43191
|
+
this.left.forEachInvertedInner(f, Math.min(from, leftLen), to, start) === false)
|
|
43192
|
+
{ return false }
|
|
43193
|
+
};
|
|
43194
|
+
|
|
43195
|
+
Append.prototype.sliceInner = function sliceInner (from, to) {
|
|
43196
|
+
if (from == 0 && to == this.length) { return this }
|
|
43197
|
+
var leftLen = this.left.length;
|
|
43198
|
+
if (to <= leftLen) { return this.left.slice(from, to) }
|
|
43199
|
+
if (from >= leftLen) { return this.right.slice(from - leftLen, to - leftLen) }
|
|
43200
|
+
return this.left.slice(from, leftLen).append(this.right.slice(0, to - leftLen))
|
|
43201
|
+
};
|
|
43202
|
+
|
|
43203
|
+
Append.prototype.leafAppend = function leafAppend (other) {
|
|
43204
|
+
var inner = this.right.leafAppend(other);
|
|
43205
|
+
if (inner) { return new Append(this.left, inner) }
|
|
43206
|
+
};
|
|
43207
|
+
|
|
43208
|
+
Append.prototype.leafPrepend = function leafPrepend (other) {
|
|
43209
|
+
var inner = this.left.leafPrepend(other);
|
|
43210
|
+
if (inner) { return new Append(inner, this.right) }
|
|
43211
|
+
};
|
|
43212
|
+
|
|
43213
|
+
Append.prototype.appendInner = function appendInner (other) {
|
|
43214
|
+
if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1)
|
|
43215
|
+
{ return new Append(this.left, new Append(this.right, other)) }
|
|
43216
|
+
return new Append(this, other)
|
|
43217
|
+
};
|
|
43218
|
+
|
|
43219
|
+
return Append;
|
|
43220
|
+
}(RopeSequence));
|
|
43221
|
+
|
|
43222
|
+
// ProseMirror's history isn't simply a way to roll back to a previous
|
|
43223
|
+
// state, because ProseMirror supports applying changes without adding
|
|
43224
|
+
// them to the history (for example during collaboration).
|
|
43225
|
+
//
|
|
43226
|
+
// To this end, each 'Branch' (one for the undo history and one for
|
|
43227
|
+
// the redo history) keeps an array of 'Items', which can optionally
|
|
43228
|
+
// hold a step (an actual undoable change), and always hold a position
|
|
43229
|
+
// map (which is needed to move changes below them to apply to the
|
|
43230
|
+
// current document).
|
|
43231
|
+
//
|
|
43232
|
+
// An item that has both a step and a selection bookmark is the start
|
|
43233
|
+
// of an 'event' — a group of changes that will be undone or redone at
|
|
43234
|
+
// once. (It stores only the bookmark, since that way we don't have to
|
|
43235
|
+
// provide a document until the selection is actually applied, which
|
|
43236
|
+
// is useful when compressing.)
|
|
43237
|
+
// Used to schedule history compression
|
|
43238
|
+
const max_empty_items = 500;
|
|
43239
|
+
class Branch {
|
|
43240
|
+
constructor(items, eventCount) {
|
|
43241
|
+
this.items = items;
|
|
43242
|
+
this.eventCount = eventCount;
|
|
43243
|
+
}
|
|
43244
|
+
// Pop the latest event off the branch's history and apply it
|
|
43245
|
+
// to a document transform.
|
|
43246
|
+
popEvent(state, preserveItems) {
|
|
43247
|
+
if (this.eventCount == 0)
|
|
43248
|
+
return null;
|
|
43249
|
+
let end = this.items.length;
|
|
43250
|
+
for (;; end--) {
|
|
43251
|
+
let next = this.items.get(end - 1);
|
|
43252
|
+
if (next.selection) {
|
|
43253
|
+
--end;
|
|
43254
|
+
break;
|
|
43255
|
+
}
|
|
43256
|
+
}
|
|
43257
|
+
let remap, mapFrom;
|
|
43258
|
+
if (preserveItems) {
|
|
43259
|
+
remap = this.remapping(end, this.items.length);
|
|
43260
|
+
mapFrom = remap.maps.length;
|
|
43261
|
+
}
|
|
43262
|
+
let transform = state.tr;
|
|
43263
|
+
let selection, remaining;
|
|
43264
|
+
let addAfter = [], addBefore = [];
|
|
43265
|
+
this.items.forEach((item, i) => {
|
|
43266
|
+
if (!item.step) {
|
|
43267
|
+
if (!remap) {
|
|
43268
|
+
remap = this.remapping(end, i + 1);
|
|
43269
|
+
mapFrom = remap.maps.length;
|
|
43270
|
+
}
|
|
43271
|
+
mapFrom--;
|
|
43272
|
+
addBefore.push(item);
|
|
43273
|
+
return;
|
|
43274
|
+
}
|
|
43275
|
+
if (remap) {
|
|
43276
|
+
addBefore.push(new Item(item.map));
|
|
43277
|
+
let step = item.step.map(remap.slice(mapFrom)), map;
|
|
43278
|
+
if (step && transform.maybeStep(step).doc) {
|
|
43279
|
+
map = transform.mapping.maps[transform.mapping.maps.length - 1];
|
|
43280
|
+
addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length));
|
|
43281
|
+
}
|
|
43282
|
+
mapFrom--;
|
|
43283
|
+
if (map)
|
|
43284
|
+
remap.appendMap(map, mapFrom);
|
|
43285
|
+
}
|
|
43286
|
+
else {
|
|
43287
|
+
transform.maybeStep(item.step);
|
|
43288
|
+
}
|
|
43289
|
+
if (item.selection) {
|
|
43290
|
+
selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;
|
|
43291
|
+
remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1);
|
|
43292
|
+
return false;
|
|
43293
|
+
}
|
|
43294
|
+
}, this.items.length, 0);
|
|
43295
|
+
return { remaining: remaining, transform, selection: selection };
|
|
43296
|
+
}
|
|
43297
|
+
// Create a new branch with the given transform added.
|
|
43298
|
+
addTransform(transform, selection, histOptions, preserveItems) {
|
|
43299
|
+
let newItems = [], eventCount = this.eventCount;
|
|
43300
|
+
let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
|
|
43301
|
+
for (let i = 0; i < transform.steps.length; i++) {
|
|
43302
|
+
let step = transform.steps[i].invert(transform.docs[i]);
|
|
43303
|
+
let item = new Item(transform.mapping.maps[i], step, selection), merged;
|
|
43304
|
+
if (merged = lastItem && lastItem.merge(item)) {
|
|
43305
|
+
item = merged;
|
|
43306
|
+
if (i)
|
|
43307
|
+
newItems.pop();
|
|
43308
|
+
else
|
|
43309
|
+
oldItems = oldItems.slice(0, oldItems.length - 1);
|
|
43310
|
+
}
|
|
43311
|
+
newItems.push(item);
|
|
43312
|
+
if (selection) {
|
|
43313
|
+
eventCount++;
|
|
43314
|
+
selection = undefined;
|
|
43315
|
+
}
|
|
43316
|
+
if (!preserveItems)
|
|
43317
|
+
lastItem = item;
|
|
43318
|
+
}
|
|
43319
|
+
let overflow = eventCount - histOptions.depth;
|
|
43320
|
+
if (overflow > DEPTH_OVERFLOW) {
|
|
43321
|
+
oldItems = cutOffEvents(oldItems, overflow);
|
|
43322
|
+
eventCount -= overflow;
|
|
43323
|
+
}
|
|
43324
|
+
return new Branch(oldItems.append(newItems), eventCount);
|
|
43325
|
+
}
|
|
43326
|
+
remapping(from, to) {
|
|
43327
|
+
let maps = new Mapping;
|
|
43328
|
+
this.items.forEach((item, i) => {
|
|
43329
|
+
let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from
|
|
43330
|
+
? maps.maps.length - item.mirrorOffset : undefined;
|
|
43331
|
+
maps.appendMap(item.map, mirrorPos);
|
|
43332
|
+
}, from, to);
|
|
43333
|
+
return maps;
|
|
43334
|
+
}
|
|
43335
|
+
addMaps(array) {
|
|
43336
|
+
if (this.eventCount == 0)
|
|
43337
|
+
return this;
|
|
43338
|
+
return new Branch(this.items.append(array.map(map => new Item(map))), this.eventCount);
|
|
43339
|
+
}
|
|
43340
|
+
// When the collab module receives remote changes, the history has
|
|
43341
|
+
// to know about those, so that it can adjust the steps that were
|
|
43342
|
+
// rebased on top of the remote changes, and include the position
|
|
43343
|
+
// maps for the remote changes in its array of items.
|
|
43344
|
+
rebased(rebasedTransform, rebasedCount) {
|
|
43345
|
+
if (!this.eventCount)
|
|
43346
|
+
return this;
|
|
43347
|
+
rebasedCount = Math.min(this.items.length, rebasedCount);
|
|
43348
|
+
let rebasedItems = [], start = this.items.length - rebasedCount;
|
|
43349
|
+
let mapping = rebasedTransform.mapping;
|
|
43350
|
+
let newUntil = rebasedTransform.steps.length;
|
|
43351
|
+
let eventCount = this.eventCount;
|
|
43352
|
+
this.items.forEach(item => { if (item.selection)
|
|
43353
|
+
eventCount--; }, start);
|
|
43354
|
+
let iRebased = rebasedCount;
|
|
43355
|
+
this.items.forEach(item => {
|
|
43356
|
+
let pos = mapping.getMirror(--iRebased);
|
|
43357
|
+
if (pos == null)
|
|
43358
|
+
return;
|
|
43359
|
+
newUntil = Math.min(newUntil, pos);
|
|
43360
|
+
let map = mapping.maps[pos];
|
|
43361
|
+
if (item.step) {
|
|
43362
|
+
let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);
|
|
43363
|
+
let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
|
|
43364
|
+
if (selection)
|
|
43365
|
+
eventCount++;
|
|
43366
|
+
rebasedItems.push(new Item(map, step, selection));
|
|
43367
|
+
}
|
|
43368
|
+
else {
|
|
43369
|
+
rebasedItems.push(new Item(map));
|
|
43370
|
+
}
|
|
43371
|
+
}, start);
|
|
43372
|
+
let newMaps = [];
|
|
43373
|
+
for (let i = rebasedCount; i < newUntil; i++)
|
|
43374
|
+
newMaps.push(new Item(mapping.maps[i]));
|
|
43375
|
+
let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
|
|
43376
|
+
let branch = new Branch(items, eventCount);
|
|
43377
|
+
if (branch.emptyItemCount() > max_empty_items)
|
|
43378
|
+
branch = branch.compress(this.items.length - rebasedItems.length);
|
|
43379
|
+
return branch;
|
|
43380
|
+
}
|
|
43381
|
+
emptyItemCount() {
|
|
43382
|
+
let count = 0;
|
|
43383
|
+
this.items.forEach(item => { if (!item.step)
|
|
43384
|
+
count++; });
|
|
43385
|
+
return count;
|
|
43386
|
+
}
|
|
43387
|
+
// Compressing a branch means rewriting it to push the air (map-only
|
|
43388
|
+
// items) out. During collaboration, these naturally accumulate
|
|
43389
|
+
// because each remote change adds one. The `upto` argument is used
|
|
43390
|
+
// to ensure that only the items below a given level are compressed,
|
|
43391
|
+
// because `rebased` relies on a clean, untouched set of items in
|
|
43392
|
+
// order to associate old items with rebased steps.
|
|
43393
|
+
compress(upto = this.items.length) {
|
|
43394
|
+
let remap = this.remapping(0, upto), mapFrom = remap.maps.length;
|
|
43395
|
+
let items = [], events = 0;
|
|
43396
|
+
this.items.forEach((item, i) => {
|
|
43397
|
+
if (i >= upto) {
|
|
43398
|
+
items.push(item);
|
|
43399
|
+
if (item.selection)
|
|
43400
|
+
events++;
|
|
43401
|
+
}
|
|
43402
|
+
else if (item.step) {
|
|
43403
|
+
let step = item.step.map(remap.slice(mapFrom)), map = step && step.getMap();
|
|
43404
|
+
mapFrom--;
|
|
43405
|
+
if (map)
|
|
43406
|
+
remap.appendMap(map, mapFrom);
|
|
43407
|
+
if (step) {
|
|
43408
|
+
let selection = item.selection && item.selection.map(remap.slice(mapFrom));
|
|
43409
|
+
if (selection)
|
|
43410
|
+
events++;
|
|
43411
|
+
let newItem = new Item(map.invert(), step, selection), merged, last = items.length - 1;
|
|
43412
|
+
if (merged = items.length && items[last].merge(newItem))
|
|
43413
|
+
items[last] = merged;
|
|
43414
|
+
else
|
|
43415
|
+
items.push(newItem);
|
|
43416
|
+
}
|
|
43417
|
+
}
|
|
43418
|
+
else if (item.map) {
|
|
43419
|
+
mapFrom--;
|
|
43420
|
+
}
|
|
43421
|
+
}, this.items.length, 0);
|
|
43422
|
+
return new Branch(RopeSequence.from(items.reverse()), events);
|
|
43423
|
+
}
|
|
43424
|
+
}
|
|
43425
|
+
Branch.empty = new Branch(RopeSequence.empty, 0);
|
|
43426
|
+
function cutOffEvents(items, n) {
|
|
43427
|
+
let cutPoint;
|
|
43428
|
+
items.forEach((item, i) => {
|
|
43429
|
+
if (item.selection && (n-- == 0)) {
|
|
43430
|
+
cutPoint = i;
|
|
43431
|
+
return false;
|
|
43432
|
+
}
|
|
43433
|
+
});
|
|
43434
|
+
return items.slice(cutPoint);
|
|
43435
|
+
}
|
|
43436
|
+
class Item {
|
|
43437
|
+
constructor(
|
|
43438
|
+
// The (forward) step map for this item.
|
|
43439
|
+
map,
|
|
43440
|
+
// The inverted step
|
|
43441
|
+
step,
|
|
43442
|
+
// If this is non-null, this item is the start of a group, and
|
|
43443
|
+
// this selection is the starting selection for the group (the one
|
|
43444
|
+
// that was active before the first step was applied)
|
|
43445
|
+
selection,
|
|
43446
|
+
// If this item is the inverse of a previous mapping on the stack,
|
|
43447
|
+
// this points at the inverse's offset
|
|
43448
|
+
mirrorOffset) {
|
|
43449
|
+
this.map = map;
|
|
43450
|
+
this.step = step;
|
|
43451
|
+
this.selection = selection;
|
|
43452
|
+
this.mirrorOffset = mirrorOffset;
|
|
43453
|
+
}
|
|
43454
|
+
merge(other) {
|
|
43455
|
+
if (this.step && other.step && !other.selection) {
|
|
43456
|
+
let step = other.step.merge(this.step);
|
|
43457
|
+
if (step)
|
|
43458
|
+
return new Item(step.getMap().invert(), step, this.selection);
|
|
43459
|
+
}
|
|
43460
|
+
}
|
|
43461
|
+
}
|
|
43462
|
+
// The value of the state field that tracks undo/redo history for that
|
|
43463
|
+
// state. Will be stored in the plugin state when the history plugin
|
|
43464
|
+
// is active.
|
|
43465
|
+
class HistoryState {
|
|
43466
|
+
constructor(done, undone, prevRanges, prevTime, prevComposition) {
|
|
43467
|
+
this.done = done;
|
|
43468
|
+
this.undone = undone;
|
|
43469
|
+
this.prevRanges = prevRanges;
|
|
43470
|
+
this.prevTime = prevTime;
|
|
43471
|
+
this.prevComposition = prevComposition;
|
|
43472
|
+
}
|
|
43473
|
+
}
|
|
43474
|
+
const DEPTH_OVERFLOW = 20;
|
|
43475
|
+
// Record a transformation in undo history.
|
|
43476
|
+
function applyTransaction(history, state, tr, options) {
|
|
43477
|
+
let historyTr = tr.getMeta(historyKey), rebased;
|
|
43478
|
+
if (historyTr)
|
|
43479
|
+
return historyTr.historyState;
|
|
43480
|
+
if (tr.getMeta(closeHistoryKey))
|
|
43481
|
+
history = new HistoryState(history.done, history.undone, null, 0, -1);
|
|
43482
|
+
let appended = tr.getMeta("appendedTransaction");
|
|
43483
|
+
if (tr.steps.length == 0) {
|
|
43484
|
+
return history;
|
|
43485
|
+
}
|
|
43486
|
+
else if (appended && appended.getMeta(historyKey)) {
|
|
43487
|
+
if (appended.getMeta(historyKey).redo)
|
|
43488
|
+
return new HistoryState(history.done.addTransform(tr, undefined, options, mustPreserveItems(state)), history.undone, rangesFor(tr.mapping.maps), history.prevTime, history.prevComposition);
|
|
43489
|
+
else
|
|
43490
|
+
return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);
|
|
43491
|
+
}
|
|
43492
|
+
else if (tr.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) {
|
|
43493
|
+
// Group transforms that occur in quick succession into one event.
|
|
43494
|
+
let composition = tr.getMeta("composition");
|
|
43495
|
+
let newGroup = history.prevTime == 0 ||
|
|
43496
|
+
(!appended && history.prevComposition != composition &&
|
|
43497
|
+
(history.prevTime < (tr.time || 0) - options.newGroupDelay || !isAdjacentTo(tr, history.prevRanges)));
|
|
43498
|
+
let prevRanges = appended ? mapRanges(history.prevRanges, tr.mapping) : rangesFor(tr.mapping.maps);
|
|
43499
|
+
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);
|
|
43500
|
+
}
|
|
43501
|
+
else if (rebased = tr.getMeta("rebased")) {
|
|
43502
|
+
// Used by the collab module to tell the history that some of its
|
|
43503
|
+
// content has been rebased.
|
|
43504
|
+
return new HistoryState(history.done.rebased(tr, rebased), history.undone.rebased(tr, rebased), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
|
43505
|
+
}
|
|
43506
|
+
else {
|
|
43507
|
+
return new HistoryState(history.done.addMaps(tr.mapping.maps), history.undone.addMaps(tr.mapping.maps), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
|
43508
|
+
}
|
|
43509
|
+
}
|
|
43510
|
+
function isAdjacentTo(transform, prevRanges) {
|
|
43511
|
+
if (!prevRanges)
|
|
43512
|
+
return false;
|
|
43513
|
+
if (!transform.docChanged)
|
|
43514
|
+
return true;
|
|
43515
|
+
let adjacent = false;
|
|
43516
|
+
transform.mapping.maps[0].forEach((start, end) => {
|
|
43517
|
+
for (let i = 0; i < prevRanges.length; i += 2)
|
|
43518
|
+
if (start <= prevRanges[i + 1] && end >= prevRanges[i])
|
|
43519
|
+
adjacent = true;
|
|
43520
|
+
});
|
|
43521
|
+
return adjacent;
|
|
43522
|
+
}
|
|
43523
|
+
function rangesFor(maps) {
|
|
43524
|
+
let result = [];
|
|
43525
|
+
for (let i = maps.length - 1; i >= 0 && result.length == 0; i--)
|
|
43526
|
+
maps[i].forEach((_from, _to, from, to) => result.push(from, to));
|
|
43527
|
+
return result;
|
|
43528
|
+
}
|
|
43529
|
+
function mapRanges(ranges, mapping) {
|
|
43530
|
+
if (!ranges)
|
|
43531
|
+
return null;
|
|
43532
|
+
let result = [];
|
|
43533
|
+
for (let i = 0; i < ranges.length; i += 2) {
|
|
43534
|
+
let from = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1);
|
|
43535
|
+
if (from <= to)
|
|
43536
|
+
result.push(from, to);
|
|
43537
|
+
}
|
|
43538
|
+
return result;
|
|
43539
|
+
}
|
|
43540
|
+
// Apply the latest event from one branch to the document and shift the event
|
|
43541
|
+
// onto the other branch.
|
|
43542
|
+
function histTransaction(history, state, redo) {
|
|
43543
|
+
let preserveItems = mustPreserveItems(state);
|
|
43544
|
+
let histOptions = historyKey.get(state).spec.config;
|
|
43545
|
+
let pop = (redo ? history.undone : history.done).popEvent(state, preserveItems);
|
|
43546
|
+
if (!pop)
|
|
43547
|
+
return null;
|
|
43548
|
+
let selection = pop.selection.resolve(pop.transform.doc);
|
|
43549
|
+
let added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);
|
|
43550
|
+
let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1);
|
|
43551
|
+
return pop.transform.setSelection(selection).setMeta(historyKey, { redo, historyState: newHist });
|
|
43552
|
+
}
|
|
43553
|
+
let cachedPreserveItems = false, cachedPreserveItemsPlugins = null;
|
|
43554
|
+
// Check whether any plugin in the given state has a
|
|
43555
|
+
// `historyPreserveItems` property in its spec, in which case we must
|
|
43556
|
+
// preserve steps exactly as they came in, so that they can be
|
|
43557
|
+
// rebased.
|
|
43558
|
+
function mustPreserveItems(state) {
|
|
43559
|
+
let plugins = state.plugins;
|
|
43560
|
+
if (cachedPreserveItemsPlugins != plugins) {
|
|
43561
|
+
cachedPreserveItems = false;
|
|
43562
|
+
cachedPreserveItemsPlugins = plugins;
|
|
43563
|
+
for (let i = 0; i < plugins.length; i++)
|
|
43564
|
+
if (plugins[i].spec.historyPreserveItems) {
|
|
43565
|
+
cachedPreserveItems = true;
|
|
43566
|
+
break;
|
|
43567
|
+
}
|
|
43568
|
+
}
|
|
43569
|
+
return cachedPreserveItems;
|
|
43570
|
+
}
|
|
43571
|
+
/**
|
|
43572
|
+
Set a flag on the given transaction that will prevent further steps
|
|
43573
|
+
from being appended to an existing history event (so that they
|
|
43574
|
+
require a separate undo command to undo).
|
|
43575
|
+
*/
|
|
43576
|
+
function closeHistory(tr) {
|
|
43577
|
+
return tr.setMeta(closeHistoryKey, true);
|
|
43578
|
+
}
|
|
43579
|
+
const historyKey = new PluginKey("history");
|
|
43580
|
+
const closeHistoryKey = new PluginKey("closeHistory");
|
|
43581
|
+
/**
|
|
43582
|
+
Returns a plugin that enables the undo history for an editor. The
|
|
43583
|
+
plugin will track undo and redo stacks, which can be used with the
|
|
43584
|
+
[`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.
|
|
43585
|
+
|
|
43586
|
+
You can set an `"addToHistory"` [metadata
|
|
43587
|
+
property](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction
|
|
43588
|
+
to prevent it from being rolled back by undo.
|
|
43589
|
+
*/
|
|
43590
|
+
function history(config = {}) {
|
|
43591
|
+
config = { depth: config.depth || 100,
|
|
43592
|
+
newGroupDelay: config.newGroupDelay || 500 };
|
|
43593
|
+
return new Plugin({
|
|
43594
|
+
key: historyKey,
|
|
43595
|
+
state: {
|
|
43596
|
+
init() {
|
|
43597
|
+
return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);
|
|
43598
|
+
},
|
|
43599
|
+
apply(tr, hist, state) {
|
|
43600
|
+
return applyTransaction(hist, state, tr, config);
|
|
43601
|
+
}
|
|
43602
|
+
},
|
|
43603
|
+
config,
|
|
43604
|
+
props: {
|
|
43605
|
+
handleDOMEvents: {
|
|
43606
|
+
beforeinput(view, e) {
|
|
43607
|
+
let inputType = e.inputType;
|
|
43608
|
+
let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
|
|
43609
|
+
if (!command || !view.editable)
|
|
43610
|
+
return false;
|
|
43611
|
+
e.preventDefault();
|
|
43612
|
+
return command(view.state, view.dispatch);
|
|
43613
|
+
}
|
|
43614
|
+
}
|
|
43615
|
+
}
|
|
43616
|
+
});
|
|
43617
|
+
}
|
|
43618
|
+
function buildCommand(redo, scroll) {
|
|
43619
|
+
return (state, dispatch) => {
|
|
43620
|
+
let hist = historyKey.getState(state);
|
|
43621
|
+
if (!hist || (redo ? hist.undone : hist.done).eventCount == 0)
|
|
43622
|
+
return false;
|
|
43623
|
+
if (dispatch) {
|
|
43624
|
+
let tr = histTransaction(hist, state, redo);
|
|
43625
|
+
if (tr)
|
|
43626
|
+
dispatch(scroll ? tr.scrollIntoView() : tr);
|
|
43627
|
+
}
|
|
43628
|
+
return true;
|
|
43629
|
+
};
|
|
43630
|
+
}
|
|
43631
|
+
/**
|
|
43632
|
+
A command function that undoes the last change, if any.
|
|
43633
|
+
*/
|
|
43634
|
+
const undo = buildCommand(false, true);
|
|
43635
|
+
/**
|
|
43636
|
+
A command function that redoes the last undone change, if any.
|
|
43637
|
+
*/
|
|
43638
|
+
const redo = buildCommand(true, true);
|
|
43639
|
+
/**
|
|
43640
|
+
Returns true if the given transaction was generated by the history
|
|
43641
|
+
plugin.
|
|
43642
|
+
*/
|
|
43643
|
+
function isHistoryTransaction(tr) {
|
|
43644
|
+
return tr.getMeta(historyKey) != null;
|
|
43645
|
+
}
|
|
43646
|
+
|
|
43647
|
+
//#region src/helpers/createChainableState.ts
|
|
43648
|
+
/**
|
|
43649
|
+
* Takes a Transaction & Editor State and turns it into a chainable state object
|
|
43650
|
+
* @param config The transaction and state to create the chainable state from
|
|
43651
|
+
* @returns A chainable Editor state object
|
|
43652
|
+
*/
|
|
43653
|
+
function createChainableState(config) {
|
|
43654
|
+
const { state, transaction } = config;
|
|
43655
|
+
let { selection } = transaction;
|
|
43656
|
+
let { doc } = transaction;
|
|
43657
|
+
let { storedMarks } = transaction;
|
|
43658
|
+
return {
|
|
43659
|
+
...state,
|
|
43660
|
+
apply: state.apply.bind(state),
|
|
43661
|
+
applyTransaction: state.applyTransaction.bind(state),
|
|
43662
|
+
plugins: state.plugins,
|
|
43663
|
+
schema: state.schema,
|
|
43664
|
+
reconfigure: state.reconfigure.bind(state),
|
|
43665
|
+
toJSON: state.toJSON.bind(state),
|
|
43666
|
+
get storedMarks() {
|
|
43667
|
+
return storedMarks;
|
|
43668
|
+
},
|
|
43669
|
+
get selection() {
|
|
43670
|
+
return selection;
|
|
43671
|
+
},
|
|
43672
|
+
get doc() {
|
|
43673
|
+
return doc;
|
|
43674
|
+
},
|
|
43675
|
+
get tr() {
|
|
43676
|
+
selection = transaction.selection;
|
|
43677
|
+
doc = transaction.doc;
|
|
43678
|
+
storedMarks = transaction.storedMarks;
|
|
43679
|
+
return transaction;
|
|
43680
|
+
}
|
|
43681
|
+
};
|
|
43682
|
+
}
|
|
43683
|
+
//#endregion
|
|
43684
|
+
//#region src/CommandManager.ts
|
|
43685
|
+
var CommandManager = class CommandManager {
|
|
43686
|
+
constructor(props) {
|
|
43687
|
+
this.editor = props.editor;
|
|
43688
|
+
this.rawCommands = this.editor.extensionManager.commands;
|
|
43689
|
+
this.customState = props.state;
|
|
43690
|
+
}
|
|
43691
|
+
get hasCustomState() {
|
|
43692
|
+
return !!this.customState;
|
|
43693
|
+
}
|
|
43694
|
+
get state() {
|
|
43695
|
+
return this.customState || this.editor.state;
|
|
43696
|
+
}
|
|
43697
|
+
get commands() {
|
|
43698
|
+
const { rawCommands, editor, state } = this;
|
|
43699
|
+
const { view } = editor;
|
|
43700
|
+
const { tr } = state;
|
|
43701
|
+
const props = this.buildProps(tr);
|
|
43702
|
+
return Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43703
|
+
const method = (...args) => {
|
|
43704
|
+
const callback = command(...args)(props);
|
|
43705
|
+
if (!tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
|
|
43706
|
+
return callback;
|
|
43707
|
+
};
|
|
43708
|
+
return [name, method];
|
|
43709
|
+
}));
|
|
43710
|
+
}
|
|
43711
|
+
get chain() {
|
|
43712
|
+
return () => this.createChain();
|
|
43713
|
+
}
|
|
43714
|
+
get can() {
|
|
43715
|
+
return () => this.createCan();
|
|
43716
|
+
}
|
|
43717
|
+
createChain(startTr, shouldDispatch = true) {
|
|
43718
|
+
const { rawCommands, editor, state } = this;
|
|
43719
|
+
const { view } = editor;
|
|
43720
|
+
const callbacks = [];
|
|
43721
|
+
const hasStartTransaction = !!startTr;
|
|
43722
|
+
const tr = startTr || state.tr;
|
|
43723
|
+
const run = () => {
|
|
43724
|
+
if (!hasStartTransaction && shouldDispatch && !tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
|
|
43725
|
+
return callbacks.every((callback) => callback === true);
|
|
43726
|
+
};
|
|
43727
|
+
const chain = {
|
|
43728
|
+
...Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43729
|
+
const chainedCommand = (...args) => {
|
|
43730
|
+
const props = this.buildProps(tr, shouldDispatch);
|
|
43731
|
+
const callback = command(...args)(props);
|
|
43732
|
+
callbacks.push(callback);
|
|
43733
|
+
return chain;
|
|
43734
|
+
};
|
|
43735
|
+
return [name, chainedCommand];
|
|
43736
|
+
})),
|
|
43737
|
+
run
|
|
43738
|
+
};
|
|
43739
|
+
return chain;
|
|
43740
|
+
}
|
|
43741
|
+
/**
|
|
43742
|
+
* Creates a chain that safely returns `false` when run.
|
|
43743
|
+
* @returns A non-dispatching command chain.
|
|
43744
|
+
* @example
|
|
43745
|
+
* const chain = CommandManager.createFakeChain()
|
|
43746
|
+
* chain.focus().run() // false
|
|
43747
|
+
*/
|
|
43748
|
+
static createFakeChain() {
|
|
43749
|
+
const chain = new Proxy({}, { get: (_target, property) => {
|
|
43750
|
+
if (property === "then") return;
|
|
43751
|
+
if (property === "run") return () => false;
|
|
43752
|
+
return () => chain;
|
|
43753
|
+
} });
|
|
43754
|
+
return chain;
|
|
43755
|
+
}
|
|
43756
|
+
createCan(startTr) {
|
|
43757
|
+
const { rawCommands, state } = this;
|
|
43758
|
+
const dispatch = false;
|
|
43759
|
+
const tr = startTr || state.tr;
|
|
43760
|
+
const props = this.buildProps(tr, dispatch);
|
|
43761
|
+
return {
|
|
43762
|
+
...Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43763
|
+
return [name, (...args) => command(...args)({
|
|
43764
|
+
...props,
|
|
43765
|
+
dispatch: void 0
|
|
43766
|
+
})];
|
|
43767
|
+
})),
|
|
43768
|
+
chain: () => this.createChain(tr, dispatch)
|
|
43769
|
+
};
|
|
43770
|
+
}
|
|
43771
|
+
/**
|
|
43772
|
+
* Creates capability checks that safely return `false`.
|
|
43773
|
+
* @returns A non-dispatching capability checker.
|
|
43774
|
+
* @example
|
|
43775
|
+
* const can = CommandManager.createFallbackCan()
|
|
43776
|
+
* can.focus() // false
|
|
43777
|
+
*/
|
|
43778
|
+
static createFallbackCan() {
|
|
43779
|
+
const chain = CommandManager.createFakeChain();
|
|
43780
|
+
return new Proxy({ chain: () => chain }, { get: (target, property) => {
|
|
43781
|
+
if (property === "then") return;
|
|
43782
|
+
if (property === "chain") return target.chain;
|
|
43783
|
+
return () => false;
|
|
43784
|
+
} });
|
|
43785
|
+
}
|
|
43786
|
+
buildProps(tr, shouldDispatch = true) {
|
|
43787
|
+
const { rawCommands, editor, state } = this;
|
|
43788
|
+
const { view } = editor;
|
|
43789
|
+
const props = {
|
|
43790
|
+
tr,
|
|
43791
|
+
editor,
|
|
43792
|
+
view,
|
|
43793
|
+
state: createChainableState({
|
|
43794
|
+
state,
|
|
43795
|
+
transaction: tr
|
|
43796
|
+
}),
|
|
43797
|
+
dispatch: shouldDispatch ? () => void 0 : void 0,
|
|
43798
|
+
chain: () => this.createChain(tr, shouldDispatch),
|
|
43799
|
+
can: () => this.createCan(tr),
|
|
43800
|
+
get commands() {
|
|
43801
|
+
return Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43802
|
+
return [name, (...args) => command(...args)(props)];
|
|
43803
|
+
}));
|
|
43804
|
+
}
|
|
43805
|
+
};
|
|
43806
|
+
return props;
|
|
43807
|
+
}
|
|
43808
|
+
};
|
|
43809
|
+
//#endregion
|
|
43810
|
+
//#region src/commands/blur.ts
|
|
43811
|
+
const blur = () => ({ editor, view }) => {
|
|
43812
|
+
requestAnimationFrame(() => {
|
|
43813
|
+
if (!editor.isDestroyed) {
|
|
43814
|
+
var _window;
|
|
43815
|
+
view.dom.blur();
|
|
43816
|
+
(_window = window) === null || _window === void 0 || (_window = _window.getSelection()) === null || _window === void 0 || _window.removeAllRanges();
|
|
43817
|
+
}
|
|
43818
|
+
});
|
|
43819
|
+
return true;
|
|
43820
|
+
};
|
|
43821
|
+
//#endregion
|
|
43822
|
+
//#region src/commands/clearContent.ts
|
|
43823
|
+
const clearContent = (emitUpdate = true) => ({ commands }) => {
|
|
43824
|
+
return commands.setContent("", { emitUpdate });
|
|
43825
|
+
};
|
|
43826
|
+
//#endregion
|
|
43827
|
+
//#region src/commands/clearNodes.ts
|
|
43828
|
+
const clearNodes = () => ({ state, tr, dispatch }) => {
|
|
43829
|
+
const { selection } = tr;
|
|
43830
|
+
const { ranges } = selection;
|
|
43831
|
+
if (!dispatch) return true;
|
|
43832
|
+
ranges.forEach(({ $from, $to }) => {
|
|
43833
|
+
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
43834
|
+
if (node.type.isText) return;
|
|
43835
|
+
const { doc, mapping } = tr;
|
|
43836
|
+
const $mappedFrom = doc.resolve(mapping.map(pos));
|
|
43837
|
+
const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize));
|
|
43838
|
+
const nodeRange = $mappedFrom.blockRange($mappedTo);
|
|
43839
|
+
if (!nodeRange) return;
|
|
43840
|
+
const targetLiftDepth = liftTarget(nodeRange);
|
|
43841
|
+
if (node.type.isTextblock) {
|
|
43842
|
+
const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index());
|
|
43843
|
+
tr.setNodeMarkup(nodeRange.start, defaultType);
|
|
43844
|
+
}
|
|
43845
|
+
if (targetLiftDepth || targetLiftDepth === 0) tr.lift(nodeRange, targetLiftDepth);
|
|
43846
|
+
});
|
|
43847
|
+
});
|
|
43848
|
+
return true;
|
|
43849
|
+
};
|
|
43850
|
+
//#endregion
|
|
43851
|
+
//#region src/commands/command.ts
|
|
43852
|
+
const command = (fn) => (props) => {
|
|
43853
|
+
return fn(props);
|
|
43854
|
+
};
|
|
43855
|
+
//#endregion
|
|
43856
|
+
//#region src/commands/createParagraphNear.ts
|
|
43857
|
+
const createParagraphNear$1 = () => ({ state, dispatch }) => {
|
|
43858
|
+
return createParagraphNear(state, dispatch);
|
|
43859
|
+
};
|
|
43860
|
+
//#endregion
|
|
43861
|
+
//#region src/commands/cut.ts
|
|
43862
|
+
const cut = (originRange, targetPos) => ({ editor, tr }) => {
|
|
43863
|
+
const { state } = editor;
|
|
43864
|
+
const contentSlice = state.doc.slice(originRange.from, originRange.to);
|
|
43865
|
+
tr.deleteRange(originRange.from, originRange.to);
|
|
43866
|
+
const newPos = tr.mapping.map(targetPos);
|
|
43867
|
+
tr.insert(newPos, contentSlice.content);
|
|
43868
|
+
tr.setSelection(new TextSelection(tr.doc.resolve(Math.max(newPos - 1, 0))));
|
|
43869
|
+
return true;
|
|
43870
|
+
};
|
|
43871
|
+
//#endregion
|
|
43872
|
+
//#region src/commands/deleteCurrentNode.ts
|
|
43873
|
+
const deleteCurrentNode = () => ({ tr, dispatch }) => {
|
|
43874
|
+
const { selection } = tr;
|
|
43875
|
+
const currentNode = selection.$anchor.node();
|
|
43876
|
+
if (currentNode.content.size > 0) return false;
|
|
43877
|
+
const $pos = tr.selection.$anchor;
|
|
43878
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === currentNode.type) {
|
|
43879
|
+
if (dispatch) {
|
|
43880
|
+
const from = $pos.before(depth);
|
|
43881
|
+
const to = $pos.after(depth);
|
|
43882
|
+
tr.delete(from, to).scrollIntoView();
|
|
43883
|
+
}
|
|
43884
|
+
return true;
|
|
43885
|
+
}
|
|
43886
|
+
return false;
|
|
43887
|
+
};
|
|
43888
|
+
//#endregion
|
|
43889
|
+
//#region src/helpers/getNodeType.ts
|
|
43890
|
+
function getNodeType(nameOrType, schema) {
|
|
43891
|
+
if (typeof nameOrType === "string") {
|
|
43892
|
+
if (!schema.nodes[nameOrType]) throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`);
|
|
43893
|
+
return schema.nodes[nameOrType];
|
|
43894
|
+
}
|
|
43895
|
+
return nameOrType;
|
|
43896
|
+
}
|
|
43897
|
+
//#endregion
|
|
43898
|
+
//#region src/commands/deleteNode.ts
|
|
43899
|
+
const deleteNode = (typeOrName) => ({ tr, state, dispatch }) => {
|
|
43900
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
43901
|
+
const $pos = tr.selection.$anchor;
|
|
43902
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === type) {
|
|
43903
|
+
if (dispatch) {
|
|
43904
|
+
const from = $pos.before(depth);
|
|
43905
|
+
const to = $pos.after(depth);
|
|
43906
|
+
tr.delete(from, to).scrollIntoView();
|
|
43907
|
+
}
|
|
43908
|
+
return true;
|
|
43909
|
+
}
|
|
43910
|
+
return false;
|
|
43911
|
+
};
|
|
43912
|
+
//#endregion
|
|
43913
|
+
//#region src/commands/deleteRange.ts
|
|
43914
|
+
const deleteRange = (range) => ({ tr, dispatch }) => {
|
|
43915
|
+
const { from, to } = range;
|
|
43916
|
+
if (dispatch) tr.delete(from, to);
|
|
43917
|
+
return true;
|
|
43918
|
+
};
|
|
43919
|
+
//#endregion
|
|
43920
|
+
//#region src/commands/deleteSelection.ts
|
|
43921
|
+
/**
|
|
43922
|
+
* Check if a node has text content based on its content specification.
|
|
43923
|
+
* Returns true if the node's content spec matches text* or text+ patterns.
|
|
43924
|
+
*/
|
|
43925
|
+
const hasTextContent = (nodeSpec) => {
|
|
43926
|
+
if (!nodeSpec.content) return false;
|
|
43927
|
+
return /^text(\*|\+)/.test(nodeSpec.content);
|
|
43928
|
+
};
|
|
43929
|
+
/**
|
|
43930
|
+
* Expand selection position for a specific side (left or right) to handle inline text nodes.
|
|
43931
|
+
* This function checks if the position is within an inline node with text content and
|
|
43932
|
+
* expands it to include the entire node boundaries for proper deletion.
|
|
43933
|
+
* @param $pos - The resolved position to expand
|
|
43934
|
+
* @param schema - The ProseMirror schema
|
|
43935
|
+
* @param side - Which side to expand ('left' or 'right')
|
|
43936
|
+
* @returns The expanded position for deletion
|
|
43937
|
+
*/
|
|
43938
|
+
const expandSelectionForSide = ($pos, schema, side) => {
|
|
43939
|
+
if (!$pos.parent.isInline) return $pos.pos;
|
|
43940
|
+
if (side === "left" && $pos.pos > $pos.start() || side === "right" && $pos.pos < $pos.end()) return $pos.pos;
|
|
43941
|
+
const parentContent = schema.nodes[$pos.parent.type.name].spec;
|
|
43942
|
+
if (!hasTextContent(parentContent)) return $pos.pos;
|
|
43943
|
+
return side === "left" ? $pos.start() - 1 : $pos.end() + 1;
|
|
43944
|
+
};
|
|
43945
|
+
/**
|
|
43946
|
+
* Expand selection range to properly handle deletion of inline text nodes.
|
|
43947
|
+
* Inline text nodes don't collapse correctly when text inside is deleted,
|
|
43948
|
+
* so we need to expand the selection to include the entire node.
|
|
43949
|
+
* See: https://code.haverbeke.berlin/prosemirror/prosemirror/issues/1365
|
|
43950
|
+
*/
|
|
43951
|
+
const expandSelectionForInlineText = ($from, $to, schema) => {
|
|
43952
|
+
return {
|
|
43953
|
+
from: expandSelectionForSide($from, schema, "left"),
|
|
43954
|
+
to: expandSelectionForSide($to, schema, "right")
|
|
43955
|
+
};
|
|
43956
|
+
};
|
|
43957
|
+
const deleteSelection = () => ({ state, dispatch }) => {
|
|
43958
|
+
if (state.selection.empty) return false;
|
|
43959
|
+
if (dispatch) {
|
|
43960
|
+
const tr = state.tr;
|
|
43961
|
+
const { ranges } = state.selection;
|
|
43962
|
+
const mapFrom = tr.steps.length;
|
|
43963
|
+
ranges.forEach((range) => {
|
|
43964
|
+
const mapping = tr.mapping.slice(mapFrom);
|
|
43965
|
+
const $from = tr.doc.resolve(mapping.map(range.$from.pos));
|
|
43966
|
+
const $to = tr.doc.resolve(mapping.map(range.$to.pos));
|
|
43967
|
+
const { from, to } = expandSelectionForInlineText($from, $to, state.schema);
|
|
43968
|
+
tr.deleteRange(from, to);
|
|
43969
|
+
});
|
|
43970
|
+
if (!tr.selection.empty) tr.setSelection(TextSelection.near(tr.doc.resolve(tr.selection.from)));
|
|
43971
|
+
tr.scrollIntoView();
|
|
43972
|
+
dispatch(tr);
|
|
43973
|
+
}
|
|
43974
|
+
return true;
|
|
43975
|
+
};
|
|
43976
|
+
//#endregion
|
|
43977
|
+
//#region src/commands/enter.ts
|
|
43978
|
+
const enter = () => ({ commands }) => {
|
|
43979
|
+
return commands.keyboardShortcut("Enter");
|
|
43980
|
+
};
|
|
43981
|
+
//#endregion
|
|
43982
|
+
//#region src/commands/exitCode.ts
|
|
43983
|
+
const exitCode$1 = () => ({ state, dispatch }) => {
|
|
43984
|
+
return exitCode(state, dispatch);
|
|
43985
|
+
};
|
|
43986
|
+
//#endregion
|
|
43987
|
+
//#region src/utilities/isRegExp.ts
|
|
43988
|
+
function isRegExp$1(value) {
|
|
43989
|
+
return Object.prototype.toString.call(value) === "[object RegExp]";
|
|
43990
|
+
}
|
|
43991
|
+
//#endregion
|
|
43992
|
+
//#region src/utilities/objectIncludes.ts
|
|
43993
|
+
/**
|
|
43994
|
+
* Check if object1 includes object2
|
|
43995
|
+
* @param object1 Object
|
|
43996
|
+
* @param object2 Object
|
|
43997
|
+
*/
|
|
43998
|
+
function objectIncludes(object1, object2, options = { strict: true }) {
|
|
43999
|
+
const keys = Object.keys(object2);
|
|
44000
|
+
if (!keys.length) return true;
|
|
44001
|
+
return keys.every((key) => {
|
|
44002
|
+
if (options.strict) return object2[key] === object1[key];
|
|
44003
|
+
if (isRegExp$1(object2[key])) return object2[key].test(object1[key]);
|
|
44004
|
+
return object2[key] === object1[key];
|
|
44005
|
+
});
|
|
44006
|
+
}
|
|
44007
|
+
//#endregion
|
|
44008
|
+
//#region src/helpers/getMarkRange.ts
|
|
44009
|
+
function findMarkInSet(marks, type, attributes = {}) {
|
|
44010
|
+
return marks.find((item) => {
|
|
44011
|
+
return item.type === type && objectIncludes(Object.fromEntries(Object.keys(attributes).map((k) => [k, item.attrs[k]])), attributes);
|
|
44012
|
+
});
|
|
44013
|
+
}
|
|
44014
|
+
function isMarkInSet(marks, type, attributes = {}) {
|
|
44015
|
+
return !!findMarkInSet(marks, type, attributes);
|
|
44016
|
+
}
|
|
44017
|
+
/**
|
|
44018
|
+
* Get the range of a mark at a resolved position.
|
|
44019
|
+
*/
|
|
44020
|
+
function getMarkRange($pos, type, attributes) {
|
|
44021
|
+
if (!$pos || !type) return;
|
|
44022
|
+
let start = $pos.parent.childAfter($pos.parentOffset);
|
|
44023
|
+
if (!start.node || !start.node.marks.some((mark) => mark.type === type)) start = $pos.parent.childBefore($pos.parentOffset);
|
|
44024
|
+
if (!start.node || !start.node.marks.some((mark) => mark.type === type)) return;
|
|
44025
|
+
if (!attributes) {
|
|
44026
|
+
const firstMark = start.node.marks.find((mark) => mark.type === type);
|
|
44027
|
+
if (firstMark) attributes = firstMark.attrs;
|
|
44028
|
+
}
|
|
44029
|
+
if (!findMarkInSet([...start.node.marks], type, attributes)) return;
|
|
44030
|
+
let startIndex = start.index;
|
|
44031
|
+
let startPos = $pos.start() + start.offset;
|
|
44032
|
+
let endIndex = startIndex + 1;
|
|
44033
|
+
let endPos = startPos + start.node.nodeSize;
|
|
44034
|
+
while (startIndex > 0 && isMarkInSet([...$pos.parent.child(startIndex - 1).marks], type, attributes)) {
|
|
44035
|
+
startIndex -= 1;
|
|
44036
|
+
startPos -= $pos.parent.child(startIndex).nodeSize;
|
|
44037
|
+
}
|
|
44038
|
+
while (endIndex < $pos.parent.childCount && isMarkInSet([...$pos.parent.child(endIndex).marks], type, attributes)) {
|
|
44039
|
+
endPos += $pos.parent.child(endIndex).nodeSize;
|
|
43386
44040
|
endIndex += 1;
|
|
43387
44041
|
}
|
|
43388
44042
|
return {
|
|
@@ -43792,11 +44446,21 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
43792
44446
|
return joinForward(state, dispatch);
|
|
43793
44447
|
};
|
|
43794
44448
|
//#endregion
|
|
44449
|
+
//#region src/commands/canJoinItemsAt.ts
|
|
44450
|
+
const canJoinItemsAt = (doc, pos) => {
|
|
44451
|
+
const $pos = doc.resolve(pos);
|
|
44452
|
+
const before = $pos.nodeBefore;
|
|
44453
|
+
const after = $pos.nodeAfter;
|
|
44454
|
+
if (!before || !after) return false;
|
|
44455
|
+
return !before.type.spec.isolating && !after.type.spec.isolating;
|
|
44456
|
+
};
|
|
44457
|
+
//#endregion
|
|
43795
44458
|
//#region src/commands/joinItemBackward.ts
|
|
43796
44459
|
const joinItemBackward = () => ({ state, dispatch, tr }) => {
|
|
43797
44460
|
try {
|
|
43798
44461
|
const point = joinPoint(state.doc, state.selection.$from.pos, -1);
|
|
43799
44462
|
if (point === null || point === void 0) return false;
|
|
44463
|
+
if (!canJoinItemsAt(state.doc, point)) return false;
|
|
43800
44464
|
tr.join(point, 2);
|
|
43801
44465
|
if (dispatch) dispatch(tr);
|
|
43802
44466
|
return true;
|
|
@@ -43810,6 +44474,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
43810
44474
|
try {
|
|
43811
44475
|
const point = joinPoint(state.doc, state.selection.$from.pos, 1);
|
|
43812
44476
|
if (point === null || point === void 0) return false;
|
|
44477
|
+
if (!canJoinItemsAt(state.doc, point)) return false;
|
|
43813
44478
|
tr.join(point, 2);
|
|
43814
44479
|
if (dispatch) dispatch(tr);
|
|
43815
44480
|
return true;
|
|
@@ -45216,8 +45881,14 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45216
45881
|
type: deflt,
|
|
45217
45882
|
attrs: newAttributes
|
|
45218
45883
|
}] : void 0;
|
|
45219
|
-
|
|
45220
|
-
|
|
45884
|
+
const deletedTr = selection instanceof TextSelection && !selection.empty ? EditorState.create({
|
|
45885
|
+
doc: tr.doc,
|
|
45886
|
+
selection
|
|
45887
|
+
}).tr.deleteSelection() : null;
|
|
45888
|
+
const splitDoc = deletedTr ? deletedTr.doc : tr.doc;
|
|
45889
|
+
const splitPos = deletedTr ? deletedTr.mapping.map($from.pos) : $from.pos;
|
|
45890
|
+
let can = canSplit(splitDoc, splitPos, 1, types);
|
|
45891
|
+
if (!types && !can && canSplit(splitDoc, splitPos, 1, deflt ? [{ type: deflt }] : void 0)) {
|
|
45221
45892
|
can = true;
|
|
45222
45893
|
types = deflt ? [{
|
|
45223
45894
|
type: deflt,
|
|
@@ -45226,12 +45897,13 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45226
45897
|
}
|
|
45227
45898
|
if (dispatch) {
|
|
45228
45899
|
if (can) {
|
|
45900
|
+
const mapFrom = tr.steps.length;
|
|
45229
45901
|
if (selection instanceof TextSelection) tr.deleteSelection();
|
|
45230
|
-
tr.split(tr.mapping.map($from.pos), 1, types);
|
|
45902
|
+
tr.split(tr.mapping.slice(mapFrom).map($from.pos), 1, types);
|
|
45231
45903
|
if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) {
|
|
45232
|
-
const first = tr.mapping.map($from.before());
|
|
45904
|
+
const first = tr.mapping.slice(mapFrom).map($from.before());
|
|
45233
45905
|
const $first = tr.doc.resolve(first);
|
|
45234
|
-
if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) tr.setNodeMarkup(tr.mapping.map($from.before()), deflt);
|
|
45906
|
+
if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) tr.setNodeMarkup(tr.mapping.slice(mapFrom).map($from.before()), deflt);
|
|
45235
45907
|
}
|
|
45236
45908
|
}
|
|
45237
45909
|
if (keepMarks) ensureMarks(state, editor.extensionManager.splittableMarks);
|
|
@@ -45284,16 +45956,19 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45284
45956
|
...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
|
|
45285
45957
|
...overrideAttrs
|
|
45286
45958
|
};
|
|
45959
|
+
const splitsAtStartOfItem = $from.parentOffset === 0 && $from.index(-1) === 0;
|
|
45960
|
+
const itemStart = $from.before(-1);
|
|
45287
45961
|
tr.delete($from.pos, $to.pos);
|
|
45962
|
+
const trailingTypeAttributes = splitsAtStartOfItem ? grandParent.attrs : newTypeAttributes;
|
|
45288
45963
|
const types = nextType ? [{
|
|
45289
45964
|
type,
|
|
45290
|
-
attrs:
|
|
45965
|
+
attrs: trailingTypeAttributes
|
|
45291
45966
|
}, {
|
|
45292
45967
|
type: nextType,
|
|
45293
45968
|
attrs: newNextTypeAttributes
|
|
45294
45969
|
}] : [{
|
|
45295
45970
|
type,
|
|
45296
|
-
attrs:
|
|
45971
|
+
attrs: trailingTypeAttributes
|
|
45297
45972
|
}];
|
|
45298
45973
|
if (!canSplit(tr.doc, $from.pos, 2)) return false;
|
|
45299
45974
|
if (dispatch) {
|
|
@@ -45301,6 +45976,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45301
45976
|
const { splittableMarks } = editor.extensionManager;
|
|
45302
45977
|
const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
|
|
45303
45978
|
tr.split($from.pos, 2, types).scrollIntoView();
|
|
45979
|
+
if (splitsAtStartOfItem) tr.setNodeMarkup(itemStart, void 0, newTypeAttributes);
|
|
45304
45980
|
if (!marks || !dispatch) return true;
|
|
45305
45981
|
const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
|
|
45306
45982
|
tr.ensureMarks(filteredMarks);
|
|
@@ -46833,55 +47509,106 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
46833
47509
|
}
|
|
46834
47510
|
return result;
|
|
46835
47511
|
};
|
|
47512
|
+
/**
|
|
47513
|
+
* Prepares the typed text so the rule handler can inspect the resulting document.
|
|
47514
|
+
*/
|
|
47515
|
+
function createRuleTransaction(config) {
|
|
47516
|
+
const { editor, from, to, text, insertText } = config;
|
|
47517
|
+
if (!insertText) return {
|
|
47518
|
+
inputTransaction: null,
|
|
47519
|
+
tr: editor.view.state.tr
|
|
47520
|
+
};
|
|
47521
|
+
const inputTransaction = editor.view.state.tr.insertText(text, from, to);
|
|
47522
|
+
return {
|
|
47523
|
+
inputTransaction,
|
|
47524
|
+
tr: EditorState.create({
|
|
47525
|
+
doc: inputTransaction.doc,
|
|
47526
|
+
selection: inputTransaction.selection,
|
|
47527
|
+
storedMarks: inputTransaction.storedMarks
|
|
47528
|
+
}).tr
|
|
47529
|
+
};
|
|
47530
|
+
}
|
|
47531
|
+
/**
|
|
47532
|
+
* Runs a matching rule and dispatches the typed text before its conversion.
|
|
47533
|
+
*/
|
|
47534
|
+
function applyRule(config) {
|
|
47535
|
+
const { editor, from, to, text, rule, match, plugin, insertText } = config;
|
|
47536
|
+
const { view } = editor;
|
|
47537
|
+
const { inputTransaction, tr } = createRuleTransaction({
|
|
47538
|
+
editor,
|
|
47539
|
+
from,
|
|
47540
|
+
to,
|
|
47541
|
+
text,
|
|
47542
|
+
insertText
|
|
47543
|
+
});
|
|
47544
|
+
const inputEnd = inputTransaction ? from + text.length : to;
|
|
47545
|
+
const state = createChainableState({
|
|
47546
|
+
state: view.state,
|
|
47547
|
+
transaction: tr
|
|
47548
|
+
});
|
|
47549
|
+
const range = {
|
|
47550
|
+
from: from - (match[0].length - text.length),
|
|
47551
|
+
to: inputEnd
|
|
47552
|
+
};
|
|
47553
|
+
const { commands, chain, can } = new CommandManager({
|
|
47554
|
+
editor,
|
|
47555
|
+
state
|
|
47556
|
+
});
|
|
47557
|
+
if (rule.handler({
|
|
47558
|
+
state,
|
|
47559
|
+
range,
|
|
47560
|
+
match,
|
|
47561
|
+
commands,
|
|
47562
|
+
chain,
|
|
47563
|
+
can
|
|
47564
|
+
}) === null || !tr.steps.length) return false;
|
|
47565
|
+
if (inputTransaction) {
|
|
47566
|
+
view.dispatch(inputTransaction);
|
|
47567
|
+
if (!view.state.doc.eq(inputTransaction.doc)) return true;
|
|
47568
|
+
}
|
|
47569
|
+
closeHistory(tr);
|
|
47570
|
+
tr.setMeta("inputRule", true);
|
|
47571
|
+
if (rule.undoable) tr.setMeta(plugin, {
|
|
47572
|
+
transform: tr,
|
|
47573
|
+
from,
|
|
47574
|
+
to: inputEnd,
|
|
47575
|
+
text
|
|
47576
|
+
});
|
|
47577
|
+
view.dispatch(tr);
|
|
47578
|
+
return true;
|
|
47579
|
+
}
|
|
47580
|
+
/**
|
|
47581
|
+
* Checks that the part of a match already in the document has matching positions.
|
|
47582
|
+
*/
|
|
47583
|
+
function matchesDocument($from, match, text) {
|
|
47584
|
+
const matchedDocLength = match[0].length - text.length;
|
|
47585
|
+
if (matchedDocLength <= 0) return true;
|
|
47586
|
+
const matchStartOffset = $from.parentOffset - matchedDocLength;
|
|
47587
|
+
return matchStartOffset >= 0 && $from.parent.textBetween(matchStartOffset, $from.parentOffset) === match[0].slice(0, matchedDocLength);
|
|
47588
|
+
}
|
|
46836
47589
|
function run$1$1(config) {
|
|
46837
47590
|
var _ref;
|
|
46838
|
-
const { editor, from, to, text, rules, plugin } = config;
|
|
47591
|
+
const { editor, from, to, text, rules, plugin, insertText } = config;
|
|
46839
47592
|
const { view } = editor;
|
|
46840
47593
|
if (view.composing) return false;
|
|
46841
47594
|
const $from = view.state.doc.resolve(from);
|
|
46842
47595
|
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;
|
|
46843
|
-
let matched = false;
|
|
46844
47596
|
const textBefore = getTextContentFromNodes($from) + text;
|
|
46845
|
-
|
|
46846
|
-
if (matched) return;
|
|
47597
|
+
for (const rule of rules) {
|
|
46847
47598
|
const match = inputRuleMatcherHandler(textBefore, rule.find);
|
|
46848
|
-
if (!match)
|
|
46849
|
-
|
|
46850
|
-
if (matchedDocLength > 0) {
|
|
46851
|
-
const matchStartOffset = $from.parentOffset - matchedDocLength;
|
|
46852
|
-
if (matchStartOffset < 0 || $from.parent.textBetween(matchStartOffset, $from.parentOffset) !== match[0].slice(0, matchedDocLength)) return;
|
|
46853
|
-
}
|
|
46854
|
-
const tr = view.state.tr;
|
|
46855
|
-
const state = createChainableState({
|
|
46856
|
-
state: view.state,
|
|
46857
|
-
transaction: tr
|
|
46858
|
-
});
|
|
46859
|
-
const range = {
|
|
46860
|
-
from: from - (match[0].length - text.length),
|
|
46861
|
-
to
|
|
46862
|
-
};
|
|
46863
|
-
const { commands, chain, can } = new CommandManager({
|
|
47599
|
+
if (!match || !matchesDocument($from, match, text)) continue;
|
|
47600
|
+
if (applyRule({
|
|
46864
47601
|
editor,
|
|
46865
|
-
state
|
|
46866
|
-
});
|
|
46867
|
-
if (rule.handler({
|
|
46868
|
-
state,
|
|
46869
|
-
range,
|
|
46870
|
-
match,
|
|
46871
|
-
commands,
|
|
46872
|
-
chain,
|
|
46873
|
-
can
|
|
46874
|
-
}) === null || !tr.steps.length) return;
|
|
46875
|
-
if (rule.undoable) tr.setMeta(plugin, {
|
|
46876
|
-
transform: tr,
|
|
46877
47602
|
from,
|
|
46878
47603
|
to,
|
|
46879
|
-
text
|
|
46880
|
-
|
|
46881
|
-
|
|
46882
|
-
|
|
46883
|
-
|
|
46884
|
-
|
|
47604
|
+
text,
|
|
47605
|
+
rule,
|
|
47606
|
+
match,
|
|
47607
|
+
plugin,
|
|
47608
|
+
insertText
|
|
47609
|
+
})) return true;
|
|
47610
|
+
}
|
|
47611
|
+
return false;
|
|
46885
47612
|
}
|
|
46886
47613
|
/**
|
|
46887
47614
|
* Create an input rules plugin. When enabled, it will cause text
|
|
@@ -46925,7 +47652,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
46925
47652
|
to,
|
|
46926
47653
|
text,
|
|
46927
47654
|
rules,
|
|
46928
|
-
plugin
|
|
47655
|
+
plugin,
|
|
47656
|
+
insertText: true
|
|
46929
47657
|
});
|
|
46930
47658
|
},
|
|
46931
47659
|
handleDOMEvents: { compositionend: (view) => {
|
|
@@ -47161,6 +47889,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
47161
47889
|
pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null;
|
|
47162
47890
|
return tr;
|
|
47163
47891
|
};
|
|
47892
|
+
editor.on("destroy", () => {
|
|
47893
|
+
if (tiptapDragFromOtherEditor === editor) tiptapDragFromOtherEditor = null;
|
|
47894
|
+
});
|
|
47164
47895
|
return rules.map((rule) => {
|
|
47165
47896
|
return new Plugin({
|
|
47166
47897
|
view(view) {
|
|
@@ -47186,6 +47917,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
47186
47917
|
if (!isDroppedFromProseMirror) {
|
|
47187
47918
|
const dragFromOtherEditor = tiptapDragFromOtherEditor;
|
|
47188
47919
|
if (dragFromOtherEditor === null || dragFromOtherEditor === void 0 ? void 0 : dragFromOtherEditor.isEditable) setTimeout(() => {
|
|
47920
|
+
if (dragFromOtherEditor.isDestroyed) return;
|
|
47189
47921
|
const selection = dragFromOtherEditor.state.selection;
|
|
47190
47922
|
if (selection) dragFromOtherEditor.commands.deleteRange({
|
|
47191
47923
|
from: selection.from,
|
|
@@ -48355,7 +49087,10 @@ img.ProseMirror-separator {
|
|
|
48355
49087
|
...options
|
|
48356
49088
|
};
|
|
48357
49089
|
if (!this.editorView || !this.state || this.isDestroyed) return;
|
|
48358
|
-
if (this.options.editorProps) this.view.setProps(
|
|
49090
|
+
if (this.options.editorProps) this.view.setProps({
|
|
49091
|
+
...this.options.editorProps,
|
|
49092
|
+
attributes: this.getEditorViewAttributes()
|
|
49093
|
+
});
|
|
48359
49094
|
this.view.updateState(this.state);
|
|
48360
49095
|
}
|
|
48361
49096
|
/**
|
|
@@ -48511,6 +49246,23 @@ img.ProseMirror-separator {
|
|
|
48511
49246
|
return doc;
|
|
48512
49247
|
}
|
|
48513
49248
|
/**
|
|
49249
|
+
* Returns the attributes for the editor element.
|
|
49250
|
+
* Merges the default `role="textbox"` with the attributes from `editorProps`,
|
|
49251
|
+
* so the role is kept no matter when the props are applied.
|
|
49252
|
+
*/
|
|
49253
|
+
getEditorViewAttributes() {
|
|
49254
|
+
var _this$options$editorP;
|
|
49255
|
+
const attributes = (_this$options$editorP = this.options.editorProps) === null || _this$options$editorP === void 0 ? void 0 : _this$options$editorP.attributes;
|
|
49256
|
+
if (isFunction$3(attributes)) return (state) => ({
|
|
49257
|
+
role: "textbox",
|
|
49258
|
+
...attributes(state)
|
|
49259
|
+
});
|
|
49260
|
+
return {
|
|
49261
|
+
role: "textbox",
|
|
49262
|
+
...attributes
|
|
49263
|
+
};
|
|
49264
|
+
}
|
|
49265
|
+
/**
|
|
48514
49266
|
* Creates a ProseMirror view.
|
|
48515
49267
|
*/
|
|
48516
49268
|
createView(element) {
|
|
@@ -48521,10 +49273,7 @@ img.ProseMirror-separator {
|
|
|
48521
49273
|
const transformPastedHTML = this.extensionManager.transformPastedHTML(baseTransformPastedHTML);
|
|
48522
49274
|
this.editorView = new EditorView(element, {
|
|
48523
49275
|
...editorProps,
|
|
48524
|
-
attributes:
|
|
48525
|
-
role: "textbox",
|
|
48526
|
-
...editorProps === null || editorProps === void 0 ? void 0 : editorProps.attributes
|
|
48527
|
-
},
|
|
49276
|
+
attributes: this.getEditorViewAttributes(),
|
|
48528
49277
|
dispatchTransaction: dispatch,
|
|
48529
49278
|
transformPastedHTML,
|
|
48530
49279
|
state: this.editorState,
|
|
@@ -58227,7 +58976,7 @@ img.ProseMirror-separator {
|
|
|
58227
58976
|
toDOM() { return ["div", ["hr"]]; }
|
|
58228
58977
|
},
|
|
58229
58978
|
heading: {
|
|
58230
|
-
attrs: { level: { default: 1 } },
|
|
58979
|
+
attrs: { level: { default: 1, validate: "number" } },
|
|
58231
58980
|
content: "(text | image)*",
|
|
58232
58981
|
group: "block",
|
|
58233
58982
|
defining: true,
|
|
@@ -58237,7 +58986,7 @@ img.ProseMirror-separator {
|
|
|
58237
58986
|
{ tag: "h4", attrs: { level: 4 } },
|
|
58238
58987
|
{ tag: "h5", attrs: { level: 5 } },
|
|
58239
58988
|
{ tag: "h6", attrs: { level: 6 } }],
|
|
58240
|
-
toDOM(node) { return ["h" + node.attrs.level, 0]; }
|
|
58989
|
+
toDOM(node) { return ["h" + +node.attrs.level, 0]; }
|
|
58241
58990
|
},
|
|
58242
58991
|
code_block: {
|
|
58243
58992
|
content: "text*",
|
|
@@ -61734,8 +62483,27 @@ img.ProseMirror-separator {
|
|
|
61734
62483
|
const UNICODE_WHITESPACE_PATTERN = "[\0- \xA0 -\u2029 ]";
|
|
61735
62484
|
const UNICODE_WHITESPACE_REGEX = new RegExp(UNICODE_WHITESPACE_PATTERN);
|
|
61736
62485
|
const UNICODE_WHITESPACE_REGEX_END = new RegExp(`${UNICODE_WHITESPACE_PATTERN}$`);
|
|
62486
|
+
const UNICODE_WHITESPACE_REGEX_TRAILING = new RegExp(`${UNICODE_WHITESPACE_PATTERN}+$`);
|
|
61737
62487
|
const UNICODE_WHITESPACE_REGEX_GLOBAL = new RegExp(UNICODE_WHITESPACE_PATTERN, "g");
|
|
61738
62488
|
//#endregion
|
|
62489
|
+
//#region src/helpers/unlinkTrailingWhitespace.ts
|
|
62490
|
+
function unlinkTrailingWhitespace(tr, range, type) {
|
|
62491
|
+
var _rangeEnd$nodeBefore, _insertedText$match;
|
|
62492
|
+
const rangeEnd = tr.doc.resolve(range.to);
|
|
62493
|
+
if (!((_rangeEnd$nodeBefore = rangeEnd.nodeBefore) === null || _rangeEnd$nodeBefore === void 0 ? void 0 : _rangeEnd$nodeBefore.isText)) return;
|
|
62494
|
+
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];
|
|
62495
|
+
if (!trailingWhitespace) return;
|
|
62496
|
+
const whitespaceFrom = range.to - trailingWhitespace.length;
|
|
62497
|
+
const linkMarks = getMarksBetween(whitespaceFrom, range.to, tr.doc).filter((item) => item.mark.type === type);
|
|
62498
|
+
if (!linkMarks.length) return;
|
|
62499
|
+
const { nodeAfter } = rangeEnd;
|
|
62500
|
+
if (!!nodeAfter && linkMarks.some((item) => item.mark.isInSet(nodeAfter.marks))) return;
|
|
62501
|
+
const storedMarks = tr.storedMarks;
|
|
62502
|
+
tr.removeMark(whitespaceFrom, range.to, type);
|
|
62503
|
+
tr.setStoredMarks(storedMarks);
|
|
62504
|
+
if (tr.selection.empty && tr.selection.from === range.to) tr.removeStoredMark(type);
|
|
62505
|
+
}
|
|
62506
|
+
//#endregion
|
|
61739
62507
|
//#region src/helpers/autolink.ts
|
|
61740
62508
|
/**
|
|
61741
62509
|
* Check if the provided tokens form a valid link structure, which can either be a single link token
|
|
@@ -61776,6 +62544,21 @@ img.ProseMirror-separator {
|
|
|
61776
62544
|
if (!docChanges || preventAutolink) return;
|
|
61777
62545
|
const { tr } = newState;
|
|
61778
62546
|
const transform = combineTransactionSteps(oldState.doc, [...transactions]);
|
|
62547
|
+
if (!transactions.some(isHistoryTransaction)) {
|
|
62548
|
+
const insertedRanges = [];
|
|
62549
|
+
transform.steps.forEach((step, index) => {
|
|
62550
|
+
if (!(step instanceof ReplaceStep) || !step.slice.size) return;
|
|
62551
|
+
const mapping = transform.mapping.slice(index + 1);
|
|
62552
|
+
const from = mapping.map(step.from, 1);
|
|
62553
|
+
const to = mapping.map(step.from + step.slice.size, -1);
|
|
62554
|
+
if (from < to) insertedRanges.push({
|
|
62555
|
+
from,
|
|
62556
|
+
to
|
|
62557
|
+
});
|
|
62558
|
+
});
|
|
62559
|
+
insertedRanges.sort((left, right) => right.to - left.to);
|
|
62560
|
+
insertedRanges.forEach((range) => unlinkTrailingWhitespace(tr, range, options.type));
|
|
62561
|
+
}
|
|
61779
62562
|
getChangedRanges(transform).forEach(({ newRange }) => {
|
|
61780
62563
|
const nodesInChangedRanges = findChildrenInRange(newState.doc, newRange, (node) => node.isTextblock);
|
|
61781
62564
|
let textBlock;
|
|
@@ -63162,6 +63945,54 @@ img.ProseMirror-separator {
|
|
|
63162
63945
|
});
|
|
63163
63946
|
}
|
|
63164
63947
|
//#endregion
|
|
63948
|
+
//#region src/ordered-list/collectOrderedListItemsFromSource.ts
|
|
63949
|
+
const ORDERED_LIST_SCAN_WINDOW = 64;
|
|
63950
|
+
function takeLines(source, max) {
|
|
63951
|
+
const lines = [];
|
|
63952
|
+
let start = 0;
|
|
63953
|
+
while (lines.length < max) {
|
|
63954
|
+
const lineEnd = source.indexOf("\n", start);
|
|
63955
|
+
if (lineEnd === -1) {
|
|
63956
|
+
lines.push(source.slice(start));
|
|
63957
|
+
return lines;
|
|
63958
|
+
}
|
|
63959
|
+
lines.push(source.slice(start, lineEnd));
|
|
63960
|
+
start = lineEnd + 1;
|
|
63961
|
+
}
|
|
63962
|
+
return lines;
|
|
63963
|
+
}
|
|
63964
|
+
/**
|
|
63965
|
+
* Collect ordered list items from the start of `source`, reading only the lines the list needs.
|
|
63966
|
+
*
|
|
63967
|
+
* @param source Markdown beginning at a block boundary.
|
|
63968
|
+
* @returns The items, how many lines they consumed, and the lines that were read.
|
|
63969
|
+
* @example
|
|
63970
|
+
* collectOrderedListItemsFromSource('1. one\n2. two\n\nAfter')
|
|
63971
|
+
* // → [[item, item], 3, ['1. one', '2. two', '', 'After']]
|
|
63972
|
+
*/
|
|
63973
|
+
function collectOrderedListItemsFromSource(source) {
|
|
63974
|
+
const firstLineEnd = source.indexOf("\n");
|
|
63975
|
+
const firstLine = firstLineEnd === -1 ? source : source.slice(0, firstLineEnd);
|
|
63976
|
+
if (!ORDERED_LIST_ITEM_REGEX.test(firstLine)) return [
|
|
63977
|
+
[],
|
|
63978
|
+
0,
|
|
63979
|
+
[]
|
|
63980
|
+
];
|
|
63981
|
+
let windowSize = ORDERED_LIST_SCAN_WINDOW;
|
|
63982
|
+
let lines = takeLines(source, windowSize);
|
|
63983
|
+
let collected = collectOrderedListItems(lines);
|
|
63984
|
+
while (collected[1] === lines.length && lines.length === windowSize) {
|
|
63985
|
+
windowSize *= 2;
|
|
63986
|
+
lines = takeLines(source, windowSize);
|
|
63987
|
+
collected = collectOrderedListItems(lines);
|
|
63988
|
+
}
|
|
63989
|
+
return [
|
|
63990
|
+
collected[0],
|
|
63991
|
+
collected[1],
|
|
63992
|
+
lines
|
|
63993
|
+
];
|
|
63994
|
+
}
|
|
63995
|
+
//#endregion
|
|
63165
63996
|
//#region src/ordered-list/ordered-list.ts
|
|
63166
63997
|
const ListItemName = "listItem";
|
|
63167
63998
|
const TextStyleName = "textStyle";
|
|
@@ -63280,8 +64111,7 @@ img.ProseMirror-separator {
|
|
|
63280
64111
|
start: () => -1,
|
|
63281
64112
|
tokenize: (src, _tokens, lexer) => {
|
|
63282
64113
|
var _listItems$, _listItems$2;
|
|
63283
|
-
const lines = src
|
|
63284
|
-
const [listItems, consumed] = collectOrderedListItems(lines);
|
|
64114
|
+
const [listItems, consumed, lines] = collectOrderedListItemsFromSource(src);
|
|
63285
64115
|
if (listItems.length === 0) return;
|
|
63286
64116
|
const items = buildNestedStructure(listItems, listItems[0].indent, lexer);
|
|
63287
64117
|
if (items.length === 0) return;
|
|
@@ -66054,1026 +66884,412 @@ img.ProseMirror-separator {
|
|
|
66054
66884
|
* This extension allows you to create text nodes.
|
|
66055
66885
|
* @see https://www.tiptap.dev/api/nodes/text
|
|
66056
66886
|
*/
|
|
66057
|
-
const Text = Node$1.create({
|
|
66058
|
-
name: "text",
|
|
66059
|
-
group: "inline",
|
|
66060
|
-
parseMarkdown: (token) => {
|
|
66061
|
-
return {
|
|
66062
|
-
type: "text",
|
|
66063
|
-
text: token.text || ""
|
|
66064
|
-
};
|
|
66065
|
-
},
|
|
66066
|
-
renderMarkdown: (node) => node.text || ""
|
|
66067
|
-
});
|
|
66068
|
-
//#endregion
|
|
66069
|
-
//#region src/index.ts
|
|
66070
|
-
var src_default = Text;
|
|
66071
|
-
|
|
66072
|
-
/**
|
|
66073
|
-
Create a plugin that, when added to a ProseMirror instance,
|
|
66074
|
-
causes a decoration to show up at the drop position when something
|
|
66075
|
-
is dragged over the editor.
|
|
66076
|
-
|
|
66077
|
-
Nodes may add a `disableDropCursor` property to their spec to
|
|
66078
|
-
control the showing of a drop cursor inside them. This may be a
|
|
66079
|
-
boolean or a function, which will be called with a view and a
|
|
66080
|
-
position, and should return a boolean.
|
|
66081
|
-
*/
|
|
66082
|
-
function dropCursor(options = {}) {
|
|
66083
|
-
return new Plugin({
|
|
66084
|
-
view(editorView) { return new DropCursorView(editorView, options); }
|
|
66085
|
-
});
|
|
66086
|
-
}
|
|
66087
|
-
class DropCursorView {
|
|
66088
|
-
constructor(editorView, options) {
|
|
66089
|
-
var _a;
|
|
66090
|
-
this.editorView = editorView;
|
|
66091
|
-
this.cursorPos = null;
|
|
66092
|
-
this.element = null;
|
|
66093
|
-
this.timeout = -1;
|
|
66094
|
-
this.lastDragEvent = null;
|
|
66095
|
-
this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1;
|
|
66096
|
-
this.color = options.color === false ? undefined : (options.color || "black");
|
|
66097
|
-
this.class = options.class;
|
|
66098
|
-
this.handlers = ["dragover", "dragend", "drop", "dragleave"].map(name => {
|
|
66099
|
-
let handler = (e) => { this[name](e); };
|
|
66100
|
-
editorView.dom.addEventListener(name, handler);
|
|
66101
|
-
return { name, handler };
|
|
66102
|
-
});
|
|
66103
|
-
}
|
|
66104
|
-
destroy() {
|
|
66105
|
-
this.handlers.forEach(({ name, handler }) => this.editorView.dom.removeEventListener(name, handler));
|
|
66106
|
-
}
|
|
66107
|
-
update(editorView, prevState) {
|
|
66108
|
-
if (this.cursorPos != null && prevState.doc != editorView.state.doc) {
|
|
66109
|
-
// if we currently have an on-going drag event
|
|
66110
|
-
// we need to update the cursor position again and update the overlay
|
|
66111
|
-
if (this.lastDragEvent) {
|
|
66112
|
-
let target = this.computeTarget(this.lastDragEvent);
|
|
66113
|
-
if (target == this.cursorPos)
|
|
66114
|
-
this.updateOverlay();
|
|
66115
|
-
else
|
|
66116
|
-
this.setCursor(target);
|
|
66117
|
-
}
|
|
66118
|
-
else {
|
|
66119
|
-
this.updateOverlay();
|
|
66120
|
-
}
|
|
66121
|
-
}
|
|
66122
|
-
}
|
|
66123
|
-
setCursor(pos) {
|
|
66124
|
-
if (pos == this.cursorPos)
|
|
66125
|
-
return;
|
|
66126
|
-
this.cursorPos = pos;
|
|
66127
|
-
if (pos == null) {
|
|
66128
|
-
this.element.parentNode.removeChild(this.element);
|
|
66129
|
-
this.element = null;
|
|
66130
|
-
}
|
|
66131
|
-
else {
|
|
66132
|
-
this.updateOverlay();
|
|
66133
|
-
}
|
|
66134
|
-
}
|
|
66135
|
-
updateOverlay() {
|
|
66136
|
-
let $pos = this.editorView.state.doc.resolve(this.cursorPos);
|
|
66137
|
-
let isBlock = !$pos.parent.inlineContent, rect;
|
|
66138
|
-
let editorDOM = this.editorView.dom, editorRect = editorDOM.getBoundingClientRect();
|
|
66139
|
-
let scaleX = editorRect.width / editorDOM.offsetWidth, scaleY = editorRect.height / editorDOM.offsetHeight;
|
|
66140
|
-
if (isBlock) {
|
|
66141
|
-
let before = $pos.nodeBefore, after = $pos.nodeAfter;
|
|
66142
|
-
if (before || after) {
|
|
66143
|
-
let node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0));
|
|
66144
|
-
if (node) {
|
|
66145
|
-
let nodeRect = node.getBoundingClientRect();
|
|
66146
|
-
let top = before ? nodeRect.bottom : nodeRect.top;
|
|
66147
|
-
if (before && after)
|
|
66148
|
-
top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2;
|
|
66149
|
-
let halfWidth = (this.width / 2) * scaleY;
|
|
66150
|
-
rect = { left: nodeRect.left, right: nodeRect.right, top: top - halfWidth, bottom: top + halfWidth };
|
|
66151
|
-
}
|
|
66152
|
-
}
|
|
66153
|
-
}
|
|
66154
|
-
if (!rect) {
|
|
66155
|
-
let coords = this.editorView.coordsAtPos(this.cursorPos);
|
|
66156
|
-
let halfWidth = (this.width / 2) * scaleX;
|
|
66157
|
-
rect = { left: coords.left - halfWidth, right: coords.left + halfWidth, top: coords.top, bottom: coords.bottom };
|
|
66158
|
-
}
|
|
66159
|
-
let parent = this.editorView.dom.offsetParent;
|
|
66160
|
-
if (!this.element) {
|
|
66161
|
-
this.element = parent.appendChild(document.createElement("div"));
|
|
66162
|
-
if (this.class)
|
|
66163
|
-
this.element.className = this.class;
|
|
66164
|
-
this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;";
|
|
66165
|
-
if (this.color) {
|
|
66166
|
-
this.element.style.backgroundColor = this.color;
|
|
66167
|
-
}
|
|
66168
|
-
}
|
|
66169
|
-
this.element.classList.toggle("prosemirror-dropcursor-block", isBlock);
|
|
66170
|
-
this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock);
|
|
66171
|
-
let parentLeft, parentTop;
|
|
66172
|
-
if (!parent || parent == document.body && getComputedStyle(parent).position == "static") {
|
|
66173
|
-
parentLeft = -pageXOffset;
|
|
66174
|
-
parentTop = -pageYOffset;
|
|
66175
|
-
}
|
|
66176
|
-
else {
|
|
66177
|
-
let rect = parent.getBoundingClientRect();
|
|
66178
|
-
let parentScaleX = rect.width / parent.offsetWidth, parentScaleY = rect.height / parent.offsetHeight;
|
|
66179
|
-
parentLeft = rect.left - parent.scrollLeft * parentScaleX;
|
|
66180
|
-
parentTop = rect.top - parent.scrollTop * parentScaleY;
|
|
66181
|
-
}
|
|
66182
|
-
this.element.style.left = (rect.left - parentLeft) / scaleX + "px";
|
|
66183
|
-
this.element.style.top = (rect.top - parentTop) / scaleY + "px";
|
|
66184
|
-
this.element.style.width = (rect.right - rect.left) / scaleX + "px";
|
|
66185
|
-
this.element.style.height = (rect.bottom - rect.top) / scaleY + "px";
|
|
66186
|
-
}
|
|
66187
|
-
scheduleRemoval(timeout) {
|
|
66188
|
-
clearTimeout(this.timeout);
|
|
66189
|
-
this.timeout = setTimeout(() => this.setCursor(null), timeout);
|
|
66190
|
-
}
|
|
66191
|
-
computeTarget(event) {
|
|
66192
|
-
let pos = this.editorView.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
66193
|
-
let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);
|
|
66194
|
-
let disableDropCursor = node && node.type.spec.disableDropCursor;
|
|
66195
|
-
let disabled = typeof disableDropCursor == "function"
|
|
66196
|
-
? disableDropCursor(this.editorView, pos, event)
|
|
66197
|
-
: disableDropCursor;
|
|
66198
|
-
if (!pos || disabled)
|
|
66199
|
-
return null;
|
|
66200
|
-
let target = pos.pos;
|
|
66201
|
-
if (this.editorView.dragging && this.editorView.dragging.slice) {
|
|
66202
|
-
let point = dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice);
|
|
66203
|
-
if (point != null)
|
|
66204
|
-
target = point;
|
|
66205
|
-
}
|
|
66206
|
-
return target;
|
|
66207
|
-
}
|
|
66208
|
-
dragover(event) {
|
|
66209
|
-
if (!this.editorView.editable)
|
|
66210
|
-
return;
|
|
66211
|
-
this.lastDragEvent = event;
|
|
66212
|
-
let target = this.computeTarget(event);
|
|
66213
|
-
if (target != null) {
|
|
66214
|
-
this.setCursor(target);
|
|
66215
|
-
this.scheduleRemoval(5000);
|
|
66216
|
-
}
|
|
66217
|
-
}
|
|
66218
|
-
dragend() {
|
|
66219
|
-
this.scheduleRemoval(20);
|
|
66220
|
-
}
|
|
66221
|
-
drop() {
|
|
66222
|
-
this.scheduleRemoval(20);
|
|
66223
|
-
}
|
|
66224
|
-
dragleave(event) {
|
|
66225
|
-
if (!this.editorView.dom.contains(event.relatedTarget))
|
|
66226
|
-
this.setCursor(null);
|
|
66227
|
-
}
|
|
66228
|
-
}
|
|
66229
|
-
|
|
66230
|
-
/**
|
|
66231
|
-
Gap cursor selections are represented using this class. Its
|
|
66232
|
-
`$anchor` and `$head` properties both point at the cursor position.
|
|
66233
|
-
*/
|
|
66234
|
-
class GapCursor extends Selection$2 {
|
|
66235
|
-
/**
|
|
66236
|
-
Create a gap cursor.
|
|
66237
|
-
*/
|
|
66238
|
-
constructor($pos) {
|
|
66239
|
-
super($pos, $pos);
|
|
66240
|
-
}
|
|
66241
|
-
map(doc, mapping) {
|
|
66242
|
-
let $pos = doc.resolve(mapping.map(this.head));
|
|
66243
|
-
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$2.near($pos);
|
|
66244
|
-
}
|
|
66245
|
-
content() { return Slice.empty; }
|
|
66246
|
-
eq(other) {
|
|
66247
|
-
return other instanceof GapCursor && other.head == this.head;
|
|
66248
|
-
}
|
|
66249
|
-
toJSON() {
|
|
66250
|
-
return { type: "gapcursor", pos: this.head };
|
|
66251
|
-
}
|
|
66252
|
-
/**
|
|
66253
|
-
@internal
|
|
66254
|
-
*/
|
|
66255
|
-
static fromJSON(doc, json) {
|
|
66256
|
-
if (typeof json.pos != "number")
|
|
66257
|
-
throw new RangeError("Invalid input for GapCursor.fromJSON");
|
|
66258
|
-
return new GapCursor(doc.resolve(json.pos));
|
|
66259
|
-
}
|
|
66260
|
-
/**
|
|
66261
|
-
@internal
|
|
66262
|
-
*/
|
|
66263
|
-
getBookmark() { return new GapBookmark(this.anchor); }
|
|
66264
|
-
/**
|
|
66265
|
-
@internal
|
|
66266
|
-
*/
|
|
66267
|
-
static valid($pos) {
|
|
66268
|
-
let parent = $pos.parent;
|
|
66269
|
-
if (parent.inlineContent || !closedBefore($pos) || !closedAfter($pos))
|
|
66270
|
-
return false;
|
|
66271
|
-
let override = parent.type.spec.allowGapCursor;
|
|
66272
|
-
if (override != null)
|
|
66273
|
-
return override;
|
|
66274
|
-
let deflt = parent.contentMatchAt($pos.index()).defaultType;
|
|
66275
|
-
return deflt && deflt.isTextblock;
|
|
66276
|
-
}
|
|
66277
|
-
/**
|
|
66278
|
-
@internal
|
|
66279
|
-
*/
|
|
66280
|
-
static findGapCursorFrom($pos, dir, mustMove = false) {
|
|
66281
|
-
search: for (;;) {
|
|
66282
|
-
if (!mustMove && GapCursor.valid($pos))
|
|
66283
|
-
return $pos;
|
|
66284
|
-
let pos = $pos.pos, next = null;
|
|
66285
|
-
// Scan up from this position
|
|
66286
|
-
for (let d = $pos.depth;; d--) {
|
|
66287
|
-
let parent = $pos.node(d);
|
|
66288
|
-
if (dir > 0 ? $pos.indexAfter(d) < parent.childCount : $pos.index(d) > 0) {
|
|
66289
|
-
next = parent.child(dir > 0 ? $pos.indexAfter(d) : $pos.index(d) - 1);
|
|
66290
|
-
break;
|
|
66291
|
-
}
|
|
66292
|
-
else if (d == 0) {
|
|
66293
|
-
return null;
|
|
66294
|
-
}
|
|
66295
|
-
pos += dir;
|
|
66296
|
-
let $cur = $pos.doc.resolve(pos);
|
|
66297
|
-
if (GapCursor.valid($cur))
|
|
66298
|
-
return $cur;
|
|
66299
|
-
}
|
|
66300
|
-
// And then down into the next node
|
|
66301
|
-
for (;;) {
|
|
66302
|
-
let inside = dir > 0 ? next.firstChild : next.lastChild;
|
|
66303
|
-
if (!inside) {
|
|
66304
|
-
if (next.isAtom && !next.isText && !NodeSelection.isSelectable(next)) {
|
|
66305
|
-
$pos = $pos.doc.resolve(pos + next.nodeSize * dir);
|
|
66306
|
-
mustMove = false;
|
|
66307
|
-
continue search;
|
|
66308
|
-
}
|
|
66309
|
-
break;
|
|
66310
|
-
}
|
|
66311
|
-
next = inside;
|
|
66312
|
-
pos += dir;
|
|
66313
|
-
let $cur = $pos.doc.resolve(pos);
|
|
66314
|
-
if (GapCursor.valid($cur))
|
|
66315
|
-
return $cur;
|
|
66316
|
-
}
|
|
66317
|
-
return null;
|
|
66318
|
-
}
|
|
66319
|
-
}
|
|
66320
|
-
}
|
|
66321
|
-
GapCursor.prototype.visible = false;
|
|
66322
|
-
GapCursor.findFrom = GapCursor.findGapCursorFrom;
|
|
66323
|
-
Selection$2.jsonID("gapcursor", GapCursor);
|
|
66324
|
-
class GapBookmark {
|
|
66325
|
-
constructor(pos) {
|
|
66326
|
-
this.pos = pos;
|
|
66327
|
-
}
|
|
66328
|
-
map(mapping) {
|
|
66329
|
-
return new GapBookmark(mapping.map(this.pos));
|
|
66330
|
-
}
|
|
66331
|
-
resolve(doc) {
|
|
66332
|
-
let $pos = doc.resolve(this.pos);
|
|
66333
|
-
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$2.near($pos);
|
|
66334
|
-
}
|
|
66335
|
-
}
|
|
66336
|
-
function needsGap(type) {
|
|
66337
|
-
return type.isAtom || type.spec.isolating || type.spec.createGapCursor;
|
|
66338
|
-
}
|
|
66339
|
-
function closedBefore($pos) {
|
|
66340
|
-
for (let d = $pos.depth; d >= 0; d--) {
|
|
66341
|
-
let index = $pos.index(d), parent = $pos.node(d);
|
|
66342
|
-
// At the start of this parent, look at next one
|
|
66343
|
-
if (index == 0) {
|
|
66344
|
-
if (parent.type.spec.isolating)
|
|
66345
|
-
return true;
|
|
66346
|
-
continue;
|
|
66347
|
-
}
|
|
66348
|
-
// See if the node before (or its first ancestor) is closed
|
|
66349
|
-
for (let before = parent.child(index - 1);; before = before.lastChild) {
|
|
66350
|
-
if ((before.childCount == 0 && !before.inlineContent) || needsGap(before.type))
|
|
66351
|
-
return true;
|
|
66352
|
-
if (before.inlineContent)
|
|
66353
|
-
return false;
|
|
66354
|
-
}
|
|
66355
|
-
}
|
|
66356
|
-
// Hit start of document
|
|
66357
|
-
return true;
|
|
66358
|
-
}
|
|
66359
|
-
function closedAfter($pos) {
|
|
66360
|
-
for (let d = $pos.depth; d >= 0; d--) {
|
|
66361
|
-
let index = $pos.indexAfter(d), parent = $pos.node(d);
|
|
66362
|
-
if (index == parent.childCount) {
|
|
66363
|
-
if (parent.type.spec.isolating)
|
|
66364
|
-
return true;
|
|
66365
|
-
continue;
|
|
66366
|
-
}
|
|
66367
|
-
for (let after = parent.child(index);; after = after.firstChild) {
|
|
66368
|
-
if ((after.childCount == 0 && !after.inlineContent) || needsGap(after.type))
|
|
66369
|
-
return true;
|
|
66370
|
-
if (after.inlineContent)
|
|
66371
|
-
return false;
|
|
66372
|
-
}
|
|
66373
|
-
}
|
|
66374
|
-
return true;
|
|
66375
|
-
}
|
|
66887
|
+
const Text = Node$1.create({
|
|
66888
|
+
name: "text",
|
|
66889
|
+
group: "inline",
|
|
66890
|
+
parseMarkdown: (token) => {
|
|
66891
|
+
return {
|
|
66892
|
+
type: "text",
|
|
66893
|
+
text: token.text || ""
|
|
66894
|
+
};
|
|
66895
|
+
},
|
|
66896
|
+
renderMarkdown: (node) => node.text || ""
|
|
66897
|
+
});
|
|
66898
|
+
//#endregion
|
|
66899
|
+
//#region src/index.ts
|
|
66900
|
+
var src_default = Text;
|
|
66376
66901
|
|
|
66377
66902
|
/**
|
|
66378
|
-
Create a
|
|
66379
|
-
|
|
66380
|
-
|
|
66381
|
-
|
|
66382
|
-
`
|
|
66383
|
-
|
|
66384
|
-
|
|
66903
|
+
Create a plugin that, when added to a ProseMirror instance,
|
|
66904
|
+
causes a decoration to show up at the drop position when something
|
|
66905
|
+
is dragged over the editor.
|
|
66906
|
+
|
|
66907
|
+
Nodes may add a `disableDropCursor` property to their spec to
|
|
66908
|
+
control the showing of a drop cursor inside them. This may be a
|
|
66909
|
+
boolean or a function, which will be called with a view and a
|
|
66910
|
+
position, and should return a boolean.
|
|
66385
66911
|
*/
|
|
66386
|
-
function
|
|
66912
|
+
function dropCursor(options = {}) {
|
|
66387
66913
|
return new Plugin({
|
|
66388
|
-
|
|
66389
|
-
decorations: drawGapCursor,
|
|
66390
|
-
createSelectionBetween(_view, $anchor, $head) {
|
|
66391
|
-
return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null;
|
|
66392
|
-
},
|
|
66393
|
-
handleClick,
|
|
66394
|
-
handleKeyDown,
|
|
66395
|
-
handleDOMEvents: { beforeinput: beforeinput }
|
|
66396
|
-
}
|
|
66914
|
+
view(editorView) { return new DropCursorView(editorView, options); }
|
|
66397
66915
|
});
|
|
66398
66916
|
}
|
|
66399
|
-
|
|
66400
|
-
|
|
66401
|
-
|
|
66402
|
-
|
|
66403
|
-
|
|
66404
|
-
|
|
66405
|
-
|
|
66406
|
-
|
|
66407
|
-
|
|
66408
|
-
|
|
66409
|
-
|
|
66410
|
-
|
|
66411
|
-
|
|
66412
|
-
|
|
66413
|
-
|
|
66414
|
-
|
|
66415
|
-
}
|
|
66416
|
-
let $found = GapCursor.findGapCursorFrom($start, dir, mustMove);
|
|
66417
|
-
if (!$found)
|
|
66418
|
-
return false;
|
|
66419
|
-
if (dispatch)
|
|
66420
|
-
dispatch(state.tr.setSelection(new GapCursor($found)));
|
|
66421
|
-
return true;
|
|
66422
|
-
};
|
|
66423
|
-
}
|
|
66424
|
-
function handleClick(view, pos, event) {
|
|
66425
|
-
if (!view || !view.editable)
|
|
66426
|
-
return false;
|
|
66427
|
-
let $pos = view.state.doc.resolve(pos);
|
|
66428
|
-
if (!GapCursor.valid($pos))
|
|
66429
|
-
return false;
|
|
66430
|
-
let clickPos = view.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
66431
|
-
if (clickPos && clickPos.inside > -1 && NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside)))
|
|
66432
|
-
return false;
|
|
66433
|
-
view.dispatch(view.state.tr.setSelection(new GapCursor($pos)));
|
|
66434
|
-
return true;
|
|
66435
|
-
}
|
|
66436
|
-
// This is a hack that, when a composition starts while a gap cursor
|
|
66437
|
-
// is active, quickly creates an inline context for the composition to
|
|
66438
|
-
// happen in, to avoid it being aborted by the DOM selection being
|
|
66439
|
-
// moved into a valid position.
|
|
66440
|
-
function beforeinput(view, event) {
|
|
66441
|
-
if (event.inputType != "insertCompositionText" || !(view.state.selection instanceof GapCursor))
|
|
66442
|
-
return false;
|
|
66443
|
-
let { $from } = view.state.selection;
|
|
66444
|
-
let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text);
|
|
66445
|
-
if (!insert)
|
|
66446
|
-
return false;
|
|
66447
|
-
let frag = Fragment.empty;
|
|
66448
|
-
for (let i = insert.length - 1; i >= 0; i--)
|
|
66449
|
-
frag = Fragment.from(insert[i].createAndFill(null, frag));
|
|
66450
|
-
let tr = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0));
|
|
66451
|
-
tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + 1)));
|
|
66452
|
-
view.dispatch(tr);
|
|
66453
|
-
return false;
|
|
66454
|
-
}
|
|
66455
|
-
function drawGapCursor(state) {
|
|
66456
|
-
if (!(state.selection instanceof GapCursor))
|
|
66457
|
-
return null;
|
|
66458
|
-
let node = document.createElement("div");
|
|
66459
|
-
node.className = "ProseMirror-gapcursor";
|
|
66460
|
-
return DecorationSet.create(state.doc, [Decoration.widget(state.selection.head, node, { key: "gapcursor" })]);
|
|
66461
|
-
}
|
|
66462
|
-
|
|
66463
|
-
var GOOD_LEAF_SIZE = 200;
|
|
66464
|
-
|
|
66465
|
-
// :: class<T> A rope sequence is a persistent sequence data structure
|
|
66466
|
-
// that supports appending, prepending, and slicing without doing a
|
|
66467
|
-
// full copy. It is represented as a mostly-balanced tree.
|
|
66468
|
-
var RopeSequence = function RopeSequence () {};
|
|
66469
|
-
|
|
66470
|
-
RopeSequence.prototype.append = function append (other) {
|
|
66471
|
-
if (!other.length) { return this }
|
|
66472
|
-
other = RopeSequence.from(other);
|
|
66473
|
-
|
|
66474
|
-
return (!this.length && other) ||
|
|
66475
|
-
(other.length < GOOD_LEAF_SIZE && this.leafAppend(other)) ||
|
|
66476
|
-
(this.length < GOOD_LEAF_SIZE && other.leafPrepend(this)) ||
|
|
66477
|
-
this.appendInner(other)
|
|
66478
|
-
};
|
|
66479
|
-
|
|
66480
|
-
// :: (union<[T], RopeSequence<T>>) → RopeSequence<T>
|
|
66481
|
-
// Prepend an array or other rope to this one, returning a new rope.
|
|
66482
|
-
RopeSequence.prototype.prepend = function prepend (other) {
|
|
66483
|
-
if (!other.length) { return this }
|
|
66484
|
-
return RopeSequence.from(other).append(this)
|
|
66485
|
-
};
|
|
66486
|
-
|
|
66487
|
-
RopeSequence.prototype.appendInner = function appendInner (other) {
|
|
66488
|
-
return new Append(this, other)
|
|
66489
|
-
};
|
|
66490
|
-
|
|
66491
|
-
// :: (?number, ?number) → RopeSequence<T>
|
|
66492
|
-
// Create a rope repesenting a sub-sequence of this rope.
|
|
66493
|
-
RopeSequence.prototype.slice = function slice (from, to) {
|
|
66494
|
-
if ( from === void 0 ) from = 0;
|
|
66495
|
-
if ( to === void 0 ) to = this.length;
|
|
66496
|
-
|
|
66497
|
-
if (from >= to) { return RopeSequence.empty }
|
|
66498
|
-
return this.sliceInner(Math.max(0, from), Math.min(this.length, to))
|
|
66499
|
-
};
|
|
66500
|
-
|
|
66501
|
-
// :: (number) → T
|
|
66502
|
-
// Retrieve the element at the given position from this rope.
|
|
66503
|
-
RopeSequence.prototype.get = function get (i) {
|
|
66504
|
-
if (i < 0 || i >= this.length) { return undefined }
|
|
66505
|
-
return this.getInner(i)
|
|
66506
|
-
};
|
|
66507
|
-
|
|
66508
|
-
// :: ((element: T, index: number) → ?bool, ?number, ?number)
|
|
66509
|
-
// Call the given function for each element between the given
|
|
66510
|
-
// indices. This tends to be more efficient than looping over the
|
|
66511
|
-
// indices and calling `get`, because it doesn't have to descend the
|
|
66512
|
-
// tree for every element.
|
|
66513
|
-
RopeSequence.prototype.forEach = function forEach (f, from, to) {
|
|
66514
|
-
if ( from === void 0 ) from = 0;
|
|
66515
|
-
if ( to === void 0 ) to = this.length;
|
|
66516
|
-
|
|
66517
|
-
if (from <= to)
|
|
66518
|
-
{ this.forEachInner(f, from, to, 0); }
|
|
66519
|
-
else
|
|
66520
|
-
{ this.forEachInvertedInner(f, from, to, 0); }
|
|
66521
|
-
};
|
|
66522
|
-
|
|
66523
|
-
// :: ((element: T, index: number) → U, ?number, ?number) → [U]
|
|
66524
|
-
// Map the given functions over the elements of the rope, producing
|
|
66525
|
-
// a flat array.
|
|
66526
|
-
RopeSequence.prototype.map = function map (f, from, to) {
|
|
66527
|
-
if ( from === void 0 ) from = 0;
|
|
66528
|
-
if ( to === void 0 ) to = this.length;
|
|
66529
|
-
|
|
66530
|
-
var result = [];
|
|
66531
|
-
this.forEach(function (elt, i) { return result.push(f(elt, i)); }, from, to);
|
|
66532
|
-
return result
|
|
66533
|
-
};
|
|
66534
|
-
|
|
66535
|
-
// :: (?union<[T], RopeSequence<T>>) → RopeSequence<T>
|
|
66536
|
-
// Create a rope representing the given array, or return the rope
|
|
66537
|
-
// itself if a rope was given.
|
|
66538
|
-
RopeSequence.from = function from (values) {
|
|
66539
|
-
if (values instanceof RopeSequence) { return values }
|
|
66540
|
-
return values && values.length ? new Leaf(values) : RopeSequence.empty
|
|
66541
|
-
};
|
|
66542
|
-
|
|
66543
|
-
var Leaf = /*@__PURE__*/(function (RopeSequence) {
|
|
66544
|
-
function Leaf(values) {
|
|
66545
|
-
RopeSequence.call(this);
|
|
66546
|
-
this.values = values;
|
|
66547
|
-
}
|
|
66548
|
-
|
|
66549
|
-
if ( RopeSequence ) Leaf.__proto__ = RopeSequence;
|
|
66550
|
-
Leaf.prototype = Object.create( RopeSequence && RopeSequence.prototype );
|
|
66551
|
-
Leaf.prototype.constructor = Leaf;
|
|
66552
|
-
|
|
66553
|
-
var prototypeAccessors = { length: { configurable: true },depth: { configurable: true } };
|
|
66554
|
-
|
|
66555
|
-
Leaf.prototype.flatten = function flatten () {
|
|
66556
|
-
return this.values
|
|
66557
|
-
};
|
|
66558
|
-
|
|
66559
|
-
Leaf.prototype.sliceInner = function sliceInner (from, to) {
|
|
66560
|
-
if (from == 0 && to == this.length) { return this }
|
|
66561
|
-
return new Leaf(this.values.slice(from, to))
|
|
66562
|
-
};
|
|
66563
|
-
|
|
66564
|
-
Leaf.prototype.getInner = function getInner (i) {
|
|
66565
|
-
return this.values[i]
|
|
66566
|
-
};
|
|
66567
|
-
|
|
66568
|
-
Leaf.prototype.forEachInner = function forEachInner (f, from, to, start) {
|
|
66569
|
-
for (var i = from; i < to; i++)
|
|
66570
|
-
{ if (f(this.values[i], start + i) === false) { return false } }
|
|
66571
|
-
};
|
|
66572
|
-
|
|
66573
|
-
Leaf.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
|
|
66574
|
-
for (var i = from - 1; i >= to; i--)
|
|
66575
|
-
{ if (f(this.values[i], start + i) === false) { return false } }
|
|
66576
|
-
};
|
|
66577
|
-
|
|
66578
|
-
Leaf.prototype.leafAppend = function leafAppend (other) {
|
|
66579
|
-
if (this.length + other.length <= GOOD_LEAF_SIZE)
|
|
66580
|
-
{ return new Leaf(this.values.concat(other.flatten())) }
|
|
66581
|
-
};
|
|
66582
|
-
|
|
66583
|
-
Leaf.prototype.leafPrepend = function leafPrepend (other) {
|
|
66584
|
-
if (this.length + other.length <= GOOD_LEAF_SIZE)
|
|
66585
|
-
{ return new Leaf(other.flatten().concat(this.values)) }
|
|
66586
|
-
};
|
|
66587
|
-
|
|
66588
|
-
prototypeAccessors.length.get = function () { return this.values.length };
|
|
66589
|
-
|
|
66590
|
-
prototypeAccessors.depth.get = function () { return 0 };
|
|
66591
|
-
|
|
66592
|
-
Object.defineProperties( Leaf.prototype, prototypeAccessors );
|
|
66593
|
-
|
|
66594
|
-
return Leaf;
|
|
66595
|
-
}(RopeSequence));
|
|
66596
|
-
|
|
66597
|
-
// :: RopeSequence
|
|
66598
|
-
// The empty rope sequence.
|
|
66599
|
-
RopeSequence.empty = new Leaf([]);
|
|
66600
|
-
|
|
66601
|
-
var Append = /*@__PURE__*/(function (RopeSequence) {
|
|
66602
|
-
function Append(left, right) {
|
|
66603
|
-
RopeSequence.call(this);
|
|
66604
|
-
this.left = left;
|
|
66605
|
-
this.right = right;
|
|
66606
|
-
this.length = left.length + right.length;
|
|
66607
|
-
this.depth = Math.max(left.depth, right.depth) + 1;
|
|
66608
|
-
}
|
|
66609
|
-
|
|
66610
|
-
if ( RopeSequence ) Append.__proto__ = RopeSequence;
|
|
66611
|
-
Append.prototype = Object.create( RopeSequence && RopeSequence.prototype );
|
|
66612
|
-
Append.prototype.constructor = Append;
|
|
66613
|
-
|
|
66614
|
-
Append.prototype.flatten = function flatten () {
|
|
66615
|
-
return this.left.flatten().concat(this.right.flatten())
|
|
66616
|
-
};
|
|
66617
|
-
|
|
66618
|
-
Append.prototype.getInner = function getInner (i) {
|
|
66619
|
-
return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length)
|
|
66620
|
-
};
|
|
66621
|
-
|
|
66622
|
-
Append.prototype.forEachInner = function forEachInner (f, from, to, start) {
|
|
66623
|
-
var leftLen = this.left.length;
|
|
66624
|
-
if (from < leftLen &&
|
|
66625
|
-
this.left.forEachInner(f, from, Math.min(to, leftLen), start) === false)
|
|
66626
|
-
{ return false }
|
|
66627
|
-
if (to > leftLen &&
|
|
66628
|
-
this.right.forEachInner(f, Math.max(from - leftLen, 0), Math.min(this.length, to) - leftLen, start + leftLen) === false)
|
|
66629
|
-
{ return false }
|
|
66630
|
-
};
|
|
66631
|
-
|
|
66632
|
-
Append.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
|
|
66633
|
-
var leftLen = this.left.length;
|
|
66634
|
-
if (from > leftLen &&
|
|
66635
|
-
this.right.forEachInvertedInner(f, from - leftLen, Math.max(to, leftLen) - leftLen, start + leftLen) === false)
|
|
66636
|
-
{ return false }
|
|
66637
|
-
if (to < leftLen &&
|
|
66638
|
-
this.left.forEachInvertedInner(f, Math.min(from, leftLen), to, start) === false)
|
|
66639
|
-
{ return false }
|
|
66640
|
-
};
|
|
66641
|
-
|
|
66642
|
-
Append.prototype.sliceInner = function sliceInner (from, to) {
|
|
66643
|
-
if (from == 0 && to == this.length) { return this }
|
|
66644
|
-
var leftLen = this.left.length;
|
|
66645
|
-
if (to <= leftLen) { return this.left.slice(from, to) }
|
|
66646
|
-
if (from >= leftLen) { return this.right.slice(from - leftLen, to - leftLen) }
|
|
66647
|
-
return this.left.slice(from, leftLen).append(this.right.slice(0, to - leftLen))
|
|
66648
|
-
};
|
|
66649
|
-
|
|
66650
|
-
Append.prototype.leafAppend = function leafAppend (other) {
|
|
66651
|
-
var inner = this.right.leafAppend(other);
|
|
66652
|
-
if (inner) { return new Append(this.left, inner) }
|
|
66653
|
-
};
|
|
66654
|
-
|
|
66655
|
-
Append.prototype.leafPrepend = function leafPrepend (other) {
|
|
66656
|
-
var inner = this.left.leafPrepend(other);
|
|
66657
|
-
if (inner) { return new Append(inner, this.right) }
|
|
66658
|
-
};
|
|
66659
|
-
|
|
66660
|
-
Append.prototype.appendInner = function appendInner (other) {
|
|
66661
|
-
if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1)
|
|
66662
|
-
{ return new Append(this.left, new Append(this.right, other)) }
|
|
66663
|
-
return new Append(this, other)
|
|
66664
|
-
};
|
|
66665
|
-
|
|
66666
|
-
return Append;
|
|
66667
|
-
}(RopeSequence));
|
|
66668
|
-
|
|
66669
|
-
// ProseMirror's history isn't simply a way to roll back to a previous
|
|
66670
|
-
// state, because ProseMirror supports applying changes without adding
|
|
66671
|
-
// them to the history (for example during collaboration).
|
|
66672
|
-
//
|
|
66673
|
-
// To this end, each 'Branch' (one for the undo history and one for
|
|
66674
|
-
// the redo history) keeps an array of 'Items', which can optionally
|
|
66675
|
-
// hold a step (an actual undoable change), and always hold a position
|
|
66676
|
-
// map (which is needed to move changes below them to apply to the
|
|
66677
|
-
// current document).
|
|
66678
|
-
//
|
|
66679
|
-
// An item that has both a step and a selection bookmark is the start
|
|
66680
|
-
// of an 'event' — a group of changes that will be undone or redone at
|
|
66681
|
-
// once. (It stores only the bookmark, since that way we don't have to
|
|
66682
|
-
// provide a document until the selection is actually applied, which
|
|
66683
|
-
// is useful when compressing.)
|
|
66684
|
-
// Used to schedule history compression
|
|
66685
|
-
const max_empty_items = 500;
|
|
66686
|
-
class Branch {
|
|
66687
|
-
constructor(items, eventCount) {
|
|
66688
|
-
this.items = items;
|
|
66689
|
-
this.eventCount = eventCount;
|
|
66690
|
-
}
|
|
66691
|
-
// Pop the latest event off the branch's history and apply it
|
|
66692
|
-
// to a document transform.
|
|
66693
|
-
popEvent(state, preserveItems) {
|
|
66694
|
-
if (this.eventCount == 0)
|
|
66695
|
-
return null;
|
|
66696
|
-
let end = this.items.length;
|
|
66697
|
-
for (;; end--) {
|
|
66698
|
-
let next = this.items.get(end - 1);
|
|
66699
|
-
if (next.selection) {
|
|
66700
|
-
--end;
|
|
66701
|
-
break;
|
|
66702
|
-
}
|
|
66703
|
-
}
|
|
66704
|
-
let remap, mapFrom;
|
|
66705
|
-
if (preserveItems) {
|
|
66706
|
-
remap = this.remapping(end, this.items.length);
|
|
66707
|
-
mapFrom = remap.maps.length;
|
|
66708
|
-
}
|
|
66709
|
-
let transform = state.tr;
|
|
66710
|
-
let selection, remaining;
|
|
66711
|
-
let addAfter = [], addBefore = [];
|
|
66712
|
-
this.items.forEach((item, i) => {
|
|
66713
|
-
if (!item.step) {
|
|
66714
|
-
if (!remap) {
|
|
66715
|
-
remap = this.remapping(end, i + 1);
|
|
66716
|
-
mapFrom = remap.maps.length;
|
|
66717
|
-
}
|
|
66718
|
-
mapFrom--;
|
|
66719
|
-
addBefore.push(item);
|
|
66720
|
-
return;
|
|
66721
|
-
}
|
|
66722
|
-
if (remap) {
|
|
66723
|
-
addBefore.push(new Item(item.map));
|
|
66724
|
-
let step = item.step.map(remap.slice(mapFrom)), map;
|
|
66725
|
-
if (step && transform.maybeStep(step).doc) {
|
|
66726
|
-
map = transform.mapping.maps[transform.mapping.maps.length - 1];
|
|
66727
|
-
addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length));
|
|
66728
|
-
}
|
|
66729
|
-
mapFrom--;
|
|
66730
|
-
if (map)
|
|
66731
|
-
remap.appendMap(map, mapFrom);
|
|
66732
|
-
}
|
|
66733
|
-
else {
|
|
66734
|
-
transform.maybeStep(item.step);
|
|
66735
|
-
}
|
|
66736
|
-
if (item.selection) {
|
|
66737
|
-
selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;
|
|
66738
|
-
remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1);
|
|
66739
|
-
return false;
|
|
66740
|
-
}
|
|
66741
|
-
}, this.items.length, 0);
|
|
66742
|
-
return { remaining: remaining, transform, selection: selection };
|
|
66743
|
-
}
|
|
66744
|
-
// Create a new branch with the given transform added.
|
|
66745
|
-
addTransform(transform, selection, histOptions, preserveItems) {
|
|
66746
|
-
let newItems = [], eventCount = this.eventCount;
|
|
66747
|
-
let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
|
|
66748
|
-
for (let i = 0; i < transform.steps.length; i++) {
|
|
66749
|
-
let step = transform.steps[i].invert(transform.docs[i]);
|
|
66750
|
-
let item = new Item(transform.mapping.maps[i], step, selection), merged;
|
|
66751
|
-
if (merged = lastItem && lastItem.merge(item)) {
|
|
66752
|
-
item = merged;
|
|
66753
|
-
if (i)
|
|
66754
|
-
newItems.pop();
|
|
66755
|
-
else
|
|
66756
|
-
oldItems = oldItems.slice(0, oldItems.length - 1);
|
|
66757
|
-
}
|
|
66758
|
-
newItems.push(item);
|
|
66759
|
-
if (selection) {
|
|
66760
|
-
eventCount++;
|
|
66761
|
-
selection = undefined;
|
|
66762
|
-
}
|
|
66763
|
-
if (!preserveItems)
|
|
66764
|
-
lastItem = item;
|
|
66765
|
-
}
|
|
66766
|
-
let overflow = eventCount - histOptions.depth;
|
|
66767
|
-
if (overflow > DEPTH_OVERFLOW) {
|
|
66768
|
-
oldItems = cutOffEvents(oldItems, overflow);
|
|
66769
|
-
eventCount -= overflow;
|
|
66770
|
-
}
|
|
66771
|
-
return new Branch(oldItems.append(newItems), eventCount);
|
|
66772
|
-
}
|
|
66773
|
-
remapping(from, to) {
|
|
66774
|
-
let maps = new Mapping;
|
|
66775
|
-
this.items.forEach((item, i) => {
|
|
66776
|
-
let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from
|
|
66777
|
-
? maps.maps.length - item.mirrorOffset : undefined;
|
|
66778
|
-
maps.appendMap(item.map, mirrorPos);
|
|
66779
|
-
}, from, to);
|
|
66780
|
-
return maps;
|
|
66781
|
-
}
|
|
66782
|
-
addMaps(array) {
|
|
66783
|
-
if (this.eventCount == 0)
|
|
66784
|
-
return this;
|
|
66785
|
-
return new Branch(this.items.append(array.map(map => new Item(map))), this.eventCount);
|
|
66786
|
-
}
|
|
66787
|
-
// When the collab module receives remote changes, the history has
|
|
66788
|
-
// to know about those, so that it can adjust the steps that were
|
|
66789
|
-
// rebased on top of the remote changes, and include the position
|
|
66790
|
-
// maps for the remote changes in its array of items.
|
|
66791
|
-
rebased(rebasedTransform, rebasedCount) {
|
|
66792
|
-
if (!this.eventCount)
|
|
66793
|
-
return this;
|
|
66794
|
-
let rebasedItems = [], start = Math.max(0, this.items.length - rebasedCount);
|
|
66795
|
-
let mapping = rebasedTransform.mapping;
|
|
66796
|
-
let newUntil = rebasedTransform.steps.length;
|
|
66797
|
-
let eventCount = this.eventCount;
|
|
66798
|
-
this.items.forEach(item => { if (item.selection)
|
|
66799
|
-
eventCount--; }, start);
|
|
66800
|
-
let iRebased = rebasedCount;
|
|
66801
|
-
this.items.forEach(item => {
|
|
66802
|
-
let pos = mapping.getMirror(--iRebased);
|
|
66803
|
-
if (pos == null)
|
|
66804
|
-
return;
|
|
66805
|
-
newUntil = Math.min(newUntil, pos);
|
|
66806
|
-
let map = mapping.maps[pos];
|
|
66807
|
-
if (item.step) {
|
|
66808
|
-
let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);
|
|
66809
|
-
let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
|
|
66810
|
-
if (selection)
|
|
66811
|
-
eventCount++;
|
|
66812
|
-
rebasedItems.push(new Item(map, step, selection));
|
|
66813
|
-
}
|
|
66814
|
-
else {
|
|
66815
|
-
rebasedItems.push(new Item(map));
|
|
66816
|
-
}
|
|
66817
|
-
}, start);
|
|
66818
|
-
let newMaps = [];
|
|
66819
|
-
for (let i = rebasedCount; i < newUntil; i++)
|
|
66820
|
-
newMaps.push(new Item(mapping.maps[i]));
|
|
66821
|
-
let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
|
|
66822
|
-
let branch = new Branch(items, eventCount);
|
|
66823
|
-
if (branch.emptyItemCount() > max_empty_items)
|
|
66824
|
-
branch = branch.compress(this.items.length - rebasedItems.length);
|
|
66825
|
-
return branch;
|
|
66917
|
+
class DropCursorView {
|
|
66918
|
+
constructor(editorView, options) {
|
|
66919
|
+
var _a;
|
|
66920
|
+
this.editorView = editorView;
|
|
66921
|
+
this.cursorPos = null;
|
|
66922
|
+
this.element = null;
|
|
66923
|
+
this.timeout = -1;
|
|
66924
|
+
this.lastDragEvent = null;
|
|
66925
|
+
this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1;
|
|
66926
|
+
this.color = options.color === false ? undefined : (options.color || "black");
|
|
66927
|
+
this.class = options.class;
|
|
66928
|
+
this.handlers = ["dragover", "dragend", "drop", "dragleave"].map(name => {
|
|
66929
|
+
let handler = (e) => { this[name](e); };
|
|
66930
|
+
editorView.dom.addEventListener(name, handler);
|
|
66931
|
+
return { name, handler };
|
|
66932
|
+
});
|
|
66826
66933
|
}
|
|
66827
|
-
|
|
66828
|
-
|
|
66829
|
-
this.
|
|
66830
|
-
count++; });
|
|
66831
|
-
return count;
|
|
66934
|
+
destroy() {
|
|
66935
|
+
this.setCursor(null);
|
|
66936
|
+
this.handlers.forEach(({ name, handler }) => this.editorView.dom.removeEventListener(name, handler));
|
|
66832
66937
|
}
|
|
66833
|
-
|
|
66834
|
-
|
|
66835
|
-
|
|
66836
|
-
|
|
66837
|
-
|
|
66838
|
-
|
|
66839
|
-
|
|
66840
|
-
|
|
66841
|
-
|
|
66842
|
-
|
|
66843
|
-
if (i >= upto) {
|
|
66844
|
-
items.push(item);
|
|
66845
|
-
if (item.selection)
|
|
66846
|
-
events++;
|
|
66938
|
+
update(editorView, prevState) {
|
|
66939
|
+
if (this.cursorPos != null && prevState.doc != editorView.state.doc) {
|
|
66940
|
+
// if we currently have an on-going drag event
|
|
66941
|
+
// we need to update the cursor position again and update the overlay
|
|
66942
|
+
if (this.lastDragEvent) {
|
|
66943
|
+
let target = this.computeTarget(this.lastDragEvent);
|
|
66944
|
+
if (target == this.cursorPos)
|
|
66945
|
+
this.updateOverlay();
|
|
66946
|
+
else
|
|
66947
|
+
this.setCursor(target);
|
|
66847
66948
|
}
|
|
66848
|
-
else
|
|
66849
|
-
|
|
66850
|
-
|
|
66851
|
-
|
|
66852
|
-
|
|
66853
|
-
|
|
66854
|
-
|
|
66855
|
-
|
|
66856
|
-
|
|
66857
|
-
|
|
66858
|
-
|
|
66859
|
-
|
|
66860
|
-
|
|
66861
|
-
|
|
66949
|
+
else {
|
|
66950
|
+
this.updateOverlay();
|
|
66951
|
+
}
|
|
66952
|
+
}
|
|
66953
|
+
}
|
|
66954
|
+
setCursor(pos) {
|
|
66955
|
+
if (pos == this.cursorPos)
|
|
66956
|
+
return;
|
|
66957
|
+
this.cursorPos = pos;
|
|
66958
|
+
if (pos == null) {
|
|
66959
|
+
this.element.parentNode.removeChild(this.element);
|
|
66960
|
+
this.element = null;
|
|
66961
|
+
}
|
|
66962
|
+
else {
|
|
66963
|
+
this.updateOverlay();
|
|
66964
|
+
}
|
|
66965
|
+
}
|
|
66966
|
+
updateOverlay() {
|
|
66967
|
+
let $pos = this.editorView.state.doc.resolve(this.cursorPos);
|
|
66968
|
+
let isBlock = !$pos.parent.inlineContent, rect;
|
|
66969
|
+
let editorDOM = this.editorView.dom, editorRect = editorDOM.getBoundingClientRect();
|
|
66970
|
+
let scaleX = editorRect.width / editorDOM.offsetWidth, scaleY = editorRect.height / editorDOM.offsetHeight;
|
|
66971
|
+
if (isBlock) {
|
|
66972
|
+
let before = $pos.nodeBefore, after = $pos.nodeAfter;
|
|
66973
|
+
if (before || after) {
|
|
66974
|
+
let node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0));
|
|
66975
|
+
if (node) {
|
|
66976
|
+
let nodeRect = node.getBoundingClientRect();
|
|
66977
|
+
let top = before ? nodeRect.bottom : nodeRect.top;
|
|
66978
|
+
if (before && after)
|
|
66979
|
+
top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2;
|
|
66980
|
+
let halfWidth = (this.width / 2) * scaleY;
|
|
66981
|
+
rect = { left: nodeRect.left, right: nodeRect.right, top: top - halfWidth, bottom: top + halfWidth };
|
|
66862
66982
|
}
|
|
66863
66983
|
}
|
|
66864
|
-
|
|
66865
|
-
|
|
66984
|
+
}
|
|
66985
|
+
if (!rect) {
|
|
66986
|
+
let coords = this.editorView.coordsAtPos(this.cursorPos);
|
|
66987
|
+
let halfWidth = (this.width / 2) * scaleX;
|
|
66988
|
+
rect = { left: coords.left - halfWidth, right: coords.left + halfWidth, top: coords.top, bottom: coords.bottom };
|
|
66989
|
+
}
|
|
66990
|
+
let parent = this.editorView.dom.offsetParent;
|
|
66991
|
+
if (!this.element) {
|
|
66992
|
+
this.element = parent.appendChild(document.createElement("div"));
|
|
66993
|
+
if (this.class)
|
|
66994
|
+
this.element.className = this.class;
|
|
66995
|
+
this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;";
|
|
66996
|
+
if (this.color) {
|
|
66997
|
+
this.element.style.backgroundColor = this.color;
|
|
66866
66998
|
}
|
|
66867
|
-
}
|
|
66868
|
-
|
|
66999
|
+
}
|
|
67000
|
+
this.element.classList.toggle("prosemirror-dropcursor-block", isBlock);
|
|
67001
|
+
this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock);
|
|
67002
|
+
let parentLeft, parentTop;
|
|
67003
|
+
if (!parent || parent == document.body && getComputedStyle(parent).position == "static") {
|
|
67004
|
+
parentLeft = -pageXOffset;
|
|
67005
|
+
parentTop = -pageYOffset;
|
|
67006
|
+
}
|
|
67007
|
+
else {
|
|
67008
|
+
let rect = parent.getBoundingClientRect();
|
|
67009
|
+
let parentScaleX = rect.width / parent.offsetWidth, parentScaleY = rect.height / parent.offsetHeight;
|
|
67010
|
+
parentLeft = rect.left - parent.scrollLeft * parentScaleX;
|
|
67011
|
+
parentTop = rect.top - parent.scrollTop * parentScaleY;
|
|
67012
|
+
}
|
|
67013
|
+
this.element.style.left = (rect.left - parentLeft) / scaleX + "px";
|
|
67014
|
+
this.element.style.top = (rect.top - parentTop) / scaleY + "px";
|
|
67015
|
+
this.element.style.width = (rect.right - rect.left) / scaleX + "px";
|
|
67016
|
+
this.element.style.height = (rect.bottom - rect.top) / scaleY + "px";
|
|
66869
67017
|
}
|
|
66870
|
-
|
|
66871
|
-
|
|
66872
|
-
|
|
66873
|
-
|
|
66874
|
-
|
|
66875
|
-
|
|
66876
|
-
|
|
66877
|
-
|
|
67018
|
+
scheduleRemoval(timeout) {
|
|
67019
|
+
clearTimeout(this.timeout);
|
|
67020
|
+
this.timeout = setTimeout(() => this.setCursor(null), timeout);
|
|
67021
|
+
}
|
|
67022
|
+
computeTarget(event) {
|
|
67023
|
+
let pos = this.editorView.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
67024
|
+
let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);
|
|
67025
|
+
let disableDropCursor = node && node.type.spec.disableDropCursor;
|
|
67026
|
+
let disabled = typeof disableDropCursor == "function"
|
|
67027
|
+
? disableDropCursor(this.editorView, pos, event)
|
|
67028
|
+
: disableDropCursor;
|
|
67029
|
+
if (!pos || disabled)
|
|
67030
|
+
return null;
|
|
67031
|
+
let target = pos.pos;
|
|
67032
|
+
if (this.editorView.dragging && this.editorView.dragging.slice) {
|
|
67033
|
+
let point = dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice);
|
|
67034
|
+
if (point != null)
|
|
67035
|
+
target = point;
|
|
66878
67036
|
}
|
|
66879
|
-
|
|
66880
|
-
return items.slice(cutPoint);
|
|
66881
|
-
}
|
|
66882
|
-
class Item {
|
|
66883
|
-
constructor(
|
|
66884
|
-
// The (forward) step map for this item.
|
|
66885
|
-
map,
|
|
66886
|
-
// The inverted step
|
|
66887
|
-
step,
|
|
66888
|
-
// If this is non-null, this item is the start of a group, and
|
|
66889
|
-
// this selection is the starting selection for the group (the one
|
|
66890
|
-
// that was active before the first step was applied)
|
|
66891
|
-
selection,
|
|
66892
|
-
// If this item is the inverse of a previous mapping on the stack,
|
|
66893
|
-
// this points at the inverse's offset
|
|
66894
|
-
mirrorOffset) {
|
|
66895
|
-
this.map = map;
|
|
66896
|
-
this.step = step;
|
|
66897
|
-
this.selection = selection;
|
|
66898
|
-
this.mirrorOffset = mirrorOffset;
|
|
67037
|
+
return target;
|
|
66899
67038
|
}
|
|
66900
|
-
|
|
66901
|
-
if (this.
|
|
66902
|
-
|
|
66903
|
-
|
|
66904
|
-
|
|
67039
|
+
dragover(event) {
|
|
67040
|
+
if (!this.editorView.editable)
|
|
67041
|
+
return;
|
|
67042
|
+
this.lastDragEvent = event;
|
|
67043
|
+
let target = this.computeTarget(event);
|
|
67044
|
+
if (target != null) {
|
|
67045
|
+
this.setCursor(target);
|
|
67046
|
+
this.scheduleRemoval(5000);
|
|
66905
67047
|
}
|
|
66906
67048
|
}
|
|
66907
|
-
|
|
66908
|
-
|
|
66909
|
-
|
|
66910
|
-
|
|
66911
|
-
|
|
66912
|
-
|
|
66913
|
-
|
|
66914
|
-
this.
|
|
66915
|
-
|
|
66916
|
-
this.prevTime = prevTime;
|
|
66917
|
-
this.prevComposition = prevComposition;
|
|
67049
|
+
dragend() {
|
|
67050
|
+
this.scheduleRemoval(20);
|
|
67051
|
+
}
|
|
67052
|
+
drop() {
|
|
67053
|
+
this.scheduleRemoval(20);
|
|
67054
|
+
}
|
|
67055
|
+
dragleave(event) {
|
|
67056
|
+
if (!this.editorView.dom.contains(event.relatedTarget))
|
|
67057
|
+
this.setCursor(null);
|
|
66918
67058
|
}
|
|
66919
67059
|
}
|
|
66920
|
-
|
|
66921
|
-
|
|
66922
|
-
|
|
66923
|
-
|
|
66924
|
-
|
|
66925
|
-
|
|
66926
|
-
|
|
66927
|
-
|
|
66928
|
-
|
|
66929
|
-
|
|
66930
|
-
|
|
67060
|
+
|
|
67061
|
+
/**
|
|
67062
|
+
Gap cursor selections are represented using this class. Its
|
|
67063
|
+
`$anchor` and `$head` properties both point at the cursor position.
|
|
67064
|
+
*/
|
|
67065
|
+
class GapCursor extends Selection$2 {
|
|
67066
|
+
/**
|
|
67067
|
+
Create a gap cursor.
|
|
67068
|
+
*/
|
|
67069
|
+
constructor($pos) {
|
|
67070
|
+
super($pos, $pos);
|
|
66931
67071
|
}
|
|
66932
|
-
|
|
66933
|
-
|
|
66934
|
-
|
|
66935
|
-
else
|
|
66936
|
-
return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);
|
|
67072
|
+
map(doc, mapping) {
|
|
67073
|
+
let $pos = doc.resolve(mapping.map(this.head));
|
|
67074
|
+
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$2.near($pos);
|
|
66937
67075
|
}
|
|
66938
|
-
|
|
66939
|
-
|
|
66940
|
-
|
|
66941
|
-
let newGroup = history.prevTime == 0 ||
|
|
66942
|
-
(!appended && history.prevComposition != composition &&
|
|
66943
|
-
(history.prevTime < (tr.time || 0) - options.newGroupDelay || !isAdjacentTo(tr, history.prevRanges)));
|
|
66944
|
-
let prevRanges = appended ? mapRanges(history.prevRanges, tr.mapping) : rangesFor(tr.mapping.maps);
|
|
66945
|
-
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);
|
|
67076
|
+
content() { return Slice.empty; }
|
|
67077
|
+
eq(other) {
|
|
67078
|
+
return other instanceof GapCursor && other.head == this.head;
|
|
66946
67079
|
}
|
|
66947
|
-
|
|
66948
|
-
|
|
66949
|
-
// content has been rebased.
|
|
66950
|
-
return new HistoryState(history.done.rebased(tr, rebased), history.undone.rebased(tr, rebased), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
|
67080
|
+
toJSON() {
|
|
67081
|
+
return { type: "gapcursor", pos: this.head };
|
|
66951
67082
|
}
|
|
66952
|
-
|
|
66953
|
-
|
|
67083
|
+
/**
|
|
67084
|
+
@internal
|
|
67085
|
+
*/
|
|
67086
|
+
static fromJSON(doc, json) {
|
|
67087
|
+
if (typeof json.pos != "number")
|
|
67088
|
+
throw new RangeError("Invalid input for GapCursor.fromJSON");
|
|
67089
|
+
return new GapCursor(doc.resolve(json.pos));
|
|
67090
|
+
}
|
|
67091
|
+
/**
|
|
67092
|
+
@internal
|
|
67093
|
+
*/
|
|
67094
|
+
getBookmark() { return new GapBookmark(this.anchor); }
|
|
67095
|
+
/**
|
|
67096
|
+
@internal
|
|
67097
|
+
*/
|
|
67098
|
+
static valid($pos) {
|
|
67099
|
+
let parent = $pos.parent;
|
|
67100
|
+
if (parent.inlineContent || !closedBefore($pos) || !closedAfter($pos))
|
|
67101
|
+
return false;
|
|
67102
|
+
let override = parent.type.spec.allowGapCursor;
|
|
67103
|
+
if (override != null)
|
|
67104
|
+
return override;
|
|
67105
|
+
let deflt = parent.contentMatchAt($pos.index()).defaultType;
|
|
67106
|
+
return deflt && deflt.isTextblock;
|
|
67107
|
+
}
|
|
67108
|
+
/**
|
|
67109
|
+
@internal
|
|
67110
|
+
*/
|
|
67111
|
+
static findGapCursorFrom($pos, dir, mustMove = false) {
|
|
67112
|
+
search: for (;;) {
|
|
67113
|
+
if (!mustMove && GapCursor.valid($pos))
|
|
67114
|
+
return $pos;
|
|
67115
|
+
let pos = $pos.pos, next = null;
|
|
67116
|
+
// Scan up from this position
|
|
67117
|
+
for (let d = $pos.depth;; d--) {
|
|
67118
|
+
let parent = $pos.node(d);
|
|
67119
|
+
if (dir > 0 ? $pos.indexAfter(d) < parent.childCount : $pos.index(d) > 0) {
|
|
67120
|
+
next = parent.child(dir > 0 ? $pos.indexAfter(d) : $pos.index(d) - 1);
|
|
67121
|
+
break;
|
|
67122
|
+
}
|
|
67123
|
+
else if (d == 0) {
|
|
67124
|
+
return null;
|
|
67125
|
+
}
|
|
67126
|
+
pos += dir;
|
|
67127
|
+
let $cur = $pos.doc.resolve(pos);
|
|
67128
|
+
if (GapCursor.valid($cur))
|
|
67129
|
+
return $cur;
|
|
67130
|
+
}
|
|
67131
|
+
// And then down into the next node
|
|
67132
|
+
for (;;) {
|
|
67133
|
+
let inside = dir > 0 ? next.firstChild : next.lastChild;
|
|
67134
|
+
if (!inside) {
|
|
67135
|
+
if (next.isAtom && !next.isText && !NodeSelection.isSelectable(next)) {
|
|
67136
|
+
$pos = $pos.doc.resolve(pos + next.nodeSize * dir);
|
|
67137
|
+
mustMove = false;
|
|
67138
|
+
continue search;
|
|
67139
|
+
}
|
|
67140
|
+
break;
|
|
67141
|
+
}
|
|
67142
|
+
next = inside;
|
|
67143
|
+
pos += dir;
|
|
67144
|
+
let $cur = $pos.doc.resolve(pos);
|
|
67145
|
+
if (GapCursor.valid($cur))
|
|
67146
|
+
return $cur;
|
|
67147
|
+
}
|
|
67148
|
+
return null;
|
|
67149
|
+
}
|
|
66954
67150
|
}
|
|
66955
67151
|
}
|
|
66956
|
-
|
|
66957
|
-
|
|
66958
|
-
|
|
66959
|
-
|
|
66960
|
-
|
|
66961
|
-
|
|
66962
|
-
|
|
66963
|
-
|
|
66964
|
-
|
|
66965
|
-
|
|
66966
|
-
|
|
66967
|
-
|
|
67152
|
+
GapCursor.prototype.visible = false;
|
|
67153
|
+
GapCursor.findFrom = GapCursor.findGapCursorFrom;
|
|
67154
|
+
Selection$2.jsonID("gapcursor", GapCursor);
|
|
67155
|
+
class GapBookmark {
|
|
67156
|
+
constructor(pos) {
|
|
67157
|
+
this.pos = pos;
|
|
67158
|
+
}
|
|
67159
|
+
map(mapping) {
|
|
67160
|
+
return new GapBookmark(mapping.map(this.pos));
|
|
67161
|
+
}
|
|
67162
|
+
resolve(doc) {
|
|
67163
|
+
let $pos = doc.resolve(this.pos);
|
|
67164
|
+
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$2.near($pos);
|
|
67165
|
+
}
|
|
66968
67166
|
}
|
|
66969
|
-
function
|
|
66970
|
-
|
|
66971
|
-
for (let i = maps.length - 1; i >= 0 && result.length == 0; i--)
|
|
66972
|
-
maps[i].forEach((_from, _to, from, to) => result.push(from, to));
|
|
66973
|
-
return result;
|
|
67167
|
+
function needsGap(type) {
|
|
67168
|
+
return type.isAtom || type.spec.isolating || type.spec.createGapCursor;
|
|
66974
67169
|
}
|
|
66975
|
-
function
|
|
66976
|
-
|
|
66977
|
-
|
|
66978
|
-
|
|
66979
|
-
|
|
66980
|
-
|
|
66981
|
-
|
|
66982
|
-
|
|
67170
|
+
function closedBefore($pos) {
|
|
67171
|
+
for (let d = $pos.depth; d >= 0; d--) {
|
|
67172
|
+
let index = $pos.index(d), parent = $pos.node(d);
|
|
67173
|
+
// At the start of this parent, look at next one
|
|
67174
|
+
if (index == 0) {
|
|
67175
|
+
if (parent.type.spec.isolating)
|
|
67176
|
+
return true;
|
|
67177
|
+
continue;
|
|
67178
|
+
}
|
|
67179
|
+
// See if the node before (or its first ancestor) is closed
|
|
67180
|
+
for (let before = parent.child(index - 1);; before = before.lastChild) {
|
|
67181
|
+
if ((before.childCount == 0 && !before.inlineContent) || needsGap(before.type))
|
|
67182
|
+
return true;
|
|
67183
|
+
if (before.inlineContent)
|
|
67184
|
+
return false;
|
|
67185
|
+
}
|
|
66983
67186
|
}
|
|
66984
|
-
|
|
66985
|
-
|
|
66986
|
-
// Apply the latest event from one branch to the document and shift the event
|
|
66987
|
-
// onto the other branch.
|
|
66988
|
-
function histTransaction(history, state, redo) {
|
|
66989
|
-
let preserveItems = mustPreserveItems(state);
|
|
66990
|
-
let histOptions = historyKey.get(state).spec.config;
|
|
66991
|
-
let pop = (redo ? history.undone : history.done).popEvent(state, preserveItems);
|
|
66992
|
-
if (!pop)
|
|
66993
|
-
return null;
|
|
66994
|
-
let selection = pop.selection.resolve(pop.transform.doc);
|
|
66995
|
-
let added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);
|
|
66996
|
-
let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1);
|
|
66997
|
-
return pop.transform.setSelection(selection).setMeta(historyKey, { redo, historyState: newHist });
|
|
67187
|
+
// Hit start of document
|
|
67188
|
+
return true;
|
|
66998
67189
|
}
|
|
66999
|
-
|
|
67000
|
-
|
|
67001
|
-
|
|
67002
|
-
|
|
67003
|
-
|
|
67004
|
-
|
|
67005
|
-
|
|
67006
|
-
|
|
67007
|
-
|
|
67008
|
-
|
|
67009
|
-
|
|
67010
|
-
if (
|
|
67011
|
-
|
|
67012
|
-
|
|
67013
|
-
}
|
|
67190
|
+
function closedAfter($pos) {
|
|
67191
|
+
for (let d = $pos.depth; d >= 0; d--) {
|
|
67192
|
+
let index = $pos.indexAfter(d), parent = $pos.node(d);
|
|
67193
|
+
if (index == parent.childCount) {
|
|
67194
|
+
if (parent.type.spec.isolating)
|
|
67195
|
+
return true;
|
|
67196
|
+
continue;
|
|
67197
|
+
}
|
|
67198
|
+
for (let after = parent.child(index);; after = after.firstChild) {
|
|
67199
|
+
if ((after.childCount == 0 && !after.inlineContent) || needsGap(after.type))
|
|
67200
|
+
return true;
|
|
67201
|
+
if (after.inlineContent)
|
|
67202
|
+
return false;
|
|
67203
|
+
}
|
|
67014
67204
|
}
|
|
67015
|
-
return
|
|
67205
|
+
return true;
|
|
67016
67206
|
}
|
|
67017
|
-
const historyKey = new PluginKey("history");
|
|
67018
|
-
const closeHistoryKey = new PluginKey("closeHistory");
|
|
67019
|
-
/**
|
|
67020
|
-
Returns a plugin that enables the undo history for an editor. The
|
|
67021
|
-
plugin will track undo and redo stacks, which can be used with the
|
|
67022
|
-
[`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.
|
|
67023
67207
|
|
|
67024
|
-
|
|
67025
|
-
|
|
67026
|
-
|
|
67208
|
+
/**
|
|
67209
|
+
Create a gap cursor plugin. When enabled, this will capture clicks
|
|
67210
|
+
near and arrow-key-motion past places that don't have a normally
|
|
67211
|
+
selectable position nearby, and create a gap cursor selection for
|
|
67212
|
+
them. The cursor is drawn as an element with class
|
|
67213
|
+
`ProseMirror-gapcursor`. You can either include
|
|
67214
|
+
`style/gapcursor.css` from the package's directory or add your own
|
|
67215
|
+
styles to make it visible.
|
|
67027
67216
|
*/
|
|
67028
|
-
function
|
|
67029
|
-
config = { depth: config.depth || 100,
|
|
67030
|
-
newGroupDelay: config.newGroupDelay || 500 };
|
|
67217
|
+
function gapCursor() {
|
|
67031
67218
|
return new Plugin({
|
|
67032
|
-
key: historyKey,
|
|
67033
|
-
state: {
|
|
67034
|
-
init() {
|
|
67035
|
-
return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);
|
|
67036
|
-
},
|
|
67037
|
-
apply(tr, hist, state) {
|
|
67038
|
-
return applyTransaction(hist, state, tr, config);
|
|
67039
|
-
}
|
|
67040
|
-
},
|
|
67041
|
-
config,
|
|
67042
67219
|
props: {
|
|
67043
|
-
|
|
67044
|
-
|
|
67045
|
-
|
|
67046
|
-
|
|
67047
|
-
|
|
67048
|
-
|
|
67049
|
-
|
|
67050
|
-
return command(view.state, view.dispatch);
|
|
67051
|
-
}
|
|
67052
|
-
}
|
|
67220
|
+
decorations: drawGapCursor,
|
|
67221
|
+
createSelectionBetween(_view, $anchor, $head) {
|
|
67222
|
+
return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null;
|
|
67223
|
+
},
|
|
67224
|
+
handleClick,
|
|
67225
|
+
handleKeyDown,
|
|
67226
|
+
handleDOMEvents: { beforeinput: beforeinput }
|
|
67053
67227
|
}
|
|
67054
67228
|
});
|
|
67055
67229
|
}
|
|
67056
|
-
|
|
67057
|
-
|
|
67058
|
-
|
|
67059
|
-
|
|
67060
|
-
|
|
67061
|
-
|
|
67062
|
-
|
|
67063
|
-
|
|
67064
|
-
|
|
67230
|
+
const handleKeyDown = keydownHandler({
|
|
67231
|
+
"ArrowLeft": arrow("horiz", -1),
|
|
67232
|
+
"ArrowRight": arrow("horiz", 1),
|
|
67233
|
+
"ArrowUp": arrow("vert", -1),
|
|
67234
|
+
"ArrowDown": arrow("vert", 1)
|
|
67235
|
+
});
|
|
67236
|
+
function arrow(axis, dir) {
|
|
67237
|
+
const dirStr = axis == "vert" ? (dir > 0 ? "down" : "up") : (dir > 0 ? "right" : "left");
|
|
67238
|
+
return function (state, dispatch, view) {
|
|
67239
|
+
let sel = state.selection;
|
|
67240
|
+
let $start = dir > 0 ? sel.$to : sel.$from, mustMove = sel.empty;
|
|
67241
|
+
if (sel instanceof TextSelection) {
|
|
67242
|
+
if (!view.endOfTextblock(dirStr) || $start.depth == 0)
|
|
67243
|
+
return false;
|
|
67244
|
+
mustMove = false;
|
|
67245
|
+
$start = state.doc.resolve(dir > 0 ? $start.after() : $start.before());
|
|
67065
67246
|
}
|
|
67247
|
+
let $found = GapCursor.findGapCursorFrom($start, dir, mustMove);
|
|
67248
|
+
if (!$found)
|
|
67249
|
+
return false;
|
|
67250
|
+
if (dispatch)
|
|
67251
|
+
dispatch(state.tr.setSelection(new GapCursor($found)));
|
|
67066
67252
|
return true;
|
|
67067
67253
|
};
|
|
67068
67254
|
}
|
|
67069
|
-
|
|
67070
|
-
|
|
67071
|
-
|
|
67072
|
-
|
|
67073
|
-
|
|
67074
|
-
|
|
67075
|
-
|
|
67076
|
-
|
|
67255
|
+
function handleClick(view, pos, event) {
|
|
67256
|
+
if (!view || !view.editable)
|
|
67257
|
+
return false;
|
|
67258
|
+
let $pos = view.state.doc.resolve(pos);
|
|
67259
|
+
if (!GapCursor.valid($pos))
|
|
67260
|
+
return false;
|
|
67261
|
+
let clickPos = view.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
67262
|
+
if (clickPos && clickPos.inside > -1 && NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside)))
|
|
67263
|
+
return false;
|
|
67264
|
+
view.dispatch(view.state.tr.setSelection(new GapCursor($pos)));
|
|
67265
|
+
return true;
|
|
67266
|
+
}
|
|
67267
|
+
// This is a hack that, when a composition starts while a gap cursor
|
|
67268
|
+
// is active, quickly creates an inline context for the composition to
|
|
67269
|
+
// happen in, to avoid it being aborted by the DOM selection being
|
|
67270
|
+
// moved into a valid position.
|
|
67271
|
+
function beforeinput(view, event) {
|
|
67272
|
+
if (event.inputType != "insertCompositionText" || !(view.state.selection instanceof GapCursor))
|
|
67273
|
+
return false;
|
|
67274
|
+
let { $from } = view.state.selection;
|
|
67275
|
+
let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text);
|
|
67276
|
+
if (!insert)
|
|
67277
|
+
return false;
|
|
67278
|
+
let frag = Fragment.empty;
|
|
67279
|
+
for (let i = insert.length - 1; i >= 0; i--)
|
|
67280
|
+
frag = Fragment.from(insert[i].createAndFill(null, frag));
|
|
67281
|
+
let tr = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0));
|
|
67282
|
+
tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + 1)));
|
|
67283
|
+
view.dispatch(tr);
|
|
67284
|
+
return false;
|
|
67285
|
+
}
|
|
67286
|
+
function drawGapCursor(state) {
|
|
67287
|
+
if (!(state.selection instanceof GapCursor))
|
|
67288
|
+
return null;
|
|
67289
|
+
let node = document.createElement("div");
|
|
67290
|
+
node.className = "ProseMirror-gapcursor";
|
|
67291
|
+
return DecorationSet.create(state.doc, [Decoration.widget(state.selection.head, node, { key: "gapcursor" })]);
|
|
67292
|
+
}
|
|
67077
67293
|
|
|
67078
67294
|
//#region src/character-count/character-count.ts
|
|
67079
67295
|
/**
|
|
@@ -97669,12 +97885,12 @@ focus outline in that case.
|
|
|
97669
97885
|
toDOMStream(options) {
|
|
97670
97886
|
return streamAdapters.toDOMStream((this._closedPromiseResolve || this._error)
|
|
97671
97887
|
? this
|
|
97672
|
-
: this._values
|
|
97888
|
+
: this._values);
|
|
97673
97889
|
}
|
|
97674
97890
|
toNodeStream(options) {
|
|
97675
97891
|
return streamAdapters.toNodeStream((this._closedPromiseResolve || this._error)
|
|
97676
97892
|
? this
|
|
97677
|
-
: this._values
|
|
97893
|
+
: this._values);
|
|
97678
97894
|
}
|
|
97679
97895
|
throw(_) {
|
|
97680
97896
|
return __awaiter(this, void 0, void 0, function* () { yield this.abort(_); return ITERATOR_DONE; });
|
|
@@ -100065,7 +100281,7 @@ focus outline in that case.
|
|
|
100065
100281
|
toNodeStream() {
|
|
100066
100282
|
return streamAdapters.toNodeStream((this.isSync()
|
|
100067
100283
|
? { [Symbol.iterator]: () => this }
|
|
100068
|
-
: { [Symbol.asyncIterator]: () => this })
|
|
100284
|
+
: { [Symbol.asyncIterator]: () => this }));
|
|
100069
100285
|
}
|
|
100070
100286
|
/** @nocollapse */
|
|
100071
100287
|
// @ts-ignore
|
|
@@ -106734,15 +106950,17 @@ focus outline in that case.
|
|
|
106734
106950
|
id="${(_, c) => `${c.parent.menuId}-option-${c.index}`}"
|
|
106735
106951
|
class="chip-selector-option"
|
|
106736
106952
|
data-option-value="${x => x}"
|
|
106953
|
+
aria-selected="${(_, c) => String(c.index === c.parent.activeOptionIndex)}"
|
|
106737
106954
|
>
|
|
106738
106955
|
${x => x}
|
|
106739
106956
|
</${menuItemTag}>
|
|
106740
|
-
|
|
106957
|
+
`, { positioning: true })}
|
|
106741
106958
|
${when(x => x.customValueCandidate.length > 0, html `
|
|
106742
106959
|
<${menuItemTag}
|
|
106743
106960
|
id="${x => `${x.menuId}-option-create`}"
|
|
106744
106961
|
class="chip-selector-option chip-selector-create-option"
|
|
106745
106962
|
data-option-value="${x => x.customValueCandidate}"
|
|
106963
|
+
aria-selected="${x => String(x.activeOptionIndex === x.visibleOptionList.length)}"
|
|
106746
106964
|
>
|
|
106747
106965
|
${x => x.createOptionLabel}
|
|
106748
106966
|
</${menuItemTag}>
|
|
@@ -107007,10 +107225,6 @@ focus outline in that case.
|
|
|
107007
107225
|
}
|
|
107008
107226
|
}
|
|
107009
107227
|
syncActiveOption() {
|
|
107010
|
-
const options = Array.from(this.shadowRoot?.querySelectorAll('.chip-selector-option') ?? []);
|
|
107011
|
-
options.forEach((option, index) => {
|
|
107012
|
-
option.setAttribute('aria-selected', String(index === this.activeOptionIndex));
|
|
107013
|
-
});
|
|
107014
107228
|
if (this.activeOptionIndex < 0) {
|
|
107015
107229
|
this.activeOptionId = null;
|
|
107016
107230
|
}
|