@ni/ok-components 1.10.0 → 1.10.2
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 +1807 -1578
- package/dist/all-components-bundle.js.map +1 -1
- package/dist/all-components-bundle.min.js +3543 -3494
- package/dist/all-components-bundle.min.js.map +1 -1
- package/dist/custom-elements.json +200 -200
- package/dist/custom-elements.md +34 -34
- 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
|
@@ -20872,18 +20872,27 @@ Defines an interaction area clip-path that leaves out the severity text so it is
|
|
|
20872
20872
|
}
|
|
20873
20873
|
|
|
20874
20874
|
.icon {
|
|
20875
|
-
|
|
20876
|
-
|
|
20877
|
-
justify-content: center;
|
|
20878
|
-
margin-top: 8px;
|
|
20875
|
+
display: none;
|
|
20876
|
+
margin: 8px ${smallPadding} 0 ${standardPadding};
|
|
20879
20877
|
flex: 0 0 auto;
|
|
20880
20878
|
opacity: 0.6;
|
|
20881
20879
|
}
|
|
20882
20880
|
|
|
20881
|
+
:host([severity='error']) .icon,
|
|
20882
|
+
:host([severity='warning']) .icon,
|
|
20883
|
+
:host([severity='information']) .icon {
|
|
20884
|
+
display: flex;
|
|
20885
|
+
}
|
|
20886
|
+
|
|
20883
20887
|
.text {
|
|
20884
20888
|
display: inline;
|
|
20885
|
-
margin
|
|
20886
|
-
|
|
20889
|
+
margin: 7px 0 7px ${standardPadding};
|
|
20890
|
+
}
|
|
20891
|
+
|
|
20892
|
+
:host([severity='error']) .text,
|
|
20893
|
+
:host([severity='warning']) .text,
|
|
20894
|
+
:host([severity='information']) .text {
|
|
20895
|
+
margin-left: 0;
|
|
20887
20896
|
}
|
|
20888
20897
|
|
|
20889
20898
|
slot[name='title'] {
|
|
@@ -20914,14 +20923,20 @@ Defines an interaction area clip-path that leaves out the severity text so it is
|
|
|
20914
20923
|
white-space: nowrap;
|
|
20915
20924
|
}
|
|
20916
20925
|
|
|
20926
|
+
:host([prevent-dismiss]) slot[name='action'] {
|
|
20927
|
+
margin-right: 12px;
|
|
20928
|
+
}
|
|
20929
|
+
|
|
20917
20930
|
slot[name='action']::slotted(nimble-anchor) {
|
|
20918
20931
|
font-size: 12.8px;
|
|
20919
20932
|
}
|
|
20920
20933
|
|
|
20921
20934
|
.dismiss {
|
|
20922
|
-
|
|
20923
|
-
|
|
20924
|
-
|
|
20935
|
+
margin: 0 12px 0 ${standardPadding};
|
|
20936
|
+
}
|
|
20937
|
+
|
|
20938
|
+
:host([prevent-dismiss]) .dismiss {
|
|
20939
|
+
display: none;
|
|
20925
20940
|
}
|
|
20926
20941
|
`.withBehaviors(themeBehavior(Theme.light, css `
|
|
20927
20942
|
:host {
|
|
@@ -29805,7 +29820,6 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
29805
29820
|
if (!type)
|
|
29806
29821
|
throw new RangeError(`There is no mark type ${json.type} in this schema`);
|
|
29807
29822
|
let mark = type.create(json.attrs);
|
|
29808
|
-
type.checkAttrs(mark.attrs);
|
|
29809
29823
|
return mark;
|
|
29810
29824
|
}
|
|
29811
29825
|
/**
|
|
@@ -30785,11 +30799,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
30785
30799
|
*/
|
|
30786
30800
|
check() {
|
|
30787
30801
|
this.type.checkContent(this.content);
|
|
30788
|
-
this.type.
|
|
30802
|
+
checkAttrs(this.type.attrs, this.attrs, "node", this.type.name);
|
|
30789
30803
|
let copy = Mark$1.none;
|
|
30790
30804
|
for (let i = 0; i < this.marks.length; i++) {
|
|
30791
30805
|
let mark = this.marks[i];
|
|
30792
|
-
mark.type.
|
|
30806
|
+
checkAttrs(mark.type.attrs, mark.attrs, "mark", mark.type.name);
|
|
30793
30807
|
copy = mark.addToSet(copy);
|
|
30794
30808
|
}
|
|
30795
30809
|
if (!Mark$1.sameSet(copy, this.marks))
|
|
@@ -30830,7 +30844,6 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
30830
30844
|
}
|
|
30831
30845
|
let content = Fragment.fromJSON(schema, json.content);
|
|
30832
30846
|
let node = schema.nodeType(json.type).create(json.attrs, content, marks);
|
|
30833
|
-
node.type.checkAttrs(node.attrs);
|
|
30834
30847
|
return node;
|
|
30835
30848
|
}
|
|
30836
30849
|
};
|
|
@@ -30880,6 +30893,15 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
30880
30893
|
str = marks[i].type.name + "(" + str + ")";
|
|
30881
30894
|
return str;
|
|
30882
30895
|
}
|
|
30896
|
+
function checkAttrs(attrs, values, type, name) {
|
|
30897
|
+
for (let attr in values)
|
|
30898
|
+
if (!(attr in attrs))
|
|
30899
|
+
throw new RangeError(`Unsupported attribute ${attr} for ${type} of type ${name}`);
|
|
30900
|
+
for (let attr in attrs) {
|
|
30901
|
+
if (attrs[attr].validate)
|
|
30902
|
+
attrs[attr].validate(values[attr]);
|
|
30903
|
+
}
|
|
30904
|
+
}
|
|
30883
30905
|
|
|
30884
30906
|
/**
|
|
30885
30907
|
Instances of this class represent a match state of a node type's
|
|
@@ -31334,27 +31356,21 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
31334
31356
|
function computeAttrs(attrs, value) {
|
|
31335
31357
|
let built = Object.create(null);
|
|
31336
31358
|
for (let name in attrs) {
|
|
31359
|
+
let attr = attrs[name];
|
|
31337
31360
|
let given = value && value[name];
|
|
31338
31361
|
if (given === undefined) {
|
|
31339
|
-
let attr = attrs[name];
|
|
31340
31362
|
if (attr.hasDefault)
|
|
31341
31363
|
given = attr.default;
|
|
31342
31364
|
else
|
|
31343
31365
|
throw new RangeError("No value supplied for attribute " + name);
|
|
31344
31366
|
}
|
|
31367
|
+
else if (attr.validate) {
|
|
31368
|
+
attr.validate(given);
|
|
31369
|
+
}
|
|
31345
31370
|
built[name] = given;
|
|
31346
31371
|
}
|
|
31347
31372
|
return built;
|
|
31348
31373
|
}
|
|
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
31374
|
function initAttrs(typeName, attrs) {
|
|
31359
31375
|
let result = Object.create(null);
|
|
31360
31376
|
if (attrs)
|
|
@@ -31526,11 +31542,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
31526
31542
|
throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`);
|
|
31527
31543
|
}
|
|
31528
31544
|
/**
|
|
31529
|
-
@internal
|
|
31545
|
+
@internal no longer useful, but called by old prosemirror-view versions
|
|
31530
31546
|
*/
|
|
31531
|
-
checkAttrs(attrs) {
|
|
31532
|
-
checkAttrs(this.attrs, attrs, "node", this.name);
|
|
31533
|
-
}
|
|
31547
|
+
checkAttrs(attrs) { }
|
|
31534
31548
|
/**
|
|
31535
31549
|
Check whether the given mark type is allowed in this node.
|
|
31536
31550
|
*/
|
|
@@ -31677,12 +31691,6 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
31677
31691
|
return set[i];
|
|
31678
31692
|
}
|
|
31679
31693
|
/**
|
|
31680
|
-
@internal
|
|
31681
|
-
*/
|
|
31682
|
-
checkAttrs(attrs) {
|
|
31683
|
-
checkAttrs(this.attrs, attrs, "mark", this.name);
|
|
31684
|
-
}
|
|
31685
|
-
/**
|
|
31686
31694
|
Queries whether a given mark type is
|
|
31687
31695
|
[excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one.
|
|
31688
31696
|
*/
|
|
@@ -32873,9 +32881,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
32873
32881
|
if (simple)
|
|
32874
32882
|
return result;
|
|
32875
32883
|
let recover = pos == (assoc < 0 ? start : end) ? null : makeRecover(i / 3, pos - start);
|
|
32876
|
-
let del =
|
|
32877
|
-
if (
|
|
32878
|
-
del |=
|
|
32884
|
+
let del = 0;
|
|
32885
|
+
if (oldSize) {
|
|
32886
|
+
del |= pos == start ? DEL_AFTER : pos == end ? DEL_BEFORE : DEL_ACROSS;
|
|
32887
|
+
if (assoc < 0 ? pos != start : pos != end)
|
|
32888
|
+
del |= DEL_SIDE;
|
|
32889
|
+
}
|
|
32879
32890
|
return new MapResult(result, del, recover);
|
|
32880
32891
|
}
|
|
32881
32892
|
diff += newSize - oldSize;
|
|
@@ -36813,15 +36824,15 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36813
36824
|
return true;
|
|
36814
36825
|
if (off == (dir < 0 ? 0 : nodeSize(node))) {
|
|
36815
36826
|
let parent = node.parentNode;
|
|
36816
|
-
if (!parent || parent
|
|
36827
|
+
if (!parent || !isElt(parent) || hasBlockDesc(node) || atomElements.test(node.nodeName) ||
|
|
36817
36828
|
node.contentEditable == "false")
|
|
36818
36829
|
return false;
|
|
36819
36830
|
off = domIndex(node) + (dir < 0 ? 0 : 1);
|
|
36820
36831
|
node = parent;
|
|
36821
36832
|
}
|
|
36822
|
-
else if (node
|
|
36833
|
+
else if (isElt(node)) {
|
|
36823
36834
|
let child = node.childNodes[off + (dir < 0 ? -1 : 0)];
|
|
36824
|
-
if (child
|
|
36835
|
+
if (isElt(child) && child.contentEditable == "false") {
|
|
36825
36836
|
if ((_a = child.pmViewDesc) === null || _a === void 0 ? void 0 : _a.ignoreForSelection)
|
|
36826
36837
|
off += dir;
|
|
36827
36838
|
else
|
|
@@ -36840,11 +36851,16 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36840
36851
|
function nodeSize(node) {
|
|
36841
36852
|
return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
|
|
36842
36853
|
}
|
|
36854
|
+
function isElt(node) { return node.nodeType == 1; }
|
|
36855
|
+
function isText(node) { return node.nodeType == 3; }
|
|
36856
|
+
function contains(parent, child) {
|
|
36857
|
+
return child ? parent.contains(isElt(child) ? child : child.parentNode) : false;
|
|
36858
|
+
}
|
|
36843
36859
|
function textNodeBefore$1(node, offset) {
|
|
36844
36860
|
for (;;) {
|
|
36845
|
-
if (node
|
|
36861
|
+
if (isText(node) && offset)
|
|
36846
36862
|
return node;
|
|
36847
|
-
if (node
|
|
36863
|
+
if (isElt(node) && offset > 0) {
|
|
36848
36864
|
if (node.contentEditable == "false")
|
|
36849
36865
|
return null;
|
|
36850
36866
|
node = node.childNodes[offset - 1];
|
|
@@ -36861,9 +36877,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36861
36877
|
}
|
|
36862
36878
|
function textNodeAfter$1(node, offset) {
|
|
36863
36879
|
for (;;) {
|
|
36864
|
-
if (node
|
|
36880
|
+
if (isText(node) && offset < node.nodeValue.length)
|
|
36865
36881
|
return node;
|
|
36866
|
-
if (node
|
|
36882
|
+
if (isElt(node) && offset < node.childNodes.length) {
|
|
36867
36883
|
if (node.contentEditable == "false")
|
|
36868
36884
|
return null;
|
|
36869
36885
|
node = node.childNodes[offset];
|
|
@@ -36987,13 +37003,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
36987
37003
|
for (let parent = startDOM || view.dom;;) {
|
|
36988
37004
|
if (!parent)
|
|
36989
37005
|
break;
|
|
36990
|
-
if (parent
|
|
37006
|
+
if (!isElt(parent)) {
|
|
36991
37007
|
parent = parentNode(parent);
|
|
36992
37008
|
continue;
|
|
36993
37009
|
}
|
|
36994
|
-
let
|
|
36995
|
-
let
|
|
36996
|
-
let bounding = atTop ? windowRect(doc) : clientRect(elt);
|
|
37010
|
+
let atTop = parent == doc.body;
|
|
37011
|
+
let bounding = atTop ? windowRect(doc) : clientRect(parent);
|
|
36997
37012
|
let moveX = 0, moveY = 0;
|
|
36998
37013
|
if (rect.top < bounding.top + getSide$1(scrollThreshold, "top"))
|
|
36999
37014
|
moveY = -(bounding.top - rect.top + getSide$1(scrollMargin, "top"));
|
|
@@ -37010,12 +37025,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37010
37025
|
doc.defaultView.scrollBy(moveX, moveY);
|
|
37011
37026
|
}
|
|
37012
37027
|
else {
|
|
37013
|
-
let startX =
|
|
37028
|
+
let startX = parent.scrollLeft, startY = parent.scrollTop;
|
|
37014
37029
|
if (moveY)
|
|
37015
|
-
|
|
37030
|
+
parent.scrollTop += moveY;
|
|
37016
37031
|
if (moveX)
|
|
37017
|
-
|
|
37018
|
-
let dX =
|
|
37032
|
+
parent.scrollLeft += moveX;
|
|
37033
|
+
let dX = parent.scrollLeft - startX, dY = parent.scrollTop - startY;
|
|
37019
37034
|
rect = { left: rect.left - dX, top: rect.top - dY, right: rect.right - dX, bottom: rect.bottom - dY };
|
|
37020
37035
|
}
|
|
37021
37036
|
}
|
|
@@ -37090,14 +37105,15 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37090
37105
|
}
|
|
37091
37106
|
}
|
|
37092
37107
|
function findOffsetInNode(node, coords) {
|
|
37093
|
-
let closest
|
|
37108
|
+
let closest;
|
|
37109
|
+
let dxClosest = 2e8, coordsClosest, offset = 0;
|
|
37094
37110
|
let rowBot = coords.top, rowTop = coords.top;
|
|
37095
37111
|
let firstBelow, coordsBelow;
|
|
37096
37112
|
for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {
|
|
37097
37113
|
let rects;
|
|
37098
|
-
if (child
|
|
37114
|
+
if (isElt(child))
|
|
37099
37115
|
rects = child.getClientRects();
|
|
37100
|
-
else if (child
|
|
37116
|
+
else if (isText(child))
|
|
37101
37117
|
rects = textRange(child).getClientRects();
|
|
37102
37118
|
else
|
|
37103
37119
|
continue;
|
|
@@ -37111,11 +37127,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37111
37127
|
if (dx < dxClosest) {
|
|
37112
37128
|
closest = child;
|
|
37113
37129
|
dxClosest = dx;
|
|
37114
|
-
coordsClosest = dx && closest
|
|
37130
|
+
coordsClosest = dx && isText(closest) ? {
|
|
37115
37131
|
left: rect.right < coords.left ? rect.right : rect.left,
|
|
37116
37132
|
top: coords.top
|
|
37117
37133
|
} : coords;
|
|
37118
|
-
if (child
|
|
37134
|
+
if (isElt(child) && dx)
|
|
37119
37135
|
offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);
|
|
37120
37136
|
continue;
|
|
37121
37137
|
}
|
|
@@ -37134,9 +37150,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37134
37150
|
coordsClosest = coordsBelow;
|
|
37135
37151
|
dxClosest = 0;
|
|
37136
37152
|
}
|
|
37137
|
-
if (closest && closest
|
|
37153
|
+
if (closest && isText(closest))
|
|
37138
37154
|
return findOffsetInText(closest, coordsClosest);
|
|
37139
|
-
if (!closest ||
|
|
37155
|
+
if (!closest || dxClosest)
|
|
37140
37156
|
return { node, offset };
|
|
37141
37157
|
return findOffsetInNode(closest, coordsClosest);
|
|
37142
37158
|
}
|
|
@@ -37169,7 +37185,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37169
37185
|
}
|
|
37170
37186
|
function posFromElement(view, elt, coords) {
|
|
37171
37187
|
let { node, offset } = findOffsetInNode(elt, coords), bias = -1;
|
|
37172
|
-
if (node
|
|
37188
|
+
if (isElt(node) && !node.firstChild) {
|
|
37173
37189
|
let rect = node.getBoundingClientRect();
|
|
37174
37190
|
bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1;
|
|
37175
37191
|
}
|
|
@@ -37189,7 +37205,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37189
37205
|
let desc = view.docView.nearestDesc(cur, true), rect;
|
|
37190
37206
|
if (!desc)
|
|
37191
37207
|
return null;
|
|
37192
|
-
if (desc.dom
|
|
37208
|
+
if (isElt(desc.dom) && (desc.node.isBlock && desc.parent || !desc.contentDOM) &&
|
|
37193
37209
|
// Ignore elements with zero-size bounding rectangles
|
|
37194
37210
|
((rect = desc.dom.getBoundingClientRect()).width || rect.height)) {
|
|
37195
37211
|
if (desc.node.isBlock && desc.parent && !/^T(R|BODY|HEAD|FOOT)$/.test(desc.dom.nodeName)) {
|
|
@@ -37216,7 +37232,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37216
37232
|
if (len && box.top < box.bottom) {
|
|
37217
37233
|
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
37234
|
let child = element.childNodes[i];
|
|
37219
|
-
if (child
|
|
37235
|
+
if (isElt(child)) {
|
|
37220
37236
|
let rects = child.getClientRects();
|
|
37221
37237
|
for (let j = 0; j < rects.length; j++) {
|
|
37222
37238
|
let rect = rects[j];
|
|
@@ -37239,7 +37255,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37239
37255
|
let elt = (view.root.elementFromPoint ? view.root : doc)
|
|
37240
37256
|
.elementFromPoint(coords.left, coords.top);
|
|
37241
37257
|
let pos;
|
|
37242
|
-
if (!elt || !view.dom.contains(elt
|
|
37258
|
+
if (!elt || !view.dom.contains(elt)) {
|
|
37243
37259
|
let box = view.dom.getBoundingClientRect();
|
|
37244
37260
|
if (!inRect(coords, box))
|
|
37245
37261
|
return null;
|
|
@@ -37255,7 +37271,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37255
37271
|
}
|
|
37256
37272
|
elt = targetKludge(elt, coords);
|
|
37257
37273
|
if (node) {
|
|
37258
|
-
if (gecko && node
|
|
37274
|
+
if (gecko && isElt(node)) {
|
|
37259
37275
|
// Firefox will sometimes return offsets into <input> nodes, which
|
|
37260
37276
|
// have no actual children, from caretPositionFromPoint (#953)
|
|
37261
37277
|
offset = Math.min(offset, node.childNodes.length);
|
|
@@ -37270,18 +37286,18 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37270
37286
|
}
|
|
37271
37287
|
let prev;
|
|
37272
37288
|
// When clicking above the right side of an uneditable node, Chrome will report a cursor position after that node.
|
|
37273
|
-
if (webkit && offset && node
|
|
37289
|
+
if (webkit && offset && isElt(node) && isElt(prev = node.childNodes[offset - 1]) &&
|
|
37274
37290
|
prev.contentEditable == "false" && prev.getBoundingClientRect().top >= coords.top)
|
|
37275
37291
|
offset--;
|
|
37276
37292
|
// Suspiciously specific kludge to work around caret*FromPoint
|
|
37277
37293
|
// never returning a position at the end of the document
|
|
37278
|
-
if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild
|
|
37294
|
+
if (node == view.dom && offset == node.childNodes.length - 1 && isElt(node.lastChild) &&
|
|
37279
37295
|
coords.top > node.lastChild.getBoundingClientRect().bottom)
|
|
37280
37296
|
pos = view.state.doc.content.size;
|
|
37281
37297
|
// Ignore positions directly after a BR, since caret*FromPoint
|
|
37282
37298
|
// 'round up' positions that would be more accurately placed
|
|
37283
37299
|
// before the BR node.
|
|
37284
|
-
else if (offset == 0 || node
|
|
37300
|
+
else if (offset == 0 || !isElt(node) || node.childNodes[offset - 1].nodeName != "BR")
|
|
37285
37301
|
pos = posFromCaret(view, node, offset, coords);
|
|
37286
37302
|
}
|
|
37287
37303
|
if (pos == null)
|
|
@@ -37307,7 +37323,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37307
37323
|
function coordsAtPos(view, pos, side) {
|
|
37308
37324
|
let { node, offset, atom } = view.docView.domFromPos(pos, side < 0 ? -1 : 1);
|
|
37309
37325
|
let supportEmptyRange = webkit || gecko;
|
|
37310
|
-
if (node
|
|
37326
|
+
if (isText(node)) {
|
|
37311
37327
|
// These browsers support querying empty text ranges. Prefer that in
|
|
37312
37328
|
// bidi context or when at the end of a node.
|
|
37313
37329
|
if (supportEmptyRange && (BIDI.test(node.nodeValue) || (side < 0 ? !offset : offset == node.nodeValue.length))) {
|
|
@@ -37349,12 +37365,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37349
37365
|
if (!$dom.parent.inlineContent) {
|
|
37350
37366
|
if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
|
|
37351
37367
|
let before = node.childNodes[offset - 1];
|
|
37352
|
-
if (before
|
|
37368
|
+
if (isElt(before))
|
|
37353
37369
|
return flattenH(before.getBoundingClientRect(), false);
|
|
37354
37370
|
}
|
|
37355
37371
|
if (atom == null && offset < nodeSize(node)) {
|
|
37356
37372
|
let after = node.childNodes[offset];
|
|
37357
|
-
if (after
|
|
37373
|
+
if (isElt(after))
|
|
37358
37374
|
return flattenH(after.getBoundingClientRect(), true);
|
|
37359
37375
|
}
|
|
37360
37376
|
return flattenH(node.getBoundingClientRect(), side >= 0);
|
|
@@ -37362,10 +37378,10 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37362
37378
|
// Inline, not in text node (this is not Bidi-safe)
|
|
37363
37379
|
if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
|
|
37364
37380
|
let before = node.childNodes[offset - 1];
|
|
37365
|
-
let target = before
|
|
37381
|
+
let target = isText(before) ? textRange(before, nodeSize(before) - (supportEmptyRange ? 0 : 1))
|
|
37366
37382
|
// BR nodes tend to only return the rectangle before them.
|
|
37367
37383
|
// Only use them if they are the last element in their parent
|
|
37368
|
-
: before
|
|
37384
|
+
: isElt(before) && (before.nodeName != "BR" || !before.nextSibling) ? before : null;
|
|
37369
37385
|
if (target)
|
|
37370
37386
|
return flattenV(singleRect(target, 1), false);
|
|
37371
37387
|
}
|
|
@@ -37373,13 +37389,13 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37373
37389
|
let after = node.childNodes[offset];
|
|
37374
37390
|
while (after.pmViewDesc && after.pmViewDesc.ignoreForCoords)
|
|
37375
37391
|
after = after.nextSibling;
|
|
37376
|
-
let target = !after ? null : after
|
|
37377
|
-
: after
|
|
37392
|
+
let target = !after ? null : isText(after) ? textRange(after, 0, (supportEmptyRange ? 0 : 1))
|
|
37393
|
+
: isElt(after) ? after : null;
|
|
37378
37394
|
if (target)
|
|
37379
37395
|
return flattenV(singleRect(target, -1), true);
|
|
37380
37396
|
}
|
|
37381
37397
|
// All else failed, just try to get a rectangle for the target node
|
|
37382
|
-
return flattenV(singleRect(node
|
|
37398
|
+
return flattenV(singleRect(isText(node) ? textRange(node) : node, -side), side >= 0);
|
|
37383
37399
|
}
|
|
37384
37400
|
function flattenV(rect, left) {
|
|
37385
37401
|
if (rect.width == 0)
|
|
@@ -37429,9 +37445,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37429
37445
|
let coords = coordsAtPos(view, $pos.pos, 1);
|
|
37430
37446
|
for (let child = dom.firstChild; child; child = child.nextSibling) {
|
|
37431
37447
|
let boxes;
|
|
37432
|
-
if (child
|
|
37448
|
+
if (isElt(child))
|
|
37433
37449
|
boxes = child.getClientRects();
|
|
37434
|
-
else if (child
|
|
37450
|
+
else if (isText(child))
|
|
37435
37451
|
boxes = textRange(child, 0, child.nodeValue.length).getClientRects();
|
|
37436
37452
|
else
|
|
37437
37453
|
continue;
|
|
@@ -37471,8 +37487,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37471
37487
|
sel.modify("move", dir, "character");
|
|
37472
37488
|
let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom;
|
|
37473
37489
|
let { focusNode: newNode, focusOffset: newOff } = view.domSelectionRange();
|
|
37474
|
-
let result = newNode && !
|
|
37475
|
-
(oldNode == newNode && oldOff == newOff);
|
|
37490
|
+
let result = newNode && !contains(parentDOM, newNode) || (oldNode == newNode && oldOff == newOff);
|
|
37476
37491
|
// Restore the previous selection
|
|
37477
37492
|
try {
|
|
37478
37493
|
sel.collapse(anchorNode, anchorOffset);
|
|
@@ -37580,7 +37595,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37580
37595
|
localPosFromDOM(dom, offset, bias) {
|
|
37581
37596
|
// If the DOM position is in the content, use the child desc after
|
|
37582
37597
|
// it to figure out a position.
|
|
37583
|
-
if (this.contentDOM && this.contentDOM
|
|
37598
|
+
if (this.contentDOM && contains(this.contentDOM, dom)) {
|
|
37584
37599
|
if (bias < 0) {
|
|
37585
37600
|
let domBefore, desc;
|
|
37586
37601
|
if (dom == this.contentDOM) {
|
|
@@ -37618,7 +37633,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37618
37633
|
atEnd = offset > domIndex(this.contentDOM);
|
|
37619
37634
|
}
|
|
37620
37635
|
else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
|
|
37621
|
-
atEnd = dom.compareDocumentPosition(this.contentDOM) &
|
|
37636
|
+
atEnd = !!(dom.compareDocumentPosition(this.contentDOM) & 4);
|
|
37622
37637
|
}
|
|
37623
37638
|
else if (this.dom.firstChild) {
|
|
37624
37639
|
if (offset == 0)
|
|
@@ -37648,7 +37663,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37648
37663
|
if (desc && (!onlyNodes || desc.node)) {
|
|
37649
37664
|
// If dom is outside of this desc's nodeDOM, don't count it.
|
|
37650
37665
|
if (first && (nodeDOM = desc.nodeDOM) &&
|
|
37651
|
-
!(nodeDOM
|
|
37666
|
+
!(isElt(nodeDOM) ? contains(nodeDOM, dom) : nodeDOM == dom))
|
|
37652
37667
|
first = false;
|
|
37653
37668
|
else
|
|
37654
37669
|
return desc;
|
|
@@ -37698,7 +37713,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37698
37713
|
let i = 0, offset = 0;
|
|
37699
37714
|
for (let curPos = 0; i < this.children.length; i++) {
|
|
37700
37715
|
let child = this.children[i], end = curPos + child.size;
|
|
37701
|
-
if (end > pos
|
|
37716
|
+
if (end > pos) {
|
|
37702
37717
|
offset = pos - curPos;
|
|
37703
37718
|
break;
|
|
37704
37719
|
}
|
|
@@ -37708,7 +37723,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37708
37723
|
if (offset)
|
|
37709
37724
|
return this.children[i].domFromPos(offset - this.children[i].border, side);
|
|
37710
37725
|
// Go back if there were any zero-length widgets with side >= 0 before this point
|
|
37711
|
-
for (
|
|
37726
|
+
for (; i > 0; i--) {
|
|
37727
|
+
let prev = this.children[i - 1];
|
|
37728
|
+
if (prev.size || !(prev instanceof BufferHackViewDesc || prev instanceof WidgetViewDesc && prev.side >= 0))
|
|
37729
|
+
break;
|
|
37730
|
+
}
|
|
37712
37731
|
// Scan towards the first useable node
|
|
37713
37732
|
if (side <= 0) {
|
|
37714
37733
|
let prev, enter = true;
|
|
@@ -37785,7 +37804,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37785
37804
|
}
|
|
37786
37805
|
domAfterPos(pos) {
|
|
37787
37806
|
let { node, offset } = this.domFromPos(pos, 0);
|
|
37788
|
-
if (node
|
|
37807
|
+
if (!isElt(node) || offset == node.childNodes.length)
|
|
37789
37808
|
throw new RangeError("No node after pos " + pos);
|
|
37790
37809
|
return node.childNodes[offset];
|
|
37791
37810
|
}
|
|
@@ -37814,7 +37833,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37814
37833
|
// reported position in such situations (#1092).
|
|
37815
37834
|
if ((gecko || safari) && anchor == head) {
|
|
37816
37835
|
let { node, offset } = anchorDOM;
|
|
37817
|
-
if (node
|
|
37836
|
+
if (isText(node)) {
|
|
37818
37837
|
brKludge = !!(offset && node.nodeValue[offset - 1] == "\n");
|
|
37819
37838
|
// Issue #1128
|
|
37820
37839
|
if (brKludge && offset == node.nodeValue.length) {
|
|
@@ -37837,7 +37856,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37837
37856
|
}
|
|
37838
37857
|
// Firefox can act strangely when the selection is in front of an
|
|
37839
37858
|
// 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
|
|
37859
|
+
if (gecko && selRange.focusNode && selRange.focusNode != headDOM.node && isElt(selRange.focusNode)) {
|
|
37841
37860
|
let after = selRange.focusNode.childNodes[selRange.focusOffset];
|
|
37842
37861
|
if (after && after.contentEditable == "false")
|
|
37843
37862
|
force = true;
|
|
@@ -37936,14 +37955,12 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
37936
37955
|
return self.parent.posBeforeChild(self);
|
|
37937
37956
|
});
|
|
37938
37957
|
if (!widget.type.spec.raw) {
|
|
37939
|
-
|
|
37940
|
-
|
|
37941
|
-
|
|
37942
|
-
|
|
37943
|
-
|
|
37944
|
-
|
|
37945
|
-
dom.contentEditable = "false";
|
|
37946
|
-
dom.classList.add("ProseMirror-widget");
|
|
37958
|
+
let elt = isElt(dom) ? dom : document.createElement("span");
|
|
37959
|
+
if (elt != dom)
|
|
37960
|
+
elt.appendChild(dom);
|
|
37961
|
+
if (!elt.hasAttribute("contenteditable"))
|
|
37962
|
+
elt.contentEditable = "false";
|
|
37963
|
+
elt.classList.add("ProseMirror-widget");
|
|
37947
37964
|
}
|
|
37948
37965
|
super(parent, [], dom, null);
|
|
37949
37966
|
this.widget = widget;
|
|
@@ -38079,7 +38096,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38079
38096
|
if (node.isText) {
|
|
38080
38097
|
if (!dom)
|
|
38081
38098
|
dom = document.createTextNode(node.text);
|
|
38082
|
-
else if (dom
|
|
38099
|
+
else if (!isText(dom))
|
|
38083
38100
|
throw new RangeError("Text must be rendered as a DOM text node");
|
|
38084
38101
|
}
|
|
38085
38102
|
else if (!dom) {
|
|
@@ -38131,7 +38148,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38131
38148
|
}
|
|
38132
38149
|
if (!rule.contentElement) {
|
|
38133
38150
|
let found = addedNodes &&
|
|
38134
|
-
addedNodes.find(n => n
|
|
38151
|
+
addedNodes.find(n => isElt(n) && addedNodes.indexOf(n.parentNode) < 0 && this.dom.contains(n));
|
|
38135
38152
|
if (found)
|
|
38136
38153
|
rule.contentElement = found;
|
|
38137
38154
|
else
|
|
@@ -38156,6 +38173,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38156
38173
|
let localComposition = composition && composition.pos > -1 ? composition : null;
|
|
38157
38174
|
let compositionInChild = composition && composition.pos < 0;
|
|
38158
38175
|
let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
|
|
38176
|
+
let addBuffers = this.node.inlineContent, atBufferPos = addBuffers && this.node.isBlock;
|
|
38159
38177
|
iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => {
|
|
38160
38178
|
if (widget.spec.marks)
|
|
38161
38179
|
updater.syncToMarks(widget.spec.marks, inline, view, i);
|
|
@@ -38167,6 +38185,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38167
38185
|
}, (child, outerDeco, innerDeco, i) => {
|
|
38168
38186
|
// Make sure the wrapping mark descs match the node's marks.
|
|
38169
38187
|
updater.syncToMarks(child.marks, inline, view, i);
|
|
38188
|
+
if (atBufferPos && child.isAtom && !child.isText)
|
|
38189
|
+
updater.addHackNode("IMG", updater.top);
|
|
38170
38190
|
// Try several strategies for drawing this node
|
|
38171
38191
|
let compIndex;
|
|
38172
38192
|
if (updater.findNodeMatch(child, outerDeco, innerDeco, i)) ;
|
|
@@ -38180,6 +38200,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38180
38200
|
updater.addNode(child, outerDeco, innerDeco, view, off);
|
|
38181
38201
|
}
|
|
38182
38202
|
off += child.nodeSize;
|
|
38203
|
+
if (addBuffers)
|
|
38204
|
+
atBufferPos = child.isAtom && !child.isText;
|
|
38183
38205
|
});
|
|
38184
38206
|
// Drop all remaining descs after the current position.
|
|
38185
38207
|
updater.syncToMarks([], inline, view, 0);
|
|
@@ -38258,7 +38280,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38258
38280
|
updateOuterDeco(outerDeco) {
|
|
38259
38281
|
if (sameOuterDeco(outerDeco, this.outerDeco))
|
|
38260
38282
|
return;
|
|
38261
|
-
let needsWrap = this.nodeDOM
|
|
38283
|
+
let needsWrap = !isElt(this.nodeDOM);
|
|
38262
38284
|
let oldDOM = this.dom;
|
|
38263
38285
|
this.dom = patchOuterDeco(this.dom, this.nodeDOM, computeOuterDeco(this.outerDeco, this.node, needsWrap), computeOuterDeco(outerDeco, this.node, needsWrap));
|
|
38264
38286
|
if (this.dom != oldDOM) {
|
|
@@ -38269,7 +38291,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38269
38291
|
}
|
|
38270
38292
|
// Mark this node as being the selected node.
|
|
38271
38293
|
selectNode() {
|
|
38272
|
-
if (this.nodeDOM
|
|
38294
|
+
if (isElt(this.nodeDOM)) {
|
|
38273
38295
|
this.nodeDOM.classList.add("ProseMirror-selectednode");
|
|
38274
38296
|
if (this.contentDOM || !this.node.type.spec.draggable)
|
|
38275
38297
|
this.nodeDOM.draggable = true;
|
|
@@ -38277,7 +38299,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38277
38299
|
}
|
|
38278
38300
|
// Remove selected node marking from this node.
|
|
38279
38301
|
deselectNode() {
|
|
38280
|
-
if (this.nodeDOM
|
|
38302
|
+
if (isElt(this.nodeDOM)) {
|
|
38281
38303
|
this.nodeDOM.classList.remove("ProseMirror-selectednode");
|
|
38282
38304
|
if (this.contentDOM || !this.node.type.spec.draggable)
|
|
38283
38305
|
this.nodeDOM.removeAttribute("draggable");
|
|
@@ -38348,9 +38370,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38348
38370
|
get domAtom() { return false; }
|
|
38349
38371
|
isText(text) { return this.node.text == text; }
|
|
38350
38372
|
}
|
|
38351
|
-
// A dummy desc used to tag
|
|
38373
|
+
// A dummy desc used to tag extra BR or IMG nodes created to work
|
|
38352
38374
|
// around contentEditable terribleness.
|
|
38353
|
-
class
|
|
38375
|
+
class BufferHackViewDesc extends ViewDesc {
|
|
38354
38376
|
parseRule() { return { ignore: true }; }
|
|
38355
38377
|
matchesHack(nodeName) { return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName; }
|
|
38356
38378
|
get domAtom() { return true; }
|
|
@@ -38523,7 +38545,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38523
38545
|
}
|
|
38524
38546
|
}
|
|
38525
38547
|
function applyOuterDeco(dom, deco, node) {
|
|
38526
|
-
return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom
|
|
38548
|
+
return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, !isElt(dom)));
|
|
38527
38549
|
}
|
|
38528
38550
|
function sameOuterDeco(a, b) {
|
|
38529
38551
|
if (a.length != b.length)
|
|
@@ -38786,7 +38808,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38786
38808
|
}
|
|
38787
38809
|
if (nodeName == "BR")
|
|
38788
38810
|
dom.className = "ProseMirror-trailingBreak";
|
|
38789
|
-
let hack = new
|
|
38811
|
+
let hack = new BufferHackViewDesc(this.top, [], dom, null);
|
|
38790
38812
|
if (parent != this.top)
|
|
38791
38813
|
parent.children.push(hack);
|
|
38792
38814
|
else
|
|
@@ -38795,7 +38817,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38795
38817
|
}
|
|
38796
38818
|
}
|
|
38797
38819
|
isLocked(node) {
|
|
38798
|
-
return this.lock && (node == this.lock || node
|
|
38820
|
+
return this.lock && (node == this.lock || isElt(node) && node.contains(this.lock.parentNode));
|
|
38799
38821
|
}
|
|
38800
38822
|
}
|
|
38801
38823
|
// Iterate from the end of the fragment and array of descs to find
|
|
@@ -38997,12 +39019,27 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
38997
39019
|
anchor = head;
|
|
38998
39020
|
while (nearestDesc && !nearestDesc.node)
|
|
38999
39021
|
nearestDesc = nearestDesc.parent;
|
|
39000
|
-
|
|
39001
|
-
|
|
39002
|
-
|
|
39022
|
+
if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) &&
|
|
39023
|
+
nearestDesc.parent &&
|
|
39024
|
+
!(nearestDesc.node.isInline && isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) {
|
|
39003
39025
|
let pos = nearestDesc.posBefore;
|
|
39004
39026
|
selection = new NodeSelection(head == pos ? $head : doc.resolve(pos));
|
|
39005
39027
|
}
|
|
39028
|
+
else if (gecko && origin == "key" && head > view.state.selection.to &&
|
|
39029
|
+
isElt(domSel.focusNode) && domSel.focusOffset == domSel.focusNode.childNodes.length &&
|
|
39030
|
+
nearestDesc && nearestDesc.posAtStart > view.state.selection.to) {
|
|
39031
|
+
// Firefox will jump across scrollable wrapper nodes on keyboard
|
|
39032
|
+
// cursor motion (#1594). This tries to detect this situation
|
|
39033
|
+
// and work around it.
|
|
39034
|
+
for (let scan = domSel.focusNode;; scan = scan.parentNode) {
|
|
39035
|
+
if (getComputedStyle(scan).overflow != "visible") {
|
|
39036
|
+
selection = Selection$2.findFrom(doc.resolve(nearestDesc.posAtStart), 1);
|
|
39037
|
+
break;
|
|
39038
|
+
}
|
|
39039
|
+
if (scan == nearestDesc.dom || scan.nextSibling || !scan.parentNode || !isElt(scan.parentNode))
|
|
39040
|
+
break;
|
|
39041
|
+
}
|
|
39042
|
+
}
|
|
39006
39043
|
}
|
|
39007
39044
|
else {
|
|
39008
39045
|
if (domSel instanceof view.dom.ownerDocument.defaultView.Selection && domSel.rangeCount > 1) {
|
|
@@ -39188,8 +39225,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39188
39225
|
// Firefox will raise 'permission denied' errors when accessing
|
|
39189
39226
|
// properties of `sel.anchorNode` when it's in a generated CSS
|
|
39190
39227
|
// element.
|
|
39191
|
-
return view.dom
|
|
39192
|
-
(view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode));
|
|
39228
|
+
return contains(view.dom, sel.anchorNode) && (view.editable || contains(view.dom, sel.focusNode));
|
|
39193
39229
|
}
|
|
39194
39230
|
catch (_) {
|
|
39195
39231
|
return false;
|
|
@@ -39240,15 +39276,14 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39240
39276
|
if (NodeSelection.isSelectable(node)) {
|
|
39241
39277
|
return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head));
|
|
39242
39278
|
}
|
|
39243
|
-
else
|
|
39279
|
+
else {
|
|
39244
39280
|
// Chrome and Safari will introduce extra pointless cursor
|
|
39245
|
-
// positions around inline uneditable nodes,
|
|
39246
|
-
//
|
|
39281
|
+
// positions around inline uneditable nodes (#937), and
|
|
39282
|
+
// Firefox will sometimes just plain refuse to move across
|
|
39283
|
+
// them (#1592), so in this situation we move the cursor
|
|
39284
|
+
// ourselves.
|
|
39247
39285
|
return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize)));
|
|
39248
39286
|
}
|
|
39249
|
-
else {
|
|
39250
|
-
return false;
|
|
39251
|
-
}
|
|
39252
39287
|
}
|
|
39253
39288
|
}
|
|
39254
39289
|
else if (sel instanceof NodeSelection && sel.node.isInline) {
|
|
@@ -39261,12 +39296,10 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39261
39296
|
return false;
|
|
39262
39297
|
}
|
|
39263
39298
|
}
|
|
39264
|
-
function nodeLen(node) {
|
|
39265
|
-
return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
|
|
39266
|
-
}
|
|
39267
39299
|
function isIgnorable(dom, dir) {
|
|
39268
39300
|
let desc = dom.pmViewDesc;
|
|
39269
|
-
return desc
|
|
39301
|
+
return desc ? desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR")
|
|
39302
|
+
: isElt(dom) && dom.contentEditable == "false";
|
|
39270
39303
|
}
|
|
39271
39304
|
function skipIgnoredNodes(view, dir) {
|
|
39272
39305
|
return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view);
|
|
@@ -39282,25 +39315,23 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39282
39315
|
// Gecko will do odd things when the selection is directly in front
|
|
39283
39316
|
// of a non-editable node, so in that case, move it into the next
|
|
39284
39317
|
// node if possible. Issue prosemirror/prosemirror#832.
|
|
39285
|
-
if (gecko && node
|
|
39318
|
+
if (gecko && isElt(node) && offset < nodeSize(node) && isIgnorable(node.childNodes[offset], -1))
|
|
39286
39319
|
force = true;
|
|
39287
39320
|
for (;;) {
|
|
39288
39321
|
if (offset > 0) {
|
|
39289
|
-
if (node
|
|
39322
|
+
if (!isElt(node))
|
|
39290
39323
|
break;
|
|
39324
|
+
let before = node.childNodes[offset - 1];
|
|
39325
|
+
if (isIgnorable(before, -1)) {
|
|
39326
|
+
moveNode = node;
|
|
39327
|
+
moveOffset = --offset;
|
|
39328
|
+
}
|
|
39329
|
+
else if (isText(before)) {
|
|
39330
|
+
node = before;
|
|
39331
|
+
offset = node.nodeValue.length;
|
|
39291
39332
|
}
|
|
39292
39333
|
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;
|
|
39334
|
+
break;
|
|
39304
39335
|
}
|
|
39305
39336
|
}
|
|
39306
39337
|
else if (isBlockNode(node)) {
|
|
@@ -39321,7 +39352,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39321
39352
|
}
|
|
39322
39353
|
else {
|
|
39323
39354
|
node = prev;
|
|
39324
|
-
offset =
|
|
39355
|
+
offset = nodeSize(node);
|
|
39325
39356
|
}
|
|
39326
39357
|
}
|
|
39327
39358
|
}
|
|
@@ -39337,19 +39368,20 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39337
39368
|
let node = sel.focusNode, offset = sel.focusOffset;
|
|
39338
39369
|
if (!node)
|
|
39339
39370
|
return;
|
|
39340
|
-
let len =
|
|
39371
|
+
let len = nodeSize(node);
|
|
39341
39372
|
let moveNode, moveOffset;
|
|
39342
39373
|
for (;;) {
|
|
39343
39374
|
if (offset < len) {
|
|
39344
|
-
if (node
|
|
39375
|
+
if (!isElt(node))
|
|
39345
39376
|
break;
|
|
39346
39377
|
let after = node.childNodes[offset];
|
|
39347
39378
|
if (isIgnorable(after, 1)) {
|
|
39348
39379
|
moveNode = node;
|
|
39349
39380
|
moveOffset = ++offset;
|
|
39350
39381
|
}
|
|
39351
|
-
else
|
|
39382
|
+
else {
|
|
39352
39383
|
break;
|
|
39384
|
+
}
|
|
39353
39385
|
}
|
|
39354
39386
|
else if (isBlockNode(node)) {
|
|
39355
39387
|
break;
|
|
@@ -39370,7 +39402,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39370
39402
|
else {
|
|
39371
39403
|
node = next;
|
|
39372
39404
|
offset = 0;
|
|
39373
|
-
len =
|
|
39405
|
+
len = nodeSize(node);
|
|
39374
39406
|
}
|
|
39375
39407
|
}
|
|
39376
39408
|
}
|
|
@@ -39388,9 +39420,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39388
39420
|
}
|
|
39389
39421
|
while (node && offset < node.childNodes.length) {
|
|
39390
39422
|
let next = node.childNodes[offset];
|
|
39391
|
-
if (next
|
|
39423
|
+
if (isText(next))
|
|
39392
39424
|
return next;
|
|
39393
|
-
if (next
|
|
39425
|
+
if (isElt(next) && next.contentEditable == "false")
|
|
39394
39426
|
break;
|
|
39395
39427
|
node = next;
|
|
39396
39428
|
offset = 0;
|
|
@@ -39403,16 +39435,16 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39403
39435
|
}
|
|
39404
39436
|
while (node && offset) {
|
|
39405
39437
|
let next = node.childNodes[offset - 1];
|
|
39406
|
-
if (next
|
|
39438
|
+
if (isText(next))
|
|
39407
39439
|
return next;
|
|
39408
|
-
if (next
|
|
39440
|
+
if (isElt(next) && next.contentEditable == "false")
|
|
39409
39441
|
break;
|
|
39410
39442
|
node = next;
|
|
39411
39443
|
offset = node.childNodes.length;
|
|
39412
39444
|
}
|
|
39413
39445
|
}
|
|
39414
39446
|
function setSelFocus(view, node, offset) {
|
|
39415
|
-
if (node
|
|
39447
|
+
if (!isText(node)) {
|
|
39416
39448
|
let before, after;
|
|
39417
39449
|
if (after = textNodeAfter(node, offset)) {
|
|
39418
39450
|
node = after;
|
|
@@ -39522,8 +39554,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39522
39554
|
if (!safari || view.state.selection.$head.parentOffset > 0)
|
|
39523
39555
|
return false;
|
|
39524
39556
|
let { focusNode, focusOffset } = view.domSelectionRange();
|
|
39525
|
-
if (focusNode && focusNode
|
|
39526
|
-
focusNode.firstChild && focusNode.firstChild.contentEditable == "false") {
|
|
39557
|
+
if (focusNode && isElt(focusNode) && focusOffset == 0 &&
|
|
39558
|
+
focusNode.firstChild && isElt(focusNode.firstChild) && focusNode.firstChild.contentEditable == "false") {
|
|
39527
39559
|
let child = focusNode.firstChild;
|
|
39528
39560
|
switchEditable(view, child, "true");
|
|
39529
39561
|
setTimeout(() => switchEditable(view, child, "false"), 20);
|
|
@@ -39594,7 +39626,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39594
39626
|
let doc = detachedDoc(), wrap = doc.createElement("div");
|
|
39595
39627
|
wrap.appendChild(serializer.serializeFragment(content, { document: doc }));
|
|
39596
39628
|
let firstChild = wrap.firstChild, needsWrap, wrappers = 0;
|
|
39597
|
-
while (firstChild && firstChild
|
|
39629
|
+
while (firstChild && isElt(firstChild) && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) {
|
|
39598
39630
|
for (let i = needsWrap.length - 1; i >= 0; i--) {
|
|
39599
39631
|
let wrapper = doc.createElement(needsWrap[i]);
|
|
39600
39632
|
while (wrap.firstChild)
|
|
@@ -39604,7 +39636,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39604
39636
|
}
|
|
39605
39637
|
firstChild = wrap.firstChild;
|
|
39606
39638
|
}
|
|
39607
|
-
if (firstChild && firstChild
|
|
39639
|
+
if (firstChild && isElt(firstChild))
|
|
39608
39640
|
firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`);
|
|
39609
39641
|
let text = view.someProp("clipboardTextSerializer", f => f(slice, view)) ||
|
|
39610
39642
|
slice.content.textBetween(0, slice.content.size, "\n\n");
|
|
@@ -39650,7 +39682,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39650
39682
|
if (sliceData && sliceData[3])
|
|
39651
39683
|
for (let i = +sliceData[3]; i > 0; i--) {
|
|
39652
39684
|
let child = dom.firstChild;
|
|
39653
|
-
while (child && child
|
|
39685
|
+
while (child && !isElt(child))
|
|
39654
39686
|
child = child.nextSibling;
|
|
39655
39687
|
if (!child)
|
|
39656
39688
|
break;
|
|
@@ -39855,12 +39887,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
39855
39887
|
if (!type || type.hasRequiredAttrs())
|
|
39856
39888
|
break;
|
|
39857
39889
|
try {
|
|
39858
|
-
type.
|
|
39890
|
+
content = Fragment.from(type.create(array[i + 1], content));
|
|
39859
39891
|
}
|
|
39860
39892
|
catch (e) {
|
|
39861
39893
|
break;
|
|
39862
39894
|
}
|
|
39863
|
-
content = Fragment.from(type.create(array[i + 1], content));
|
|
39864
39895
|
openStart++;
|
|
39865
39896
|
openEnd++;
|
|
39866
39897
|
}
|
|
@@ -40192,7 +40223,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40192
40223
|
}
|
|
40193
40224
|
const target = flushed ? null : event.target;
|
|
40194
40225
|
const targetDesc = target ? view.docView.nearestDesc(target, true) : null;
|
|
40195
|
-
this.target = targetDesc && targetDesc.nodeDOM
|
|
40226
|
+
this.target = targetDesc && isElt(targetDesc.nodeDOM) ? targetDesc.nodeDOM : null;
|
|
40196
40227
|
let { selection } = view.state;
|
|
40197
40228
|
if (event.button == 0 &&
|
|
40198
40229
|
(targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
|
|
@@ -40340,7 +40371,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40340
40371
|
if (!view.composing) {
|
|
40341
40372
|
view.domObserver.flush();
|
|
40342
40373
|
let { state } = view, $pos = state.selection.$to;
|
|
40343
|
-
if (state.selection instanceof TextSelection &&
|
|
40374
|
+
if (state.selection instanceof TextSelection && state.selection.empty &&
|
|
40344
40375
|
(state.storedMarks ||
|
|
40345
40376
|
(!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)) ||
|
|
40346
40377
|
chrome && windows$1 && selectionBeforeUneditable(view))) { // Issue #1500
|
|
@@ -40356,11 +40387,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40356
40387
|
// inside if necessary.
|
|
40357
40388
|
if (gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) {
|
|
40358
40389
|
let sel = view.domSelectionRange();
|
|
40359
|
-
for (let node = sel.focusNode, offset = sel.focusOffset; node && node
|
|
40390
|
+
for (let node = sel.focusNode, offset = sel.focusOffset; node && isElt(node) && offset != 0;) {
|
|
40360
40391
|
let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1];
|
|
40361
40392
|
if (!before)
|
|
40362
40393
|
break;
|
|
40363
|
-
if (before
|
|
40394
|
+
if (isText(before)) {
|
|
40364
40395
|
let sel = view.domSelection();
|
|
40365
40396
|
if (sel)
|
|
40366
40397
|
sel.collapse(before, before.nodeValue.length);
|
|
@@ -40379,10 +40410,10 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40379
40410
|
};
|
|
40380
40411
|
function selectionBeforeUneditable(view) {
|
|
40381
40412
|
let { focusNode, focusOffset } = view.domSelectionRange();
|
|
40382
|
-
if (!focusNode || focusNode
|
|
40413
|
+
if (!focusNode || !isElt(focusNode) || focusOffset >= focusNode.childNodes.length)
|
|
40383
40414
|
return false;
|
|
40384
40415
|
let next = focusNode.childNodes[focusOffset];
|
|
40385
|
-
return next
|
|
40416
|
+
return isElt(next) && next.contentEditable == "false";
|
|
40386
40417
|
}
|
|
40387
40418
|
editHandlers.compositionend = (view, event) => {
|
|
40388
40419
|
if (view.composing) {
|
|
@@ -40584,7 +40615,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
40584
40615
|
else if (mouseDown && mouseDown.mightDrag) {
|
|
40585
40616
|
node = NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos);
|
|
40586
40617
|
}
|
|
40587
|
-
else if (event.target && event.target
|
|
40618
|
+
else if (event.target && isElt(event.target)) {
|
|
40588
40619
|
let desc = view.docView.nearestDesc(event.target, true);
|
|
40589
40620
|
if (desc && desc.node.type.spec.draggable && desc != view.docView)
|
|
40590
40621
|
node = NodeSelection.create(view.state.doc, desc.posBefore);
|
|
@@ -41555,7 +41586,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41555
41586
|
let desc = container && this.view.docView.nearestDesc(container);
|
|
41556
41587
|
if (desc && desc.ignoreMutation({
|
|
41557
41588
|
type: "selection",
|
|
41558
|
-
target: container
|
|
41589
|
+
target: isText(container) ? container.parentNode : container
|
|
41559
41590
|
})) {
|
|
41560
41591
|
this.setCurSelection();
|
|
41561
41592
|
return true;
|
|
@@ -41597,7 +41628,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41597
41628
|
for (let node of added)
|
|
41598
41629
|
if (node.nodeName == "BR" && node.parentNode) {
|
|
41599
41630
|
let after = node.nextSibling;
|
|
41600
|
-
while (after && after
|
|
41631
|
+
while (after && isElt(after)) {
|
|
41601
41632
|
if (after.contentEditable == "false") {
|
|
41602
41633
|
node.parentNode.removeChild(node);
|
|
41603
41634
|
break;
|
|
@@ -41670,7 +41701,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41670
41701
|
for (let i = 0; i < mut.addedNodes.length; i++) {
|
|
41671
41702
|
let node = mut.addedNodes[i];
|
|
41672
41703
|
added.push(node);
|
|
41673
|
-
if (node
|
|
41704
|
+
if (isText(node))
|
|
41674
41705
|
this.lastChangedTextNode = node;
|
|
41675
41706
|
}
|
|
41676
41707
|
if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target))
|
|
@@ -41785,8 +41816,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41785
41816
|
let parent = nextCell;
|
|
41786
41817
|
for (;;) {
|
|
41787
41818
|
let first = parent.firstChild;
|
|
41788
|
-
if (!first || first
|
|
41789
|
-
/^(BR|IMG)$/.test(first.nodeName))
|
|
41819
|
+
if (!first || !isElt(first) || first.contentEditable == "false" || /^(BR|IMG)$/.test(first.nodeName))
|
|
41790
41820
|
break;
|
|
41791
41821
|
parent = first;
|
|
41792
41822
|
}
|
|
@@ -41811,7 +41841,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41811
41841
|
let domSel = view.domSelectionRange();
|
|
41812
41842
|
let find;
|
|
41813
41843
|
let anchor = domSel.anchorNode;
|
|
41814
|
-
if (anchor && view.dom
|
|
41844
|
+
if (anchor && contains(view.dom, anchor)) {
|
|
41815
41845
|
find = [{ node: anchor, offset: domSel.anchorOffset }];
|
|
41816
41846
|
if (!selectionCollapsed(domSel))
|
|
41817
41847
|
find.push({ node: domSel.focusNode, offset: domSel.focusOffset });
|
|
@@ -41919,7 +41949,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41919
41949
|
if (change)
|
|
41920
41950
|
view.input.domChangeCount++;
|
|
41921
41951
|
if ((ios && view.input.lastIOSEnter > Date.now() - 225 || android) &&
|
|
41922
|
-
addedNodes.some(n => n
|
|
41952
|
+
addedNodes.some(n => isElt(n) && !isInline.test(n.nodeName)) &&
|
|
41923
41953
|
(!change || change.endA >= change.endB) &&
|
|
41924
41954
|
view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
|
|
41925
41955
|
view.input.lastIOSEnter = 0;
|
|
@@ -41977,9 +42007,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
41977
42007
|
// as being an iOS enter press), just dispatch an Enter key instead.
|
|
41978
42008
|
if (((ios && view.input.lastIOSEnter > Date.now() - 225 &&
|
|
41979
42009
|
(!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, "", "")))) &&
|
|
42010
|
+
(!inlineChange && looksLikeEnter(parse.doc, $from.pos, $to.pos))) &&
|
|
41983
42011
|
view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
|
|
41984
42012
|
view.input.lastIOSEnter = 0;
|
|
41985
42013
|
return;
|
|
@@ -42130,6 +42158,16 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42130
42158
|
// The fragments after the join point must match
|
|
42131
42159
|
return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content);
|
|
42132
42160
|
}
|
|
42161
|
+
function looksLikeEnter(content, from, to) {
|
|
42162
|
+
let newTextlines = 0, newLeaves = 0;
|
|
42163
|
+
content.nodesBetween(from, to, (node, pos) => {
|
|
42164
|
+
if (node.isTextblock && pos >= from && pos < to)
|
|
42165
|
+
newTextlines++;
|
|
42166
|
+
else if (node.isText ? /\S/.test(node.text.slice(Math.max(0, from - pos), Math.min(node.nodeSize, to - pos))) : node.isLeaf)
|
|
42167
|
+
newLeaves++;
|
|
42168
|
+
});
|
|
42169
|
+
return newLeaves == 0 && newTextlines == 1;
|
|
42170
|
+
}
|
|
42133
42171
|
function skipClosingAndOpening($pos, fromEnd, mayOpen) {
|
|
42134
42172
|
let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos;
|
|
42135
42173
|
while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) {
|
|
@@ -42390,11 +42428,11 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42390
42428
|
*/
|
|
42391
42429
|
scrollToSelection() {
|
|
42392
42430
|
let startDOM = this.domSelectionRange().focusNode;
|
|
42393
|
-
if (!startDOM || !this.dom
|
|
42431
|
+
if (!startDOM || !contains(this.dom, startDOM)) ;
|
|
42394
42432
|
else if (this.someProp("handleScrollToSelection", f => f(this))) ;
|
|
42395
42433
|
else if (this.state.selection instanceof NodeSelection) {
|
|
42396
42434
|
let target = this.docView.domAfterPos(this.state.selection.from);
|
|
42397
|
-
if (target
|
|
42435
|
+
if (isElt(target))
|
|
42398
42436
|
scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
|
|
42399
42437
|
}
|
|
42400
42438
|
else {
|
|
@@ -42659,7 +42697,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42659
42697
|
@internal
|
|
42660
42698
|
*/
|
|
42661
42699
|
domSelectionRange() {
|
|
42662
|
-
let sel = this.domSelection();
|
|
42700
|
+
let sel = this.dom.isConnected !== false && this.domSelection();
|
|
42663
42701
|
if (!sel)
|
|
42664
42702
|
return { focusNode: null, focusOffset: 0, anchorNode: null, anchorOffset: 0 };
|
|
42665
42703
|
return safari && this.root.nodeType === 11 &&
|
|
@@ -42990,382 +43028,1013 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
42990
43028
|
};
|
|
42991
43029
|
}
|
|
42992
43030
|
|
|
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;
|
|
43031
|
+
var GOOD_LEAF_SIZE = 200;
|
|
43032
|
+
|
|
43033
|
+
// :: class<T> A rope sequence is a persistent sequence data structure
|
|
43034
|
+
// that supports appending, prepending, and slicing without doing a
|
|
43035
|
+
// full copy. It is represented as a mostly-balanced tree.
|
|
43036
|
+
var RopeSequence = function RopeSequence () {};
|
|
43037
|
+
|
|
43038
|
+
RopeSequence.prototype.append = function append (other) {
|
|
43039
|
+
if (!other.length) { return this }
|
|
43040
|
+
other = RopeSequence.from(other);
|
|
43041
|
+
|
|
43042
|
+
return (!this.length && other) ||
|
|
43043
|
+
(other.length < GOOD_LEAF_SIZE && this.leafAppend(other)) ||
|
|
43044
|
+
(this.length < GOOD_LEAF_SIZE && other.leafPrepend(this)) ||
|
|
43045
|
+
this.appendInner(other)
|
|
43257
43046
|
};
|
|
43258
|
-
|
|
43259
|
-
|
|
43260
|
-
|
|
43261
|
-
|
|
43262
|
-
|
|
43263
|
-
|
|
43047
|
+
|
|
43048
|
+
// :: (union<[T], RopeSequence<T>>) → RopeSequence<T>
|
|
43049
|
+
// Prepend an array or other rope to this one, returning a new rope.
|
|
43050
|
+
RopeSequence.prototype.prepend = function prepend (other) {
|
|
43051
|
+
if (!other.length) { return this }
|
|
43052
|
+
return RopeSequence.from(other).append(this)
|
|
43264
43053
|
};
|
|
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);
|
|
43054
|
+
|
|
43055
|
+
RopeSequence.prototype.appendInner = function appendInner (other) {
|
|
43056
|
+
return new Append(this, other)
|
|
43274
43057
|
};
|
|
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;
|
|
43058
|
+
|
|
43059
|
+
// :: (?number, ?number) → RopeSequence<T>
|
|
43060
|
+
// Create a rope repesenting a sub-sequence of this rope.
|
|
43061
|
+
RopeSequence.prototype.slice = function slice (from, to) {
|
|
43062
|
+
if ( from === void 0 ) from = 0;
|
|
43063
|
+
if ( to === void 0 ) to = this.length;
|
|
43064
|
+
|
|
43065
|
+
if (from >= to) { return RopeSequence.empty }
|
|
43066
|
+
return this.sliceInner(Math.max(0, from), Math.min(this.length, to))
|
|
43290
43067
|
};
|
|
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
|
-
};
|
|
43068
|
+
|
|
43069
|
+
// :: (number) → T
|
|
43070
|
+
// Retrieve the element at the given position from this rope.
|
|
43071
|
+
RopeSequence.prototype.get = function get (i) {
|
|
43072
|
+
if (i < 0 || i >= this.length) { return undefined }
|
|
43073
|
+
return this.getInner(i)
|
|
43302
43074
|
};
|
|
43303
|
-
|
|
43304
|
-
|
|
43305
|
-
|
|
43306
|
-
|
|
43307
|
-
|
|
43308
|
-
|
|
43309
|
-
|
|
43310
|
-
|
|
43311
|
-
|
|
43312
|
-
|
|
43313
|
-
|
|
43314
|
-
|
|
43315
|
-
|
|
43316
|
-
|
|
43317
|
-
tr.scrollIntoView();
|
|
43318
|
-
dispatch(tr);
|
|
43319
|
-
}
|
|
43320
|
-
return true;
|
|
43075
|
+
|
|
43076
|
+
// :: ((element: T, index: number) → ?bool, ?number, ?number)
|
|
43077
|
+
// Call the given function for each element between the given
|
|
43078
|
+
// indices. This tends to be more efficient than looping over the
|
|
43079
|
+
// indices and calling `get`, because it doesn't have to descend the
|
|
43080
|
+
// tree for every element.
|
|
43081
|
+
RopeSequence.prototype.forEach = function forEach (f, from, to) {
|
|
43082
|
+
if ( from === void 0 ) from = 0;
|
|
43083
|
+
if ( to === void 0 ) to = this.length;
|
|
43084
|
+
|
|
43085
|
+
if (from <= to)
|
|
43086
|
+
{ this.forEachInner(f, from, to, 0); }
|
|
43087
|
+
else
|
|
43088
|
+
{ this.forEachInvertedInner(f, from, to, 0); }
|
|
43321
43089
|
};
|
|
43322
|
-
|
|
43323
|
-
|
|
43324
|
-
|
|
43325
|
-
|
|
43090
|
+
|
|
43091
|
+
// :: ((element: T, index: number) → U, ?number, ?number) → [U]
|
|
43092
|
+
// Map the given functions over the elements of the rope, producing
|
|
43093
|
+
// a flat array.
|
|
43094
|
+
RopeSequence.prototype.map = function map (f, from, to) {
|
|
43095
|
+
if ( from === void 0 ) from = 0;
|
|
43096
|
+
if ( to === void 0 ) to = this.length;
|
|
43097
|
+
|
|
43098
|
+
var result = [];
|
|
43099
|
+
this.forEach(function (elt, i) { return result.push(f(elt, i)); }, from, to);
|
|
43100
|
+
return result
|
|
43326
43101
|
};
|
|
43327
|
-
|
|
43328
|
-
|
|
43329
|
-
|
|
43330
|
-
|
|
43102
|
+
|
|
43103
|
+
// :: (?union<[T], RopeSequence<T>>) → RopeSequence<T>
|
|
43104
|
+
// Create a rope representing the given array, or return the rope
|
|
43105
|
+
// itself if a rope was given.
|
|
43106
|
+
RopeSequence.from = function from (values) {
|
|
43107
|
+
if (values instanceof RopeSequence) { return values }
|
|
43108
|
+
return values && values.length ? new Leaf(values) : RopeSequence.empty
|
|
43331
43109
|
};
|
|
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
|
-
|
|
43110
|
+
|
|
43111
|
+
var Leaf = /*@__PURE__*/(function (RopeSequence) {
|
|
43112
|
+
function Leaf(values) {
|
|
43113
|
+
RopeSequence.call(this);
|
|
43114
|
+
this.values = values;
|
|
43115
|
+
}
|
|
43116
|
+
|
|
43117
|
+
if ( RopeSequence ) Leaf.__proto__ = RopeSequence;
|
|
43118
|
+
Leaf.prototype = Object.create( RopeSequence && RopeSequence.prototype );
|
|
43119
|
+
Leaf.prototype.constructor = Leaf;
|
|
43120
|
+
|
|
43121
|
+
var prototypeAccessors = { length: { configurable: true },depth: { configurable: true } };
|
|
43122
|
+
|
|
43123
|
+
Leaf.prototype.flatten = function flatten () {
|
|
43124
|
+
return this.values
|
|
43125
|
+
};
|
|
43126
|
+
|
|
43127
|
+
Leaf.prototype.sliceInner = function sliceInner (from, to) {
|
|
43128
|
+
if (from == 0 && to == this.length) { return this }
|
|
43129
|
+
return new Leaf(this.values.slice(from, to))
|
|
43130
|
+
};
|
|
43131
|
+
|
|
43132
|
+
Leaf.prototype.getInner = function getInner (i) {
|
|
43133
|
+
return this.values[i]
|
|
43134
|
+
};
|
|
43135
|
+
|
|
43136
|
+
Leaf.prototype.forEachInner = function forEachInner (f, from, to, start) {
|
|
43137
|
+
for (var i = from; i < to; i++)
|
|
43138
|
+
{ if (f(this.values[i], start + i) === false) { return false } }
|
|
43139
|
+
};
|
|
43140
|
+
|
|
43141
|
+
Leaf.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
|
|
43142
|
+
for (var i = from - 1; i >= to; i--)
|
|
43143
|
+
{ if (f(this.values[i], start + i) === false) { return false } }
|
|
43144
|
+
};
|
|
43145
|
+
|
|
43146
|
+
Leaf.prototype.leafAppend = function leafAppend (other) {
|
|
43147
|
+
if (this.length + other.length <= GOOD_LEAF_SIZE)
|
|
43148
|
+
{ return new Leaf(this.values.concat(other.flatten())) }
|
|
43149
|
+
};
|
|
43150
|
+
|
|
43151
|
+
Leaf.prototype.leafPrepend = function leafPrepend (other) {
|
|
43152
|
+
if (this.length + other.length <= GOOD_LEAF_SIZE)
|
|
43153
|
+
{ return new Leaf(other.flatten().concat(this.values)) }
|
|
43154
|
+
};
|
|
43155
|
+
|
|
43156
|
+
prototypeAccessors.length.get = function () { return this.values.length };
|
|
43157
|
+
|
|
43158
|
+
prototypeAccessors.depth.get = function () { return 0 };
|
|
43159
|
+
|
|
43160
|
+
Object.defineProperties( Leaf.prototype, prototypeAccessors );
|
|
43161
|
+
|
|
43162
|
+
return Leaf;
|
|
43163
|
+
}(RopeSequence));
|
|
43164
|
+
|
|
43165
|
+
// :: RopeSequence
|
|
43166
|
+
// The empty rope sequence.
|
|
43167
|
+
RopeSequence.empty = new Leaf([]);
|
|
43168
|
+
|
|
43169
|
+
var Append = /*@__PURE__*/(function (RopeSequence) {
|
|
43170
|
+
function Append(left, right) {
|
|
43171
|
+
RopeSequence.call(this);
|
|
43172
|
+
this.left = left;
|
|
43173
|
+
this.right = right;
|
|
43174
|
+
this.length = left.length + right.length;
|
|
43175
|
+
this.depth = Math.max(left.depth, right.depth) + 1;
|
|
43176
|
+
}
|
|
43177
|
+
|
|
43178
|
+
if ( RopeSequence ) Append.__proto__ = RopeSequence;
|
|
43179
|
+
Append.prototype = Object.create( RopeSequence && RopeSequence.prototype );
|
|
43180
|
+
Append.prototype.constructor = Append;
|
|
43181
|
+
|
|
43182
|
+
Append.prototype.flatten = function flatten () {
|
|
43183
|
+
return this.left.flatten().concat(this.right.flatten())
|
|
43184
|
+
};
|
|
43185
|
+
|
|
43186
|
+
Append.prototype.getInner = function getInner (i) {
|
|
43187
|
+
return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length)
|
|
43188
|
+
};
|
|
43189
|
+
|
|
43190
|
+
Append.prototype.forEachInner = function forEachInner (f, from, to, start) {
|
|
43191
|
+
var leftLen = this.left.length;
|
|
43192
|
+
if (from < leftLen &&
|
|
43193
|
+
this.left.forEachInner(f, from, Math.min(to, leftLen), start) === false)
|
|
43194
|
+
{ return false }
|
|
43195
|
+
if (to > leftLen &&
|
|
43196
|
+
this.right.forEachInner(f, Math.max(from - leftLen, 0), Math.min(this.length, to) - leftLen, start + leftLen) === false)
|
|
43197
|
+
{ return false }
|
|
43198
|
+
};
|
|
43199
|
+
|
|
43200
|
+
Append.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
|
|
43201
|
+
var leftLen = this.left.length;
|
|
43202
|
+
if (from > leftLen &&
|
|
43203
|
+
this.right.forEachInvertedInner(f, from - leftLen, Math.max(to, leftLen) - leftLen, start + leftLen) === false)
|
|
43204
|
+
{ return false }
|
|
43205
|
+
if (to < leftLen &&
|
|
43206
|
+
this.left.forEachInvertedInner(f, Math.min(from, leftLen), to, start) === false)
|
|
43207
|
+
{ return false }
|
|
43208
|
+
};
|
|
43209
|
+
|
|
43210
|
+
Append.prototype.sliceInner = function sliceInner (from, to) {
|
|
43211
|
+
if (from == 0 && to == this.length) { return this }
|
|
43212
|
+
var leftLen = this.left.length;
|
|
43213
|
+
if (to <= leftLen) { return this.left.slice(from, to) }
|
|
43214
|
+
if (from >= leftLen) { return this.right.slice(from - leftLen, to - leftLen) }
|
|
43215
|
+
return this.left.slice(from, leftLen).append(this.right.slice(0, to - leftLen))
|
|
43216
|
+
};
|
|
43217
|
+
|
|
43218
|
+
Append.prototype.leafAppend = function leafAppend (other) {
|
|
43219
|
+
var inner = this.right.leafAppend(other);
|
|
43220
|
+
if (inner) { return new Append(this.left, inner) }
|
|
43221
|
+
};
|
|
43222
|
+
|
|
43223
|
+
Append.prototype.leafPrepend = function leafPrepend (other) {
|
|
43224
|
+
var inner = this.left.leafPrepend(other);
|
|
43225
|
+
if (inner) { return new Append(inner, this.right) }
|
|
43226
|
+
};
|
|
43227
|
+
|
|
43228
|
+
Append.prototype.appendInner = function appendInner (other) {
|
|
43229
|
+
if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1)
|
|
43230
|
+
{ return new Append(this.left, new Append(this.right, other)) }
|
|
43231
|
+
return new Append(this, other)
|
|
43232
|
+
};
|
|
43233
|
+
|
|
43234
|
+
return Append;
|
|
43235
|
+
}(RopeSequence));
|
|
43236
|
+
|
|
43237
|
+
// ProseMirror's history isn't simply a way to roll back to a previous
|
|
43238
|
+
// state, because ProseMirror supports applying changes without adding
|
|
43239
|
+
// them to the history (for example during collaboration).
|
|
43240
|
+
//
|
|
43241
|
+
// To this end, each 'Branch' (one for the undo history and one for
|
|
43242
|
+
// the redo history) keeps an array of 'Items', which can optionally
|
|
43243
|
+
// hold a step (an actual undoable change), and always hold a position
|
|
43244
|
+
// map (which is needed to move changes below them to apply to the
|
|
43245
|
+
// current document).
|
|
43246
|
+
//
|
|
43247
|
+
// An item that has both a step and a selection bookmark is the start
|
|
43248
|
+
// of an 'event' — a group of changes that will be undone or redone at
|
|
43249
|
+
// once. (It stores only the bookmark, since that way we don't have to
|
|
43250
|
+
// provide a document until the selection is actually applied, which
|
|
43251
|
+
// is useful when compressing.)
|
|
43252
|
+
// Used to schedule history compression
|
|
43253
|
+
const max_empty_items = 500;
|
|
43254
|
+
class Branch {
|
|
43255
|
+
constructor(items, eventCount) {
|
|
43256
|
+
this.items = items;
|
|
43257
|
+
this.eventCount = eventCount;
|
|
43258
|
+
}
|
|
43259
|
+
// Pop the latest event off the branch's history and apply it
|
|
43260
|
+
// to a document transform.
|
|
43261
|
+
popEvent(state, preserveItems) {
|
|
43262
|
+
if (this.eventCount == 0)
|
|
43263
|
+
return null;
|
|
43264
|
+
let end = this.items.length;
|
|
43265
|
+
for (;; end--) {
|
|
43266
|
+
let next = this.items.get(end - 1);
|
|
43267
|
+
if (next.selection) {
|
|
43268
|
+
--end;
|
|
43269
|
+
break;
|
|
43270
|
+
}
|
|
43271
|
+
}
|
|
43272
|
+
let remap, mapFrom;
|
|
43273
|
+
if (preserveItems) {
|
|
43274
|
+
remap = this.remapping(end, this.items.length);
|
|
43275
|
+
mapFrom = remap.maps.length;
|
|
43276
|
+
}
|
|
43277
|
+
let transform = state.tr;
|
|
43278
|
+
let selection, remaining;
|
|
43279
|
+
let addAfter = [], addBefore = [];
|
|
43280
|
+
this.items.forEach((item, i) => {
|
|
43281
|
+
if (!item.step) {
|
|
43282
|
+
if (!remap) {
|
|
43283
|
+
remap = this.remapping(end, i + 1);
|
|
43284
|
+
mapFrom = remap.maps.length;
|
|
43285
|
+
}
|
|
43286
|
+
mapFrom--;
|
|
43287
|
+
addBefore.push(item);
|
|
43288
|
+
return;
|
|
43289
|
+
}
|
|
43290
|
+
if (remap) {
|
|
43291
|
+
addBefore.push(new Item(item.map));
|
|
43292
|
+
let step = item.step.map(remap.slice(mapFrom)), map;
|
|
43293
|
+
if (step && transform.maybeStep(step).doc) {
|
|
43294
|
+
map = transform.mapping.maps[transform.mapping.maps.length - 1];
|
|
43295
|
+
addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length));
|
|
43296
|
+
}
|
|
43297
|
+
mapFrom--;
|
|
43298
|
+
if (map)
|
|
43299
|
+
remap.appendMap(map, mapFrom);
|
|
43300
|
+
}
|
|
43301
|
+
else {
|
|
43302
|
+
transform.maybeStep(item.step);
|
|
43303
|
+
}
|
|
43304
|
+
if (item.selection) {
|
|
43305
|
+
selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;
|
|
43306
|
+
remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1);
|
|
43307
|
+
return false;
|
|
43308
|
+
}
|
|
43309
|
+
}, this.items.length, 0);
|
|
43310
|
+
return { remaining: remaining, transform, selection: selection };
|
|
43311
|
+
}
|
|
43312
|
+
// Create a new branch with the given transform added.
|
|
43313
|
+
addTransform(transform, selection, histOptions, preserveItems) {
|
|
43314
|
+
let newItems = [], eventCount = this.eventCount;
|
|
43315
|
+
let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
|
|
43316
|
+
for (let i = 0; i < transform.steps.length; i++) {
|
|
43317
|
+
let step = transform.steps[i].invert(transform.docs[i]);
|
|
43318
|
+
let item = new Item(transform.mapping.maps[i], step, selection), merged;
|
|
43319
|
+
if (merged = lastItem && lastItem.merge(item)) {
|
|
43320
|
+
item = merged;
|
|
43321
|
+
if (i)
|
|
43322
|
+
newItems.pop();
|
|
43323
|
+
else
|
|
43324
|
+
oldItems = oldItems.slice(0, oldItems.length - 1);
|
|
43325
|
+
}
|
|
43326
|
+
newItems.push(item);
|
|
43327
|
+
if (selection) {
|
|
43328
|
+
eventCount++;
|
|
43329
|
+
selection = undefined;
|
|
43330
|
+
}
|
|
43331
|
+
if (!preserveItems)
|
|
43332
|
+
lastItem = item;
|
|
43333
|
+
}
|
|
43334
|
+
let overflow = eventCount - histOptions.depth;
|
|
43335
|
+
if (overflow > DEPTH_OVERFLOW) {
|
|
43336
|
+
oldItems = cutOffEvents(oldItems, overflow);
|
|
43337
|
+
eventCount -= overflow;
|
|
43338
|
+
}
|
|
43339
|
+
return new Branch(oldItems.append(newItems), eventCount);
|
|
43340
|
+
}
|
|
43341
|
+
remapping(from, to) {
|
|
43342
|
+
let maps = new Mapping;
|
|
43343
|
+
this.items.forEach((item, i) => {
|
|
43344
|
+
let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from
|
|
43345
|
+
? maps.maps.length - item.mirrorOffset : undefined;
|
|
43346
|
+
maps.appendMap(item.map, mirrorPos);
|
|
43347
|
+
}, from, to);
|
|
43348
|
+
return maps;
|
|
43349
|
+
}
|
|
43350
|
+
addMaps(array) {
|
|
43351
|
+
if (this.eventCount == 0)
|
|
43352
|
+
return this;
|
|
43353
|
+
return new Branch(this.items.append(array.map(map => new Item(map))), this.eventCount);
|
|
43354
|
+
}
|
|
43355
|
+
// When the collab module receives remote changes, the history has
|
|
43356
|
+
// to know about those, so that it can adjust the steps that were
|
|
43357
|
+
// rebased on top of the remote changes, and include the position
|
|
43358
|
+
// maps for the remote changes in its array of items.
|
|
43359
|
+
rebased(rebasedTransform, rebasedCount) {
|
|
43360
|
+
if (!this.eventCount)
|
|
43361
|
+
return this;
|
|
43362
|
+
rebasedCount = Math.min(this.items.length, rebasedCount);
|
|
43363
|
+
let rebasedItems = [], start = this.items.length - rebasedCount;
|
|
43364
|
+
let mapping = rebasedTransform.mapping;
|
|
43365
|
+
let newUntil = rebasedTransform.steps.length;
|
|
43366
|
+
let eventCount = this.eventCount;
|
|
43367
|
+
this.items.forEach(item => { if (item.selection)
|
|
43368
|
+
eventCount--; }, start);
|
|
43369
|
+
let iRebased = rebasedCount;
|
|
43370
|
+
this.items.forEach(item => {
|
|
43371
|
+
let pos = mapping.getMirror(--iRebased);
|
|
43372
|
+
if (pos == null)
|
|
43373
|
+
return;
|
|
43374
|
+
newUntil = Math.min(newUntil, pos);
|
|
43375
|
+
let map = mapping.maps[pos];
|
|
43376
|
+
if (item.step) {
|
|
43377
|
+
let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);
|
|
43378
|
+
let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
|
|
43379
|
+
if (selection)
|
|
43380
|
+
eventCount++;
|
|
43381
|
+
rebasedItems.push(new Item(map, step, selection));
|
|
43382
|
+
}
|
|
43383
|
+
else {
|
|
43384
|
+
rebasedItems.push(new Item(map));
|
|
43385
|
+
}
|
|
43386
|
+
}, start);
|
|
43387
|
+
let newMaps = [];
|
|
43388
|
+
for (let i = rebasedCount; i < newUntil; i++)
|
|
43389
|
+
newMaps.push(new Item(mapping.maps[i]));
|
|
43390
|
+
let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
|
|
43391
|
+
let branch = new Branch(items, eventCount);
|
|
43392
|
+
if (branch.emptyItemCount() > max_empty_items)
|
|
43393
|
+
branch = branch.compress(this.items.length - rebasedItems.length);
|
|
43394
|
+
return branch;
|
|
43395
|
+
}
|
|
43396
|
+
emptyItemCount() {
|
|
43397
|
+
let count = 0;
|
|
43398
|
+
this.items.forEach(item => { if (!item.step)
|
|
43399
|
+
count++; });
|
|
43400
|
+
return count;
|
|
43401
|
+
}
|
|
43402
|
+
// Compressing a branch means rewriting it to push the air (map-only
|
|
43403
|
+
// items) out. During collaboration, these naturally accumulate
|
|
43404
|
+
// because each remote change adds one. The `upto` argument is used
|
|
43405
|
+
// to ensure that only the items below a given level are compressed,
|
|
43406
|
+
// because `rebased` relies on a clean, untouched set of items in
|
|
43407
|
+
// order to associate old items with rebased steps.
|
|
43408
|
+
compress(upto = this.items.length) {
|
|
43409
|
+
let remap = this.remapping(0, upto), mapFrom = remap.maps.length;
|
|
43410
|
+
let items = [], events = 0;
|
|
43411
|
+
this.items.forEach((item, i) => {
|
|
43412
|
+
if (i >= upto) {
|
|
43413
|
+
items.push(item);
|
|
43414
|
+
if (item.selection)
|
|
43415
|
+
events++;
|
|
43416
|
+
}
|
|
43417
|
+
else if (item.step) {
|
|
43418
|
+
let step = item.step.map(remap.slice(mapFrom)), map = step && step.getMap();
|
|
43419
|
+
mapFrom--;
|
|
43420
|
+
if (map)
|
|
43421
|
+
remap.appendMap(map, mapFrom);
|
|
43422
|
+
if (step) {
|
|
43423
|
+
let selection = item.selection && item.selection.map(remap.slice(mapFrom));
|
|
43424
|
+
if (selection)
|
|
43425
|
+
events++;
|
|
43426
|
+
let newItem = new Item(map.invert(), step, selection), merged, last = items.length - 1;
|
|
43427
|
+
if (merged = items.length && items[last].merge(newItem))
|
|
43428
|
+
items[last] = merged;
|
|
43429
|
+
else
|
|
43430
|
+
items.push(newItem);
|
|
43431
|
+
}
|
|
43432
|
+
}
|
|
43433
|
+
else if (item.map) {
|
|
43434
|
+
mapFrom--;
|
|
43435
|
+
}
|
|
43436
|
+
}, this.items.length, 0);
|
|
43437
|
+
return new Branch(RopeSequence.from(items.reverse()), events);
|
|
43438
|
+
}
|
|
43439
|
+
}
|
|
43440
|
+
Branch.empty = new Branch(RopeSequence.empty, 0);
|
|
43441
|
+
function cutOffEvents(items, n) {
|
|
43442
|
+
let cutPoint;
|
|
43443
|
+
items.forEach((item, i) => {
|
|
43444
|
+
if (item.selection && (n-- == 0)) {
|
|
43445
|
+
cutPoint = i;
|
|
43446
|
+
return false;
|
|
43447
|
+
}
|
|
43448
|
+
});
|
|
43449
|
+
return items.slice(cutPoint);
|
|
43450
|
+
}
|
|
43451
|
+
class Item {
|
|
43452
|
+
constructor(
|
|
43453
|
+
// The (forward) step map for this item.
|
|
43454
|
+
map,
|
|
43455
|
+
// The inverted step
|
|
43456
|
+
step,
|
|
43457
|
+
// If this is non-null, this item is the start of a group, and
|
|
43458
|
+
// this selection is the starting selection for the group (the one
|
|
43459
|
+
// that was active before the first step was applied)
|
|
43460
|
+
selection,
|
|
43461
|
+
// If this item is the inverse of a previous mapping on the stack,
|
|
43462
|
+
// this points at the inverse's offset
|
|
43463
|
+
mirrorOffset) {
|
|
43464
|
+
this.map = map;
|
|
43465
|
+
this.step = step;
|
|
43466
|
+
this.selection = selection;
|
|
43467
|
+
this.mirrorOffset = mirrorOffset;
|
|
43468
|
+
}
|
|
43469
|
+
merge(other) {
|
|
43470
|
+
if (this.step && other.step && !other.selection) {
|
|
43471
|
+
let step = other.step.merge(this.step);
|
|
43472
|
+
if (step)
|
|
43473
|
+
return new Item(step.getMap().invert(), step, this.selection);
|
|
43474
|
+
}
|
|
43475
|
+
}
|
|
43476
|
+
}
|
|
43477
|
+
// The value of the state field that tracks undo/redo history for that
|
|
43478
|
+
// state. Will be stored in the plugin state when the history plugin
|
|
43479
|
+
// is active.
|
|
43480
|
+
class HistoryState {
|
|
43481
|
+
constructor(done, undone, prevRanges, prevTime, prevComposition) {
|
|
43482
|
+
this.done = done;
|
|
43483
|
+
this.undone = undone;
|
|
43484
|
+
this.prevRanges = prevRanges;
|
|
43485
|
+
this.prevTime = prevTime;
|
|
43486
|
+
this.prevComposition = prevComposition;
|
|
43487
|
+
}
|
|
43488
|
+
}
|
|
43489
|
+
const DEPTH_OVERFLOW = 20;
|
|
43490
|
+
// Record a transformation in undo history.
|
|
43491
|
+
function applyTransaction(history, state, tr, options) {
|
|
43492
|
+
let historyTr = tr.getMeta(historyKey), rebased;
|
|
43493
|
+
if (historyTr)
|
|
43494
|
+
return historyTr.historyState;
|
|
43495
|
+
if (tr.getMeta(closeHistoryKey))
|
|
43496
|
+
history = new HistoryState(history.done, history.undone, null, 0, -1);
|
|
43497
|
+
let appended = tr.getMeta("appendedTransaction");
|
|
43498
|
+
if (tr.steps.length == 0) {
|
|
43499
|
+
return history;
|
|
43500
|
+
}
|
|
43501
|
+
else if (appended && appended.getMeta(historyKey)) {
|
|
43502
|
+
if (appended.getMeta(historyKey).redo)
|
|
43503
|
+
return new HistoryState(history.done.addTransform(tr, undefined, options, mustPreserveItems(state)), history.undone, rangesFor(tr.mapping.maps), history.prevTime, history.prevComposition);
|
|
43504
|
+
else
|
|
43505
|
+
return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);
|
|
43506
|
+
}
|
|
43507
|
+
else if (tr.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) {
|
|
43508
|
+
// Group transforms that occur in quick succession into one event.
|
|
43509
|
+
let composition = tr.getMeta("composition");
|
|
43510
|
+
let newGroup = history.prevTime == 0 ||
|
|
43511
|
+
(!appended && history.prevComposition != composition &&
|
|
43512
|
+
(history.prevTime < (tr.time || 0) - options.newGroupDelay || !isAdjacentTo(tr, history.prevRanges)));
|
|
43513
|
+
let prevRanges = appended ? mapRanges(history.prevRanges, tr.mapping) : rangesFor(tr.mapping.maps);
|
|
43514
|
+
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);
|
|
43515
|
+
}
|
|
43516
|
+
else if (rebased = tr.getMeta("rebased")) {
|
|
43517
|
+
// Used by the collab module to tell the history that some of its
|
|
43518
|
+
// content has been rebased.
|
|
43519
|
+
return new HistoryState(history.done.rebased(tr, rebased), history.undone.rebased(tr, rebased), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
|
43520
|
+
}
|
|
43521
|
+
else {
|
|
43522
|
+
return new HistoryState(history.done.addMaps(tr.mapping.maps), history.undone.addMaps(tr.mapping.maps), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
|
43523
|
+
}
|
|
43524
|
+
}
|
|
43525
|
+
function isAdjacentTo(transform, prevRanges) {
|
|
43526
|
+
if (!prevRanges)
|
|
43527
|
+
return false;
|
|
43528
|
+
if (!transform.docChanged)
|
|
43529
|
+
return true;
|
|
43530
|
+
let adjacent = false;
|
|
43531
|
+
transform.mapping.maps[0].forEach((start, end) => {
|
|
43532
|
+
for (let i = 0; i < prevRanges.length; i += 2)
|
|
43533
|
+
if (start <= prevRanges[i + 1] && end >= prevRanges[i])
|
|
43534
|
+
adjacent = true;
|
|
43535
|
+
});
|
|
43536
|
+
return adjacent;
|
|
43537
|
+
}
|
|
43538
|
+
function rangesFor(maps) {
|
|
43539
|
+
let result = [];
|
|
43540
|
+
for (let i = maps.length - 1; i >= 0 && result.length == 0; i--)
|
|
43541
|
+
maps[i].forEach((_from, _to, from, to) => result.push(from, to));
|
|
43542
|
+
return result;
|
|
43543
|
+
}
|
|
43544
|
+
function mapRanges(ranges, mapping) {
|
|
43545
|
+
if (!ranges)
|
|
43546
|
+
return null;
|
|
43547
|
+
let result = [];
|
|
43548
|
+
for (let i = 0; i < ranges.length; i += 2) {
|
|
43549
|
+
let from = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1);
|
|
43550
|
+
if (from <= to)
|
|
43551
|
+
result.push(from, to);
|
|
43552
|
+
}
|
|
43553
|
+
return result;
|
|
43554
|
+
}
|
|
43555
|
+
// Apply the latest event from one branch to the document and shift the event
|
|
43556
|
+
// onto the other branch.
|
|
43557
|
+
function histTransaction(history, state, redo) {
|
|
43558
|
+
let preserveItems = mustPreserveItems(state);
|
|
43559
|
+
let histOptions = historyKey.get(state).spec.config;
|
|
43560
|
+
let pop = (redo ? history.undone : history.done).popEvent(state, preserveItems);
|
|
43561
|
+
if (!pop)
|
|
43562
|
+
return null;
|
|
43563
|
+
let selection = pop.selection.resolve(pop.transform.doc);
|
|
43564
|
+
let added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);
|
|
43565
|
+
let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1);
|
|
43566
|
+
return pop.transform.setSelection(selection).setMeta(historyKey, { redo, historyState: newHist });
|
|
43567
|
+
}
|
|
43568
|
+
let cachedPreserveItems = false, cachedPreserveItemsPlugins = null;
|
|
43569
|
+
// Check whether any plugin in the given state has a
|
|
43570
|
+
// `historyPreserveItems` property in its spec, in which case we must
|
|
43571
|
+
// preserve steps exactly as they came in, so that they can be
|
|
43572
|
+
// rebased.
|
|
43573
|
+
function mustPreserveItems(state) {
|
|
43574
|
+
let plugins = state.plugins;
|
|
43575
|
+
if (cachedPreserveItemsPlugins != plugins) {
|
|
43576
|
+
cachedPreserveItems = false;
|
|
43577
|
+
cachedPreserveItemsPlugins = plugins;
|
|
43578
|
+
for (let i = 0; i < plugins.length; i++)
|
|
43579
|
+
if (plugins[i].spec.historyPreserveItems) {
|
|
43580
|
+
cachedPreserveItems = true;
|
|
43581
|
+
break;
|
|
43582
|
+
}
|
|
43583
|
+
}
|
|
43584
|
+
return cachedPreserveItems;
|
|
43585
|
+
}
|
|
43586
|
+
/**
|
|
43587
|
+
Set a flag on the given transaction that will prevent further steps
|
|
43588
|
+
from being appended to an existing history event (so that they
|
|
43589
|
+
require a separate undo command to undo).
|
|
43590
|
+
*/
|
|
43591
|
+
function closeHistory(tr) {
|
|
43592
|
+
return tr.setMeta(closeHistoryKey, true);
|
|
43593
|
+
}
|
|
43594
|
+
const historyKey = new PluginKey("history");
|
|
43595
|
+
const closeHistoryKey = new PluginKey("closeHistory");
|
|
43596
|
+
/**
|
|
43597
|
+
Returns a plugin that enables the undo history for an editor. The
|
|
43598
|
+
plugin will track undo and redo stacks, which can be used with the
|
|
43599
|
+
[`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.
|
|
43600
|
+
|
|
43601
|
+
You can set an `"addToHistory"` [metadata
|
|
43602
|
+
property](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction
|
|
43603
|
+
to prevent it from being rolled back by undo.
|
|
43604
|
+
*/
|
|
43605
|
+
function history(config = {}) {
|
|
43606
|
+
config = { depth: config.depth || 100,
|
|
43607
|
+
newGroupDelay: config.newGroupDelay || 500 };
|
|
43608
|
+
return new Plugin({
|
|
43609
|
+
key: historyKey,
|
|
43610
|
+
state: {
|
|
43611
|
+
init() {
|
|
43612
|
+
return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);
|
|
43613
|
+
},
|
|
43614
|
+
apply(tr, hist, state) {
|
|
43615
|
+
return applyTransaction(hist, state, tr, config);
|
|
43616
|
+
}
|
|
43617
|
+
},
|
|
43618
|
+
config,
|
|
43619
|
+
props: {
|
|
43620
|
+
handleDOMEvents: {
|
|
43621
|
+
beforeinput(view, e) {
|
|
43622
|
+
let inputType = e.inputType;
|
|
43623
|
+
let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
|
|
43624
|
+
if (!command || !view.editable)
|
|
43625
|
+
return false;
|
|
43626
|
+
e.preventDefault();
|
|
43627
|
+
return command(view.state, view.dispatch);
|
|
43628
|
+
}
|
|
43629
|
+
}
|
|
43630
|
+
}
|
|
43631
|
+
});
|
|
43632
|
+
}
|
|
43633
|
+
function buildCommand(redo, scroll) {
|
|
43634
|
+
return (state, dispatch) => {
|
|
43635
|
+
let hist = historyKey.getState(state);
|
|
43636
|
+
if (!hist || (redo ? hist.undone : hist.done).eventCount == 0)
|
|
43637
|
+
return false;
|
|
43638
|
+
if (dispatch) {
|
|
43639
|
+
let tr = histTransaction(hist, state, redo);
|
|
43640
|
+
if (tr)
|
|
43641
|
+
dispatch(scroll ? tr.scrollIntoView() : tr);
|
|
43642
|
+
}
|
|
43643
|
+
return true;
|
|
43644
|
+
};
|
|
43645
|
+
}
|
|
43646
|
+
/**
|
|
43647
|
+
A command function that undoes the last change, if any.
|
|
43648
|
+
*/
|
|
43649
|
+
const undo = buildCommand(false, true);
|
|
43650
|
+
/**
|
|
43651
|
+
A command function that redoes the last undone change, if any.
|
|
43652
|
+
*/
|
|
43653
|
+
const redo = buildCommand(true, true);
|
|
43654
|
+
/**
|
|
43655
|
+
Returns true if the given transaction was generated by the history
|
|
43656
|
+
plugin.
|
|
43657
|
+
*/
|
|
43658
|
+
function isHistoryTransaction(tr) {
|
|
43659
|
+
return tr.getMeta(historyKey) != null;
|
|
43660
|
+
}
|
|
43661
|
+
|
|
43662
|
+
//#region src/helpers/createChainableState.ts
|
|
43663
|
+
/**
|
|
43664
|
+
* Takes a Transaction & Editor State and turns it into a chainable state object
|
|
43665
|
+
* @param config The transaction and state to create the chainable state from
|
|
43666
|
+
* @returns A chainable Editor state object
|
|
43667
|
+
*/
|
|
43668
|
+
function createChainableState(config) {
|
|
43669
|
+
const { state, transaction } = config;
|
|
43670
|
+
let { selection } = transaction;
|
|
43671
|
+
let { doc } = transaction;
|
|
43672
|
+
let { storedMarks } = transaction;
|
|
43673
|
+
return {
|
|
43674
|
+
...state,
|
|
43675
|
+
apply: state.apply.bind(state),
|
|
43676
|
+
applyTransaction: state.applyTransaction.bind(state),
|
|
43677
|
+
plugins: state.plugins,
|
|
43678
|
+
schema: state.schema,
|
|
43679
|
+
reconfigure: state.reconfigure.bind(state),
|
|
43680
|
+
toJSON: state.toJSON.bind(state),
|
|
43681
|
+
get storedMarks() {
|
|
43682
|
+
return storedMarks;
|
|
43683
|
+
},
|
|
43684
|
+
get selection() {
|
|
43685
|
+
return selection;
|
|
43686
|
+
},
|
|
43687
|
+
get doc() {
|
|
43688
|
+
return doc;
|
|
43689
|
+
},
|
|
43690
|
+
get tr() {
|
|
43691
|
+
selection = transaction.selection;
|
|
43692
|
+
doc = transaction.doc;
|
|
43693
|
+
storedMarks = transaction.storedMarks;
|
|
43694
|
+
return transaction;
|
|
43695
|
+
}
|
|
43696
|
+
};
|
|
43697
|
+
}
|
|
43698
|
+
//#endregion
|
|
43699
|
+
//#region src/CommandManager.ts
|
|
43700
|
+
var CommandManager = class CommandManager {
|
|
43701
|
+
constructor(props) {
|
|
43702
|
+
this.editor = props.editor;
|
|
43703
|
+
this.rawCommands = this.editor.extensionManager.commands;
|
|
43704
|
+
this.customState = props.state;
|
|
43705
|
+
}
|
|
43706
|
+
get hasCustomState() {
|
|
43707
|
+
return !!this.customState;
|
|
43708
|
+
}
|
|
43709
|
+
get state() {
|
|
43710
|
+
return this.customState || this.editor.state;
|
|
43711
|
+
}
|
|
43712
|
+
get commands() {
|
|
43713
|
+
const { rawCommands, editor, state } = this;
|
|
43714
|
+
const { view } = editor;
|
|
43715
|
+
const { tr } = state;
|
|
43716
|
+
const props = this.buildProps(tr);
|
|
43717
|
+
return Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43718
|
+
const method = (...args) => {
|
|
43719
|
+
const callback = command(...args)(props);
|
|
43720
|
+
if (!tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
|
|
43721
|
+
return callback;
|
|
43722
|
+
};
|
|
43723
|
+
return [name, method];
|
|
43724
|
+
}));
|
|
43725
|
+
}
|
|
43726
|
+
get chain() {
|
|
43727
|
+
return () => this.createChain();
|
|
43728
|
+
}
|
|
43729
|
+
get can() {
|
|
43730
|
+
return () => this.createCan();
|
|
43731
|
+
}
|
|
43732
|
+
createChain(startTr, shouldDispatch = true) {
|
|
43733
|
+
const { rawCommands, editor, state } = this;
|
|
43734
|
+
const { view } = editor;
|
|
43735
|
+
const callbacks = [];
|
|
43736
|
+
const hasStartTransaction = !!startTr;
|
|
43737
|
+
const tr = startTr || state.tr;
|
|
43738
|
+
const run = () => {
|
|
43739
|
+
if (!hasStartTransaction && shouldDispatch && !tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
|
|
43740
|
+
return callbacks.every((callback) => callback === true);
|
|
43741
|
+
};
|
|
43742
|
+
const chain = {
|
|
43743
|
+
...Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43744
|
+
const chainedCommand = (...args) => {
|
|
43745
|
+
const props = this.buildProps(tr, shouldDispatch);
|
|
43746
|
+
const callback = command(...args)(props);
|
|
43747
|
+
callbacks.push(callback);
|
|
43748
|
+
return chain;
|
|
43749
|
+
};
|
|
43750
|
+
return [name, chainedCommand];
|
|
43751
|
+
})),
|
|
43752
|
+
run
|
|
43753
|
+
};
|
|
43754
|
+
return chain;
|
|
43755
|
+
}
|
|
43756
|
+
/**
|
|
43757
|
+
* Creates a chain that safely returns `false` when run.
|
|
43758
|
+
* @returns A non-dispatching command chain.
|
|
43759
|
+
* @example
|
|
43760
|
+
* const chain = CommandManager.createFakeChain()
|
|
43761
|
+
* chain.focus().run() // false
|
|
43762
|
+
*/
|
|
43763
|
+
static createFakeChain() {
|
|
43764
|
+
const chain = new Proxy({}, { get: (_target, property) => {
|
|
43765
|
+
if (property === "then") return;
|
|
43766
|
+
if (property === "run") return () => false;
|
|
43767
|
+
return () => chain;
|
|
43768
|
+
} });
|
|
43769
|
+
return chain;
|
|
43770
|
+
}
|
|
43771
|
+
createCan(startTr) {
|
|
43772
|
+
const { rawCommands, state } = this;
|
|
43773
|
+
const dispatch = false;
|
|
43774
|
+
const tr = startTr || state.tr;
|
|
43775
|
+
const props = this.buildProps(tr, dispatch);
|
|
43776
|
+
return {
|
|
43777
|
+
...Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43778
|
+
return [name, (...args) => command(...args)({
|
|
43779
|
+
...props,
|
|
43780
|
+
dispatch: void 0
|
|
43781
|
+
})];
|
|
43782
|
+
})),
|
|
43783
|
+
chain: () => this.createChain(tr, dispatch)
|
|
43784
|
+
};
|
|
43785
|
+
}
|
|
43786
|
+
/**
|
|
43787
|
+
* Creates capability checks that safely return `false`.
|
|
43788
|
+
* @returns A non-dispatching capability checker.
|
|
43789
|
+
* @example
|
|
43790
|
+
* const can = CommandManager.createFallbackCan()
|
|
43791
|
+
* can.focus() // false
|
|
43792
|
+
*/
|
|
43793
|
+
static createFallbackCan() {
|
|
43794
|
+
const chain = CommandManager.createFakeChain();
|
|
43795
|
+
return new Proxy({ chain: () => chain }, { get: (target, property) => {
|
|
43796
|
+
if (property === "then") return;
|
|
43797
|
+
if (property === "chain") return target.chain;
|
|
43798
|
+
return () => false;
|
|
43799
|
+
} });
|
|
43800
|
+
}
|
|
43801
|
+
buildProps(tr, shouldDispatch = true) {
|
|
43802
|
+
const { rawCommands, editor, state } = this;
|
|
43803
|
+
const { view } = editor;
|
|
43804
|
+
const props = {
|
|
43805
|
+
tr,
|
|
43806
|
+
editor,
|
|
43807
|
+
view,
|
|
43808
|
+
state: createChainableState({
|
|
43809
|
+
state,
|
|
43810
|
+
transaction: tr
|
|
43811
|
+
}),
|
|
43812
|
+
dispatch: shouldDispatch ? () => void 0 : void 0,
|
|
43813
|
+
chain: () => this.createChain(tr, shouldDispatch),
|
|
43814
|
+
can: () => this.createCan(tr),
|
|
43815
|
+
get commands() {
|
|
43816
|
+
return Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => {
|
|
43817
|
+
return [name, (...args) => command(...args)(props)];
|
|
43818
|
+
}));
|
|
43819
|
+
}
|
|
43820
|
+
};
|
|
43821
|
+
return props;
|
|
43822
|
+
}
|
|
43823
|
+
};
|
|
43824
|
+
//#endregion
|
|
43825
|
+
//#region src/commands/blur.ts
|
|
43826
|
+
const blur = () => ({ editor, view }) => {
|
|
43827
|
+
requestAnimationFrame(() => {
|
|
43828
|
+
if (!editor.isDestroyed) {
|
|
43829
|
+
var _window;
|
|
43830
|
+
view.dom.blur();
|
|
43831
|
+
(_window = window) === null || _window === void 0 || (_window = _window.getSelection()) === null || _window === void 0 || _window.removeAllRanges();
|
|
43832
|
+
}
|
|
43833
|
+
});
|
|
43834
|
+
return true;
|
|
43835
|
+
};
|
|
43836
|
+
//#endregion
|
|
43837
|
+
//#region src/commands/clearContent.ts
|
|
43838
|
+
const clearContent = (emitUpdate = true) => ({ commands }) => {
|
|
43839
|
+
return commands.setContent("", { emitUpdate });
|
|
43840
|
+
};
|
|
43841
|
+
//#endregion
|
|
43842
|
+
//#region src/commands/clearNodes.ts
|
|
43843
|
+
const clearNodes = () => ({ state, tr, dispatch }) => {
|
|
43844
|
+
const { selection } = tr;
|
|
43845
|
+
const { ranges } = selection;
|
|
43846
|
+
if (!dispatch) return true;
|
|
43847
|
+
ranges.forEach(({ $from, $to }) => {
|
|
43848
|
+
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
43849
|
+
if (node.type.isText) return;
|
|
43850
|
+
const { doc, mapping } = tr;
|
|
43851
|
+
const $mappedFrom = doc.resolve(mapping.map(pos));
|
|
43852
|
+
const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize));
|
|
43853
|
+
const nodeRange = $mappedFrom.blockRange($mappedTo);
|
|
43854
|
+
if (!nodeRange) return;
|
|
43855
|
+
const targetLiftDepth = liftTarget(nodeRange);
|
|
43856
|
+
if (node.type.isTextblock) {
|
|
43857
|
+
const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index());
|
|
43858
|
+
tr.setNodeMarkup(nodeRange.start, defaultType);
|
|
43859
|
+
}
|
|
43860
|
+
if (targetLiftDepth || targetLiftDepth === 0) tr.lift(nodeRange, targetLiftDepth);
|
|
43861
|
+
});
|
|
43862
|
+
});
|
|
43863
|
+
return true;
|
|
43864
|
+
};
|
|
43865
|
+
//#endregion
|
|
43866
|
+
//#region src/commands/command.ts
|
|
43867
|
+
const command = (fn) => (props) => {
|
|
43868
|
+
return fn(props);
|
|
43869
|
+
};
|
|
43870
|
+
//#endregion
|
|
43871
|
+
//#region src/commands/createParagraphNear.ts
|
|
43872
|
+
const createParagraphNear$1 = () => ({ state, dispatch }) => {
|
|
43873
|
+
return createParagraphNear(state, dispatch);
|
|
43874
|
+
};
|
|
43875
|
+
//#endregion
|
|
43876
|
+
//#region src/commands/cut.ts
|
|
43877
|
+
const cut = (originRange, targetPos) => ({ editor, tr }) => {
|
|
43878
|
+
const { state } = editor;
|
|
43879
|
+
const contentSlice = state.doc.slice(originRange.from, originRange.to);
|
|
43880
|
+
tr.deleteRange(originRange.from, originRange.to);
|
|
43881
|
+
const newPos = tr.mapping.map(targetPos);
|
|
43882
|
+
tr.insert(newPos, contentSlice.content);
|
|
43883
|
+
tr.setSelection(new TextSelection(tr.doc.resolve(Math.max(newPos - 1, 0))));
|
|
43884
|
+
return true;
|
|
43885
|
+
};
|
|
43886
|
+
//#endregion
|
|
43887
|
+
//#region src/commands/deleteCurrentNode.ts
|
|
43888
|
+
const deleteCurrentNode = () => ({ tr, dispatch }) => {
|
|
43889
|
+
const { selection } = tr;
|
|
43890
|
+
const currentNode = selection.$anchor.node();
|
|
43891
|
+
if (currentNode.content.size > 0) return false;
|
|
43892
|
+
const $pos = tr.selection.$anchor;
|
|
43893
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === currentNode.type) {
|
|
43894
|
+
if (dispatch) {
|
|
43895
|
+
const from = $pos.before(depth);
|
|
43896
|
+
const to = $pos.after(depth);
|
|
43897
|
+
tr.delete(from, to).scrollIntoView();
|
|
43898
|
+
}
|
|
43899
|
+
return true;
|
|
43900
|
+
}
|
|
43901
|
+
return false;
|
|
43902
|
+
};
|
|
43903
|
+
//#endregion
|
|
43904
|
+
//#region src/helpers/getNodeType.ts
|
|
43905
|
+
function getNodeType(nameOrType, schema) {
|
|
43906
|
+
if (typeof nameOrType === "string") {
|
|
43907
|
+
if (!schema.nodes[nameOrType]) throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`);
|
|
43908
|
+
return schema.nodes[nameOrType];
|
|
43909
|
+
}
|
|
43910
|
+
return nameOrType;
|
|
43911
|
+
}
|
|
43912
|
+
//#endregion
|
|
43913
|
+
//#region src/commands/deleteNode.ts
|
|
43914
|
+
const deleteNode = (typeOrName) => ({ tr, state, dispatch }) => {
|
|
43915
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
43916
|
+
const $pos = tr.selection.$anchor;
|
|
43917
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === type) {
|
|
43918
|
+
if (dispatch) {
|
|
43919
|
+
const from = $pos.before(depth);
|
|
43920
|
+
const to = $pos.after(depth);
|
|
43921
|
+
tr.delete(from, to).scrollIntoView();
|
|
43922
|
+
}
|
|
43923
|
+
return true;
|
|
43924
|
+
}
|
|
43925
|
+
return false;
|
|
43926
|
+
};
|
|
43927
|
+
//#endregion
|
|
43928
|
+
//#region src/commands/deleteRange.ts
|
|
43929
|
+
const deleteRange = (range) => ({ tr, dispatch }) => {
|
|
43930
|
+
const { from, to } = range;
|
|
43931
|
+
if (dispatch) tr.delete(from, to);
|
|
43932
|
+
return true;
|
|
43933
|
+
};
|
|
43934
|
+
//#endregion
|
|
43935
|
+
//#region src/commands/deleteSelection.ts
|
|
43936
|
+
/**
|
|
43937
|
+
* Check if a node has text content based on its content specification.
|
|
43938
|
+
* Returns true if the node's content spec matches text* or text+ patterns.
|
|
43939
|
+
*/
|
|
43940
|
+
const hasTextContent = (nodeSpec) => {
|
|
43941
|
+
if (!nodeSpec.content) return false;
|
|
43942
|
+
return /^text(\*|\+)/.test(nodeSpec.content);
|
|
43943
|
+
};
|
|
43944
|
+
/**
|
|
43945
|
+
* Expand selection position for a specific side (left or right) to handle inline text nodes.
|
|
43946
|
+
* This function checks if the position is within an inline node with text content and
|
|
43947
|
+
* expands it to include the entire node boundaries for proper deletion.
|
|
43948
|
+
* @param $pos - The resolved position to expand
|
|
43949
|
+
* @param schema - The ProseMirror schema
|
|
43950
|
+
* @param side - Which side to expand ('left' or 'right')
|
|
43951
|
+
* @returns The expanded position for deletion
|
|
43952
|
+
*/
|
|
43953
|
+
const expandSelectionForSide = ($pos, schema, side) => {
|
|
43954
|
+
if (!$pos.parent.isInline) return $pos.pos;
|
|
43955
|
+
if (side === "left" && $pos.pos > $pos.start() || side === "right" && $pos.pos < $pos.end()) return $pos.pos;
|
|
43956
|
+
const parentContent = schema.nodes[$pos.parent.type.name].spec;
|
|
43957
|
+
if (!hasTextContent(parentContent)) return $pos.pos;
|
|
43958
|
+
return side === "left" ? $pos.start() - 1 : $pos.end() + 1;
|
|
43959
|
+
};
|
|
43960
|
+
/**
|
|
43961
|
+
* Expand selection range to properly handle deletion of inline text nodes.
|
|
43962
|
+
* Inline text nodes don't collapse correctly when text inside is deleted,
|
|
43963
|
+
* so we need to expand the selection to include the entire node.
|
|
43964
|
+
* See: https://code.haverbeke.berlin/prosemirror/prosemirror/issues/1365
|
|
43965
|
+
*/
|
|
43966
|
+
const expandSelectionForInlineText = ($from, $to, schema) => {
|
|
43967
|
+
return {
|
|
43968
|
+
from: expandSelectionForSide($from, schema, "left"),
|
|
43969
|
+
to: expandSelectionForSide($to, schema, "right")
|
|
43970
|
+
};
|
|
43971
|
+
};
|
|
43972
|
+
const deleteSelection = () => ({ state, dispatch }) => {
|
|
43973
|
+
if (state.selection.empty) return false;
|
|
43974
|
+
if (dispatch) {
|
|
43975
|
+
const tr = state.tr;
|
|
43976
|
+
const { ranges } = state.selection;
|
|
43977
|
+
const mapFrom = tr.steps.length;
|
|
43978
|
+
ranges.forEach((range) => {
|
|
43979
|
+
const mapping = tr.mapping.slice(mapFrom);
|
|
43980
|
+
const $from = tr.doc.resolve(mapping.map(range.$from.pos));
|
|
43981
|
+
const $to = tr.doc.resolve(mapping.map(range.$to.pos));
|
|
43982
|
+
const { from, to } = expandSelectionForInlineText($from, $to, state.schema);
|
|
43983
|
+
tr.deleteRange(from, to);
|
|
43984
|
+
});
|
|
43985
|
+
if (!tr.selection.empty) tr.setSelection(TextSelection.near(tr.doc.resolve(tr.selection.from)));
|
|
43986
|
+
tr.scrollIntoView();
|
|
43987
|
+
dispatch(tr);
|
|
43988
|
+
}
|
|
43989
|
+
return true;
|
|
43990
|
+
};
|
|
43991
|
+
//#endregion
|
|
43992
|
+
//#region src/commands/enter.ts
|
|
43993
|
+
const enter = () => ({ commands }) => {
|
|
43994
|
+
return commands.keyboardShortcut("Enter");
|
|
43995
|
+
};
|
|
43996
|
+
//#endregion
|
|
43997
|
+
//#region src/commands/exitCode.ts
|
|
43998
|
+
const exitCode$1 = () => ({ state, dispatch }) => {
|
|
43999
|
+
return exitCode(state, dispatch);
|
|
44000
|
+
};
|
|
44001
|
+
//#endregion
|
|
44002
|
+
//#region src/utilities/isRegExp.ts
|
|
44003
|
+
function isRegExp$1(value) {
|
|
44004
|
+
return Object.prototype.toString.call(value) === "[object RegExp]";
|
|
44005
|
+
}
|
|
44006
|
+
//#endregion
|
|
44007
|
+
//#region src/utilities/objectIncludes.ts
|
|
44008
|
+
/**
|
|
44009
|
+
* Check if object1 includes object2
|
|
44010
|
+
* @param object1 Object
|
|
44011
|
+
* @param object2 Object
|
|
44012
|
+
*/
|
|
44013
|
+
function objectIncludes(object1, object2, options = { strict: true }) {
|
|
44014
|
+
const keys = Object.keys(object2);
|
|
44015
|
+
if (!keys.length) return true;
|
|
44016
|
+
return keys.every((key) => {
|
|
44017
|
+
if (options.strict) return object2[key] === object1[key];
|
|
44018
|
+
if (isRegExp$1(object2[key])) return object2[key].test(object1[key]);
|
|
44019
|
+
return object2[key] === object1[key];
|
|
44020
|
+
});
|
|
44021
|
+
}
|
|
44022
|
+
//#endregion
|
|
44023
|
+
//#region src/helpers/getMarkRange.ts
|
|
44024
|
+
function findMarkInSet(marks, type, attributes = {}) {
|
|
44025
|
+
return marks.find((item) => {
|
|
44026
|
+
return item.type === type && objectIncludes(Object.fromEntries(Object.keys(attributes).map((k) => [k, item.attrs[k]])), attributes);
|
|
44027
|
+
});
|
|
44028
|
+
}
|
|
44029
|
+
function isMarkInSet(marks, type, attributes = {}) {
|
|
44030
|
+
return !!findMarkInSet(marks, type, attributes);
|
|
44031
|
+
}
|
|
44032
|
+
/**
|
|
44033
|
+
* Get the range of a mark at a resolved position.
|
|
44034
|
+
*/
|
|
44035
|
+
function getMarkRange($pos, type, attributes) {
|
|
44036
|
+
if (!$pos || !type) return;
|
|
44037
|
+
let start = $pos.parent.childAfter($pos.parentOffset);
|
|
43369
44038
|
if (!start.node || !start.node.marks.some((mark) => mark.type === type)) start = $pos.parent.childBefore($pos.parentOffset);
|
|
43370
44039
|
if (!start.node || !start.node.marks.some((mark) => mark.type === type)) return;
|
|
43371
44040
|
if (!attributes) {
|
|
@@ -43792,11 +44461,21 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
43792
44461
|
return joinForward(state, dispatch);
|
|
43793
44462
|
};
|
|
43794
44463
|
//#endregion
|
|
44464
|
+
//#region src/commands/canJoinItemsAt.ts
|
|
44465
|
+
const canJoinItemsAt = (doc, pos) => {
|
|
44466
|
+
const $pos = doc.resolve(pos);
|
|
44467
|
+
const before = $pos.nodeBefore;
|
|
44468
|
+
const after = $pos.nodeAfter;
|
|
44469
|
+
if (!before || !after) return false;
|
|
44470
|
+
return !before.type.spec.isolating && !after.type.spec.isolating;
|
|
44471
|
+
};
|
|
44472
|
+
//#endregion
|
|
43795
44473
|
//#region src/commands/joinItemBackward.ts
|
|
43796
44474
|
const joinItemBackward = () => ({ state, dispatch, tr }) => {
|
|
43797
44475
|
try {
|
|
43798
44476
|
const point = joinPoint(state.doc, state.selection.$from.pos, -1);
|
|
43799
44477
|
if (point === null || point === void 0) return false;
|
|
44478
|
+
if (!canJoinItemsAt(state.doc, point)) return false;
|
|
43800
44479
|
tr.join(point, 2);
|
|
43801
44480
|
if (dispatch) dispatch(tr);
|
|
43802
44481
|
return true;
|
|
@@ -43810,6 +44489,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
43810
44489
|
try {
|
|
43811
44490
|
const point = joinPoint(state.doc, state.selection.$from.pos, 1);
|
|
43812
44491
|
if (point === null || point === void 0) return false;
|
|
44492
|
+
if (!canJoinItemsAt(state.doc, point)) return false;
|
|
43813
44493
|
tr.join(point, 2);
|
|
43814
44494
|
if (dispatch) dispatch(tr);
|
|
43815
44495
|
return true;
|
|
@@ -45216,8 +45896,14 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45216
45896
|
type: deflt,
|
|
45217
45897
|
attrs: newAttributes
|
|
45218
45898
|
}] : void 0;
|
|
45219
|
-
|
|
45220
|
-
|
|
45899
|
+
const deletedTr = selection instanceof TextSelection && !selection.empty ? EditorState.create({
|
|
45900
|
+
doc: tr.doc,
|
|
45901
|
+
selection
|
|
45902
|
+
}).tr.deleteSelection() : null;
|
|
45903
|
+
const splitDoc = deletedTr ? deletedTr.doc : tr.doc;
|
|
45904
|
+
const splitPos = deletedTr ? deletedTr.mapping.map($from.pos) : $from.pos;
|
|
45905
|
+
let can = canSplit(splitDoc, splitPos, 1, types);
|
|
45906
|
+
if (!types && !can && canSplit(splitDoc, splitPos, 1, deflt ? [{ type: deflt }] : void 0)) {
|
|
45221
45907
|
can = true;
|
|
45222
45908
|
types = deflt ? [{
|
|
45223
45909
|
type: deflt,
|
|
@@ -45226,12 +45912,13 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45226
45912
|
}
|
|
45227
45913
|
if (dispatch) {
|
|
45228
45914
|
if (can) {
|
|
45915
|
+
const mapFrom = tr.steps.length;
|
|
45229
45916
|
if (selection instanceof TextSelection) tr.deleteSelection();
|
|
45230
|
-
tr.split(tr.mapping.map($from.pos), 1, types);
|
|
45917
|
+
tr.split(tr.mapping.slice(mapFrom).map($from.pos), 1, types);
|
|
45231
45918
|
if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) {
|
|
45232
|
-
const first = tr.mapping.map($from.before());
|
|
45919
|
+
const first = tr.mapping.slice(mapFrom).map($from.before());
|
|
45233
45920
|
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);
|
|
45921
|
+
if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) tr.setNodeMarkup(tr.mapping.slice(mapFrom).map($from.before()), deflt);
|
|
45235
45922
|
}
|
|
45236
45923
|
}
|
|
45237
45924
|
if (keepMarks) ensureMarks(state, editor.extensionManager.splittableMarks);
|
|
@@ -45284,16 +45971,19 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45284
45971
|
...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
|
|
45285
45972
|
...overrideAttrs
|
|
45286
45973
|
};
|
|
45974
|
+
const splitsAtStartOfItem = $from.parentOffset === 0 && $from.index(-1) === 0;
|
|
45975
|
+
const itemStart = $from.before(-1);
|
|
45287
45976
|
tr.delete($from.pos, $to.pos);
|
|
45977
|
+
const trailingTypeAttributes = splitsAtStartOfItem ? grandParent.attrs : newTypeAttributes;
|
|
45288
45978
|
const types = nextType ? [{
|
|
45289
45979
|
type,
|
|
45290
|
-
attrs:
|
|
45980
|
+
attrs: trailingTypeAttributes
|
|
45291
45981
|
}, {
|
|
45292
45982
|
type: nextType,
|
|
45293
45983
|
attrs: newNextTypeAttributes
|
|
45294
45984
|
}] : [{
|
|
45295
45985
|
type,
|
|
45296
|
-
attrs:
|
|
45986
|
+
attrs: trailingTypeAttributes
|
|
45297
45987
|
}];
|
|
45298
45988
|
if (!canSplit(tr.doc, $from.pos, 2)) return false;
|
|
45299
45989
|
if (dispatch) {
|
|
@@ -45301,6 +45991,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
45301
45991
|
const { splittableMarks } = editor.extensionManager;
|
|
45302
45992
|
const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
|
|
45303
45993
|
tr.split($from.pos, 2, types).scrollIntoView();
|
|
45994
|
+
if (splitsAtStartOfItem) tr.setNodeMarkup(itemStart, void 0, newTypeAttributes);
|
|
45304
45995
|
if (!marks || !dispatch) return true;
|
|
45305
45996
|
const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
|
|
45306
45997
|
tr.ensureMarks(filteredMarks);
|
|
@@ -46833,55 +47524,106 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
46833
47524
|
}
|
|
46834
47525
|
return result;
|
|
46835
47526
|
};
|
|
47527
|
+
/**
|
|
47528
|
+
* Prepares the typed text so the rule handler can inspect the resulting document.
|
|
47529
|
+
*/
|
|
47530
|
+
function createRuleTransaction(config) {
|
|
47531
|
+
const { editor, from, to, text, insertText } = config;
|
|
47532
|
+
if (!insertText) return {
|
|
47533
|
+
inputTransaction: null,
|
|
47534
|
+
tr: editor.view.state.tr
|
|
47535
|
+
};
|
|
47536
|
+
const inputTransaction = editor.view.state.tr.insertText(text, from, to);
|
|
47537
|
+
return {
|
|
47538
|
+
inputTransaction,
|
|
47539
|
+
tr: EditorState.create({
|
|
47540
|
+
doc: inputTransaction.doc,
|
|
47541
|
+
selection: inputTransaction.selection,
|
|
47542
|
+
storedMarks: inputTransaction.storedMarks
|
|
47543
|
+
}).tr
|
|
47544
|
+
};
|
|
47545
|
+
}
|
|
47546
|
+
/**
|
|
47547
|
+
* Runs a matching rule and dispatches the typed text before its conversion.
|
|
47548
|
+
*/
|
|
47549
|
+
function applyRule(config) {
|
|
47550
|
+
const { editor, from, to, text, rule, match, plugin, insertText } = config;
|
|
47551
|
+
const { view } = editor;
|
|
47552
|
+
const { inputTransaction, tr } = createRuleTransaction({
|
|
47553
|
+
editor,
|
|
47554
|
+
from,
|
|
47555
|
+
to,
|
|
47556
|
+
text,
|
|
47557
|
+
insertText
|
|
47558
|
+
});
|
|
47559
|
+
const inputEnd = inputTransaction ? from + text.length : to;
|
|
47560
|
+
const state = createChainableState({
|
|
47561
|
+
state: view.state,
|
|
47562
|
+
transaction: tr
|
|
47563
|
+
});
|
|
47564
|
+
const range = {
|
|
47565
|
+
from: from - (match[0].length - text.length),
|
|
47566
|
+
to: inputEnd
|
|
47567
|
+
};
|
|
47568
|
+
const { commands, chain, can } = new CommandManager({
|
|
47569
|
+
editor,
|
|
47570
|
+
state
|
|
47571
|
+
});
|
|
47572
|
+
if (rule.handler({
|
|
47573
|
+
state,
|
|
47574
|
+
range,
|
|
47575
|
+
match,
|
|
47576
|
+
commands,
|
|
47577
|
+
chain,
|
|
47578
|
+
can
|
|
47579
|
+
}) === null || !tr.steps.length) return false;
|
|
47580
|
+
if (inputTransaction) {
|
|
47581
|
+
view.dispatch(inputTransaction);
|
|
47582
|
+
if (!view.state.doc.eq(inputTransaction.doc)) return true;
|
|
47583
|
+
}
|
|
47584
|
+
closeHistory(tr);
|
|
47585
|
+
tr.setMeta("inputRule", true);
|
|
47586
|
+
if (rule.undoable) tr.setMeta(plugin, {
|
|
47587
|
+
transform: tr,
|
|
47588
|
+
from,
|
|
47589
|
+
to: inputEnd,
|
|
47590
|
+
text
|
|
47591
|
+
});
|
|
47592
|
+
view.dispatch(tr);
|
|
47593
|
+
return true;
|
|
47594
|
+
}
|
|
47595
|
+
/**
|
|
47596
|
+
* Checks that the part of a match already in the document has matching positions.
|
|
47597
|
+
*/
|
|
47598
|
+
function matchesDocument($from, match, text) {
|
|
47599
|
+
const matchedDocLength = match[0].length - text.length;
|
|
47600
|
+
if (matchedDocLength <= 0) return true;
|
|
47601
|
+
const matchStartOffset = $from.parentOffset - matchedDocLength;
|
|
47602
|
+
return matchStartOffset >= 0 && $from.parent.textBetween(matchStartOffset, $from.parentOffset) === match[0].slice(0, matchedDocLength);
|
|
47603
|
+
}
|
|
46836
47604
|
function run$1$1(config) {
|
|
46837
47605
|
var _ref;
|
|
46838
|
-
const { editor, from, to, text, rules, plugin } = config;
|
|
47606
|
+
const { editor, from, to, text, rules, plugin, insertText } = config;
|
|
46839
47607
|
const { view } = editor;
|
|
46840
47608
|
if (view.composing) return false;
|
|
46841
47609
|
const $from = view.state.doc.resolve(from);
|
|
46842
47610
|
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
47611
|
const textBefore = getTextContentFromNodes($from) + text;
|
|
46845
|
-
|
|
46846
|
-
if (matched) return;
|
|
47612
|
+
for (const rule of rules) {
|
|
46847
47613
|
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({
|
|
47614
|
+
if (!match || !matchesDocument($from, match, text)) continue;
|
|
47615
|
+
if (applyRule({
|
|
46864
47616
|
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
47617
|
from,
|
|
46878
47618
|
to,
|
|
46879
|
-
text
|
|
46880
|
-
|
|
46881
|
-
|
|
46882
|
-
|
|
46883
|
-
|
|
46884
|
-
|
|
47619
|
+
text,
|
|
47620
|
+
rule,
|
|
47621
|
+
match,
|
|
47622
|
+
plugin,
|
|
47623
|
+
insertText
|
|
47624
|
+
})) return true;
|
|
47625
|
+
}
|
|
47626
|
+
return false;
|
|
46885
47627
|
}
|
|
46886
47628
|
/**
|
|
46887
47629
|
* Create an input rules plugin. When enabled, it will cause text
|
|
@@ -46925,7 +47667,8 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
46925
47667
|
to,
|
|
46926
47668
|
text,
|
|
46927
47669
|
rules,
|
|
46928
|
-
plugin
|
|
47670
|
+
plugin,
|
|
47671
|
+
insertText: true
|
|
46929
47672
|
});
|
|
46930
47673
|
},
|
|
46931
47674
|
handleDOMEvents: { compositionend: (view) => {
|
|
@@ -47161,6 +47904,9 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
47161
47904
|
pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null;
|
|
47162
47905
|
return tr;
|
|
47163
47906
|
};
|
|
47907
|
+
editor.on("destroy", () => {
|
|
47908
|
+
if (tiptapDragFromOtherEditor === editor) tiptapDragFromOtherEditor = null;
|
|
47909
|
+
});
|
|
47164
47910
|
return rules.map((rule) => {
|
|
47165
47911
|
return new Plugin({
|
|
47166
47912
|
view(view) {
|
|
@@ -47186,6 +47932,7 @@ so this becomes the fallback color for the slot */ ''}
|
|
|
47186
47932
|
if (!isDroppedFromProseMirror) {
|
|
47187
47933
|
const dragFromOtherEditor = tiptapDragFromOtherEditor;
|
|
47188
47934
|
if (dragFromOtherEditor === null || dragFromOtherEditor === void 0 ? void 0 : dragFromOtherEditor.isEditable) setTimeout(() => {
|
|
47935
|
+
if (dragFromOtherEditor.isDestroyed) return;
|
|
47189
47936
|
const selection = dragFromOtherEditor.state.selection;
|
|
47190
47937
|
if (selection) dragFromOtherEditor.commands.deleteRange({
|
|
47191
47938
|
from: selection.from,
|
|
@@ -48355,7 +49102,10 @@ img.ProseMirror-separator {
|
|
|
48355
49102
|
...options
|
|
48356
49103
|
};
|
|
48357
49104
|
if (!this.editorView || !this.state || this.isDestroyed) return;
|
|
48358
|
-
if (this.options.editorProps) this.view.setProps(
|
|
49105
|
+
if (this.options.editorProps) this.view.setProps({
|
|
49106
|
+
...this.options.editorProps,
|
|
49107
|
+
attributes: this.getEditorViewAttributes()
|
|
49108
|
+
});
|
|
48359
49109
|
this.view.updateState(this.state);
|
|
48360
49110
|
}
|
|
48361
49111
|
/**
|
|
@@ -48511,6 +49261,23 @@ img.ProseMirror-separator {
|
|
|
48511
49261
|
return doc;
|
|
48512
49262
|
}
|
|
48513
49263
|
/**
|
|
49264
|
+
* Returns the attributes for the editor element.
|
|
49265
|
+
* Merges the default `role="textbox"` with the attributes from `editorProps`,
|
|
49266
|
+
* so the role is kept no matter when the props are applied.
|
|
49267
|
+
*/
|
|
49268
|
+
getEditorViewAttributes() {
|
|
49269
|
+
var _this$options$editorP;
|
|
49270
|
+
const attributes = (_this$options$editorP = this.options.editorProps) === null || _this$options$editorP === void 0 ? void 0 : _this$options$editorP.attributes;
|
|
49271
|
+
if (isFunction$3(attributes)) return (state) => ({
|
|
49272
|
+
role: "textbox",
|
|
49273
|
+
...attributes(state)
|
|
49274
|
+
});
|
|
49275
|
+
return {
|
|
49276
|
+
role: "textbox",
|
|
49277
|
+
...attributes
|
|
49278
|
+
};
|
|
49279
|
+
}
|
|
49280
|
+
/**
|
|
48514
49281
|
* Creates a ProseMirror view.
|
|
48515
49282
|
*/
|
|
48516
49283
|
createView(element) {
|
|
@@ -48521,10 +49288,7 @@ img.ProseMirror-separator {
|
|
|
48521
49288
|
const transformPastedHTML = this.extensionManager.transformPastedHTML(baseTransformPastedHTML);
|
|
48522
49289
|
this.editorView = new EditorView(element, {
|
|
48523
49290
|
...editorProps,
|
|
48524
|
-
attributes:
|
|
48525
|
-
role: "textbox",
|
|
48526
|
-
...editorProps === null || editorProps === void 0 ? void 0 : editorProps.attributes
|
|
48527
|
-
},
|
|
49291
|
+
attributes: this.getEditorViewAttributes(),
|
|
48528
49292
|
dispatchTransaction: dispatch,
|
|
48529
49293
|
transformPastedHTML,
|
|
48530
49294
|
state: this.editorState,
|
|
@@ -58227,7 +58991,7 @@ img.ProseMirror-separator {
|
|
|
58227
58991
|
toDOM() { return ["div", ["hr"]]; }
|
|
58228
58992
|
},
|
|
58229
58993
|
heading: {
|
|
58230
|
-
attrs: { level: { default: 1 } },
|
|
58994
|
+
attrs: { level: { default: 1, validate: "number" } },
|
|
58231
58995
|
content: "(text | image)*",
|
|
58232
58996
|
group: "block",
|
|
58233
58997
|
defining: true,
|
|
@@ -58237,7 +59001,7 @@ img.ProseMirror-separator {
|
|
|
58237
59001
|
{ tag: "h4", attrs: { level: 4 } },
|
|
58238
59002
|
{ tag: "h5", attrs: { level: 5 } },
|
|
58239
59003
|
{ tag: "h6", attrs: { level: 6 } }],
|
|
58240
|
-
toDOM(node) { return ["h" + node.attrs.level, 0]; }
|
|
59004
|
+
toDOM(node) { return ["h" + +node.attrs.level, 0]; }
|
|
58241
59005
|
},
|
|
58242
59006
|
code_block: {
|
|
58243
59007
|
content: "text*",
|
|
@@ -61734,8 +62498,27 @@ img.ProseMirror-separator {
|
|
|
61734
62498
|
const UNICODE_WHITESPACE_PATTERN = "[\0- \xA0 -\u2029 ]";
|
|
61735
62499
|
const UNICODE_WHITESPACE_REGEX = new RegExp(UNICODE_WHITESPACE_PATTERN);
|
|
61736
62500
|
const UNICODE_WHITESPACE_REGEX_END = new RegExp(`${UNICODE_WHITESPACE_PATTERN}$`);
|
|
62501
|
+
const UNICODE_WHITESPACE_REGEX_TRAILING = new RegExp(`${UNICODE_WHITESPACE_PATTERN}+$`);
|
|
61737
62502
|
const UNICODE_WHITESPACE_REGEX_GLOBAL = new RegExp(UNICODE_WHITESPACE_PATTERN, "g");
|
|
61738
62503
|
//#endregion
|
|
62504
|
+
//#region src/helpers/unlinkTrailingWhitespace.ts
|
|
62505
|
+
function unlinkTrailingWhitespace(tr, range, type) {
|
|
62506
|
+
var _rangeEnd$nodeBefore, _insertedText$match;
|
|
62507
|
+
const rangeEnd = tr.doc.resolve(range.to);
|
|
62508
|
+
if (!((_rangeEnd$nodeBefore = rangeEnd.nodeBefore) === null || _rangeEnd$nodeBefore === void 0 ? void 0 : _rangeEnd$nodeBefore.isText)) return;
|
|
62509
|
+
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];
|
|
62510
|
+
if (!trailingWhitespace) return;
|
|
62511
|
+
const whitespaceFrom = range.to - trailingWhitespace.length;
|
|
62512
|
+
const linkMarks = getMarksBetween(whitespaceFrom, range.to, tr.doc).filter((item) => item.mark.type === type);
|
|
62513
|
+
if (!linkMarks.length) return;
|
|
62514
|
+
const { nodeAfter } = rangeEnd;
|
|
62515
|
+
if (!!nodeAfter && linkMarks.some((item) => item.mark.isInSet(nodeAfter.marks))) return;
|
|
62516
|
+
const storedMarks = tr.storedMarks;
|
|
62517
|
+
tr.removeMark(whitespaceFrom, range.to, type);
|
|
62518
|
+
tr.setStoredMarks(storedMarks);
|
|
62519
|
+
if (tr.selection.empty && tr.selection.from === range.to) tr.removeStoredMark(type);
|
|
62520
|
+
}
|
|
62521
|
+
//#endregion
|
|
61739
62522
|
//#region src/helpers/autolink.ts
|
|
61740
62523
|
/**
|
|
61741
62524
|
* Check if the provided tokens form a valid link structure, which can either be a single link token
|
|
@@ -61776,6 +62559,21 @@ img.ProseMirror-separator {
|
|
|
61776
62559
|
if (!docChanges || preventAutolink) return;
|
|
61777
62560
|
const { tr } = newState;
|
|
61778
62561
|
const transform = combineTransactionSteps(oldState.doc, [...transactions]);
|
|
62562
|
+
if (!transactions.some(isHistoryTransaction)) {
|
|
62563
|
+
const insertedRanges = [];
|
|
62564
|
+
transform.steps.forEach((step, index) => {
|
|
62565
|
+
if (!(step instanceof ReplaceStep) || !step.slice.size) return;
|
|
62566
|
+
const mapping = transform.mapping.slice(index + 1);
|
|
62567
|
+
const from = mapping.map(step.from, 1);
|
|
62568
|
+
const to = mapping.map(step.from + step.slice.size, -1);
|
|
62569
|
+
if (from < to) insertedRanges.push({
|
|
62570
|
+
from,
|
|
62571
|
+
to
|
|
62572
|
+
});
|
|
62573
|
+
});
|
|
62574
|
+
insertedRanges.sort((left, right) => right.to - left.to);
|
|
62575
|
+
insertedRanges.forEach((range) => unlinkTrailingWhitespace(tr, range, options.type));
|
|
62576
|
+
}
|
|
61779
62577
|
getChangedRanges(transform).forEach(({ newRange }) => {
|
|
61780
62578
|
const nodesInChangedRanges = findChildrenInRange(newState.doc, newRange, (node) => node.isTextblock);
|
|
61781
62579
|
let textBlock;
|
|
@@ -63162,6 +63960,54 @@ img.ProseMirror-separator {
|
|
|
63162
63960
|
});
|
|
63163
63961
|
}
|
|
63164
63962
|
//#endregion
|
|
63963
|
+
//#region src/ordered-list/collectOrderedListItemsFromSource.ts
|
|
63964
|
+
const ORDERED_LIST_SCAN_WINDOW = 64;
|
|
63965
|
+
function takeLines(source, max) {
|
|
63966
|
+
const lines = [];
|
|
63967
|
+
let start = 0;
|
|
63968
|
+
while (lines.length < max) {
|
|
63969
|
+
const lineEnd = source.indexOf("\n", start);
|
|
63970
|
+
if (lineEnd === -1) {
|
|
63971
|
+
lines.push(source.slice(start));
|
|
63972
|
+
return lines;
|
|
63973
|
+
}
|
|
63974
|
+
lines.push(source.slice(start, lineEnd));
|
|
63975
|
+
start = lineEnd + 1;
|
|
63976
|
+
}
|
|
63977
|
+
return lines;
|
|
63978
|
+
}
|
|
63979
|
+
/**
|
|
63980
|
+
* Collect ordered list items from the start of `source`, reading only the lines the list needs.
|
|
63981
|
+
*
|
|
63982
|
+
* @param source Markdown beginning at a block boundary.
|
|
63983
|
+
* @returns The items, how many lines they consumed, and the lines that were read.
|
|
63984
|
+
* @example
|
|
63985
|
+
* collectOrderedListItemsFromSource('1. one\n2. two\n\nAfter')
|
|
63986
|
+
* // → [[item, item], 3, ['1. one', '2. two', '', 'After']]
|
|
63987
|
+
*/
|
|
63988
|
+
function collectOrderedListItemsFromSource(source) {
|
|
63989
|
+
const firstLineEnd = source.indexOf("\n");
|
|
63990
|
+
const firstLine = firstLineEnd === -1 ? source : source.slice(0, firstLineEnd);
|
|
63991
|
+
if (!ORDERED_LIST_ITEM_REGEX.test(firstLine)) return [
|
|
63992
|
+
[],
|
|
63993
|
+
0,
|
|
63994
|
+
[]
|
|
63995
|
+
];
|
|
63996
|
+
let windowSize = ORDERED_LIST_SCAN_WINDOW;
|
|
63997
|
+
let lines = takeLines(source, windowSize);
|
|
63998
|
+
let collected = collectOrderedListItems(lines);
|
|
63999
|
+
while (collected[1] === lines.length && lines.length === windowSize) {
|
|
64000
|
+
windowSize *= 2;
|
|
64001
|
+
lines = takeLines(source, windowSize);
|
|
64002
|
+
collected = collectOrderedListItems(lines);
|
|
64003
|
+
}
|
|
64004
|
+
return [
|
|
64005
|
+
collected[0],
|
|
64006
|
+
collected[1],
|
|
64007
|
+
lines
|
|
64008
|
+
];
|
|
64009
|
+
}
|
|
64010
|
+
//#endregion
|
|
63165
64011
|
//#region src/ordered-list/ordered-list.ts
|
|
63166
64012
|
const ListItemName = "listItem";
|
|
63167
64013
|
const TextStyleName = "textStyle";
|
|
@@ -63280,8 +64126,7 @@ img.ProseMirror-separator {
|
|
|
63280
64126
|
start: () => -1,
|
|
63281
64127
|
tokenize: (src, _tokens, lexer) => {
|
|
63282
64128
|
var _listItems$, _listItems$2;
|
|
63283
|
-
const lines = src
|
|
63284
|
-
const [listItems, consumed] = collectOrderedListItems(lines);
|
|
64129
|
+
const [listItems, consumed, lines] = collectOrderedListItemsFromSource(src);
|
|
63285
64130
|
if (listItems.length === 0) return;
|
|
63286
64131
|
const items = buildNestedStructure(listItems, listItems[0].indent, lexer);
|
|
63287
64132
|
if (items.length === 0) return;
|
|
@@ -66054,1026 +66899,412 @@ img.ProseMirror-separator {
|
|
|
66054
66899
|
* This extension allows you to create text nodes.
|
|
66055
66900
|
* @see https://www.tiptap.dev/api/nodes/text
|
|
66056
66901
|
*/
|
|
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
|
-
}
|
|
66902
|
+
const Text = Node$1.create({
|
|
66903
|
+
name: "text",
|
|
66904
|
+
group: "inline",
|
|
66905
|
+
parseMarkdown: (token) => {
|
|
66906
|
+
return {
|
|
66907
|
+
type: "text",
|
|
66908
|
+
text: token.text || ""
|
|
66909
|
+
};
|
|
66910
|
+
},
|
|
66911
|
+
renderMarkdown: (node) => node.text || ""
|
|
66912
|
+
});
|
|
66913
|
+
//#endregion
|
|
66914
|
+
//#region src/index.ts
|
|
66915
|
+
var src_default = Text;
|
|
66376
66916
|
|
|
66377
66917
|
/**
|
|
66378
|
-
Create a
|
|
66379
|
-
|
|
66380
|
-
|
|
66381
|
-
|
|
66382
|
-
`
|
|
66383
|
-
|
|
66384
|
-
|
|
66918
|
+
Create a plugin that, when added to a ProseMirror instance,
|
|
66919
|
+
causes a decoration to show up at the drop position when something
|
|
66920
|
+
is dragged over the editor.
|
|
66921
|
+
|
|
66922
|
+
Nodes may add a `disableDropCursor` property to their spec to
|
|
66923
|
+
control the showing of a drop cursor inside them. This may be a
|
|
66924
|
+
boolean or a function, which will be called with a view and a
|
|
66925
|
+
position, and should return a boolean.
|
|
66385
66926
|
*/
|
|
66386
|
-
function
|
|
66927
|
+
function dropCursor(options = {}) {
|
|
66387
66928
|
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
|
-
}
|
|
66929
|
+
view(editorView) { return new DropCursorView(editorView, options); }
|
|
66397
66930
|
});
|
|
66398
66931
|
}
|
|
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;
|
|
66932
|
+
class DropCursorView {
|
|
66933
|
+
constructor(editorView, options) {
|
|
66934
|
+
var _a;
|
|
66935
|
+
this.editorView = editorView;
|
|
66936
|
+
this.cursorPos = null;
|
|
66937
|
+
this.element = null;
|
|
66938
|
+
this.timeout = -1;
|
|
66939
|
+
this.lastDragEvent = null;
|
|
66940
|
+
this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1;
|
|
66941
|
+
this.color = options.color === false ? undefined : (options.color || "black");
|
|
66942
|
+
this.class = options.class;
|
|
66943
|
+
this.handlers = ["dragover", "dragend", "drop", "dragleave"].map(name => {
|
|
66944
|
+
let handler = (e) => { this[name](e); };
|
|
66945
|
+
editorView.dom.addEventListener(name, handler);
|
|
66946
|
+
return { name, handler };
|
|
66947
|
+
});
|
|
66826
66948
|
}
|
|
66827
|
-
|
|
66828
|
-
|
|
66829
|
-
this.
|
|
66830
|
-
count++; });
|
|
66831
|
-
return count;
|
|
66949
|
+
destroy() {
|
|
66950
|
+
this.setCursor(null);
|
|
66951
|
+
this.handlers.forEach(({ name, handler }) => this.editorView.dom.removeEventListener(name, handler));
|
|
66832
66952
|
}
|
|
66833
|
-
|
|
66834
|
-
|
|
66835
|
-
|
|
66836
|
-
|
|
66837
|
-
|
|
66838
|
-
|
|
66839
|
-
|
|
66840
|
-
|
|
66841
|
-
|
|
66842
|
-
|
|
66843
|
-
if (i >= upto) {
|
|
66844
|
-
items.push(item);
|
|
66845
|
-
if (item.selection)
|
|
66846
|
-
events++;
|
|
66953
|
+
update(editorView, prevState) {
|
|
66954
|
+
if (this.cursorPos != null && prevState.doc != editorView.state.doc) {
|
|
66955
|
+
// if we currently have an on-going drag event
|
|
66956
|
+
// we need to update the cursor position again and update the overlay
|
|
66957
|
+
if (this.lastDragEvent) {
|
|
66958
|
+
let target = this.computeTarget(this.lastDragEvent);
|
|
66959
|
+
if (target == this.cursorPos)
|
|
66960
|
+
this.updateOverlay();
|
|
66961
|
+
else
|
|
66962
|
+
this.setCursor(target);
|
|
66847
66963
|
}
|
|
66848
|
-
else
|
|
66849
|
-
|
|
66850
|
-
|
|
66851
|
-
|
|
66852
|
-
|
|
66853
|
-
|
|
66854
|
-
|
|
66855
|
-
|
|
66856
|
-
|
|
66857
|
-
|
|
66858
|
-
|
|
66859
|
-
|
|
66860
|
-
|
|
66861
|
-
|
|
66964
|
+
else {
|
|
66965
|
+
this.updateOverlay();
|
|
66966
|
+
}
|
|
66967
|
+
}
|
|
66968
|
+
}
|
|
66969
|
+
setCursor(pos) {
|
|
66970
|
+
if (pos == this.cursorPos)
|
|
66971
|
+
return;
|
|
66972
|
+
this.cursorPos = pos;
|
|
66973
|
+
if (pos == null) {
|
|
66974
|
+
this.element.parentNode.removeChild(this.element);
|
|
66975
|
+
this.element = null;
|
|
66976
|
+
}
|
|
66977
|
+
else {
|
|
66978
|
+
this.updateOverlay();
|
|
66979
|
+
}
|
|
66980
|
+
}
|
|
66981
|
+
updateOverlay() {
|
|
66982
|
+
let $pos = this.editorView.state.doc.resolve(this.cursorPos);
|
|
66983
|
+
let isBlock = !$pos.parent.inlineContent, rect;
|
|
66984
|
+
let editorDOM = this.editorView.dom, editorRect = editorDOM.getBoundingClientRect();
|
|
66985
|
+
let scaleX = editorRect.width / editorDOM.offsetWidth, scaleY = editorRect.height / editorDOM.offsetHeight;
|
|
66986
|
+
if (isBlock) {
|
|
66987
|
+
let before = $pos.nodeBefore, after = $pos.nodeAfter;
|
|
66988
|
+
if (before || after) {
|
|
66989
|
+
let node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0));
|
|
66990
|
+
if (node) {
|
|
66991
|
+
let nodeRect = node.getBoundingClientRect();
|
|
66992
|
+
let top = before ? nodeRect.bottom : nodeRect.top;
|
|
66993
|
+
if (before && after)
|
|
66994
|
+
top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2;
|
|
66995
|
+
let halfWidth = (this.width / 2) * scaleY;
|
|
66996
|
+
rect = { left: nodeRect.left, right: nodeRect.right, top: top - halfWidth, bottom: top + halfWidth };
|
|
66862
66997
|
}
|
|
66863
66998
|
}
|
|
66864
|
-
|
|
66865
|
-
|
|
66999
|
+
}
|
|
67000
|
+
if (!rect) {
|
|
67001
|
+
let coords = this.editorView.coordsAtPos(this.cursorPos);
|
|
67002
|
+
let halfWidth = (this.width / 2) * scaleX;
|
|
67003
|
+
rect = { left: coords.left - halfWidth, right: coords.left + halfWidth, top: coords.top, bottom: coords.bottom };
|
|
67004
|
+
}
|
|
67005
|
+
let parent = this.editorView.dom.offsetParent;
|
|
67006
|
+
if (!this.element) {
|
|
67007
|
+
this.element = parent.appendChild(document.createElement("div"));
|
|
67008
|
+
if (this.class)
|
|
67009
|
+
this.element.className = this.class;
|
|
67010
|
+
this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;";
|
|
67011
|
+
if (this.color) {
|
|
67012
|
+
this.element.style.backgroundColor = this.color;
|
|
66866
67013
|
}
|
|
66867
|
-
}
|
|
66868
|
-
|
|
67014
|
+
}
|
|
67015
|
+
this.element.classList.toggle("prosemirror-dropcursor-block", isBlock);
|
|
67016
|
+
this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock);
|
|
67017
|
+
let parentLeft, parentTop;
|
|
67018
|
+
if (!parent || parent == document.body && getComputedStyle(parent).position == "static") {
|
|
67019
|
+
parentLeft = -pageXOffset;
|
|
67020
|
+
parentTop = -pageYOffset;
|
|
67021
|
+
}
|
|
67022
|
+
else {
|
|
67023
|
+
let rect = parent.getBoundingClientRect();
|
|
67024
|
+
let parentScaleX = rect.width / parent.offsetWidth, parentScaleY = rect.height / parent.offsetHeight;
|
|
67025
|
+
parentLeft = rect.left - parent.scrollLeft * parentScaleX;
|
|
67026
|
+
parentTop = rect.top - parent.scrollTop * parentScaleY;
|
|
67027
|
+
}
|
|
67028
|
+
this.element.style.left = (rect.left - parentLeft) / scaleX + "px";
|
|
67029
|
+
this.element.style.top = (rect.top - parentTop) / scaleY + "px";
|
|
67030
|
+
this.element.style.width = (rect.right - rect.left) / scaleX + "px";
|
|
67031
|
+
this.element.style.height = (rect.bottom - rect.top) / scaleY + "px";
|
|
66869
67032
|
}
|
|
66870
|
-
|
|
66871
|
-
|
|
66872
|
-
|
|
66873
|
-
|
|
66874
|
-
|
|
66875
|
-
|
|
66876
|
-
|
|
66877
|
-
|
|
67033
|
+
scheduleRemoval(timeout) {
|
|
67034
|
+
clearTimeout(this.timeout);
|
|
67035
|
+
this.timeout = setTimeout(() => this.setCursor(null), timeout);
|
|
67036
|
+
}
|
|
67037
|
+
computeTarget(event) {
|
|
67038
|
+
let pos = this.editorView.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
67039
|
+
let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);
|
|
67040
|
+
let disableDropCursor = node && node.type.spec.disableDropCursor;
|
|
67041
|
+
let disabled = typeof disableDropCursor == "function"
|
|
67042
|
+
? disableDropCursor(this.editorView, pos, event)
|
|
67043
|
+
: disableDropCursor;
|
|
67044
|
+
if (!pos || disabled)
|
|
67045
|
+
return null;
|
|
67046
|
+
let target = pos.pos;
|
|
67047
|
+
if (this.editorView.dragging && this.editorView.dragging.slice) {
|
|
67048
|
+
let point = dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice);
|
|
67049
|
+
if (point != null)
|
|
67050
|
+
target = point;
|
|
66878
67051
|
}
|
|
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;
|
|
67052
|
+
return target;
|
|
66899
67053
|
}
|
|
66900
|
-
|
|
66901
|
-
if (this.
|
|
66902
|
-
|
|
66903
|
-
|
|
66904
|
-
|
|
67054
|
+
dragover(event) {
|
|
67055
|
+
if (!this.editorView.editable)
|
|
67056
|
+
return;
|
|
67057
|
+
this.lastDragEvent = event;
|
|
67058
|
+
let target = this.computeTarget(event);
|
|
67059
|
+
if (target != null) {
|
|
67060
|
+
this.setCursor(target);
|
|
67061
|
+
this.scheduleRemoval(5000);
|
|
66905
67062
|
}
|
|
66906
67063
|
}
|
|
66907
|
-
|
|
66908
|
-
|
|
66909
|
-
|
|
66910
|
-
|
|
66911
|
-
|
|
66912
|
-
|
|
66913
|
-
|
|
66914
|
-
this.
|
|
66915
|
-
|
|
66916
|
-
this.prevTime = prevTime;
|
|
66917
|
-
this.prevComposition = prevComposition;
|
|
67064
|
+
dragend() {
|
|
67065
|
+
this.scheduleRemoval(20);
|
|
67066
|
+
}
|
|
67067
|
+
drop() {
|
|
67068
|
+
this.scheduleRemoval(20);
|
|
67069
|
+
}
|
|
67070
|
+
dragleave(event) {
|
|
67071
|
+
if (!this.editorView.dom.contains(event.relatedTarget))
|
|
67072
|
+
this.setCursor(null);
|
|
66918
67073
|
}
|
|
66919
67074
|
}
|
|
66920
|
-
|
|
66921
|
-
|
|
66922
|
-
|
|
66923
|
-
|
|
66924
|
-
|
|
66925
|
-
|
|
66926
|
-
|
|
66927
|
-
|
|
66928
|
-
|
|
66929
|
-
|
|
66930
|
-
|
|
67075
|
+
|
|
67076
|
+
/**
|
|
67077
|
+
Gap cursor selections are represented using this class. Its
|
|
67078
|
+
`$anchor` and `$head` properties both point at the cursor position.
|
|
67079
|
+
*/
|
|
67080
|
+
class GapCursor extends Selection$2 {
|
|
67081
|
+
/**
|
|
67082
|
+
Create a gap cursor.
|
|
67083
|
+
*/
|
|
67084
|
+
constructor($pos) {
|
|
67085
|
+
super($pos, $pos);
|
|
66931
67086
|
}
|
|
66932
|
-
|
|
66933
|
-
|
|
66934
|
-
|
|
66935
|
-
else
|
|
66936
|
-
return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);
|
|
67087
|
+
map(doc, mapping) {
|
|
67088
|
+
let $pos = doc.resolve(mapping.map(this.head));
|
|
67089
|
+
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$2.near($pos);
|
|
66937
67090
|
}
|
|
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);
|
|
67091
|
+
content() { return Slice.empty; }
|
|
67092
|
+
eq(other) {
|
|
67093
|
+
return other instanceof GapCursor && other.head == this.head;
|
|
66946
67094
|
}
|
|
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);
|
|
67095
|
+
toJSON() {
|
|
67096
|
+
return { type: "gapcursor", pos: this.head };
|
|
66951
67097
|
}
|
|
66952
|
-
|
|
66953
|
-
|
|
67098
|
+
/**
|
|
67099
|
+
@internal
|
|
67100
|
+
*/
|
|
67101
|
+
static fromJSON(doc, json) {
|
|
67102
|
+
if (typeof json.pos != "number")
|
|
67103
|
+
throw new RangeError("Invalid input for GapCursor.fromJSON");
|
|
67104
|
+
return new GapCursor(doc.resolve(json.pos));
|
|
67105
|
+
}
|
|
67106
|
+
/**
|
|
67107
|
+
@internal
|
|
67108
|
+
*/
|
|
67109
|
+
getBookmark() { return new GapBookmark(this.anchor); }
|
|
67110
|
+
/**
|
|
67111
|
+
@internal
|
|
67112
|
+
*/
|
|
67113
|
+
static valid($pos) {
|
|
67114
|
+
let parent = $pos.parent;
|
|
67115
|
+
if (parent.inlineContent || !closedBefore($pos) || !closedAfter($pos))
|
|
67116
|
+
return false;
|
|
67117
|
+
let override = parent.type.spec.allowGapCursor;
|
|
67118
|
+
if (override != null)
|
|
67119
|
+
return override;
|
|
67120
|
+
let deflt = parent.contentMatchAt($pos.index()).defaultType;
|
|
67121
|
+
return deflt && deflt.isTextblock;
|
|
67122
|
+
}
|
|
67123
|
+
/**
|
|
67124
|
+
@internal
|
|
67125
|
+
*/
|
|
67126
|
+
static findGapCursorFrom($pos, dir, mustMove = false) {
|
|
67127
|
+
search: for (;;) {
|
|
67128
|
+
if (!mustMove && GapCursor.valid($pos))
|
|
67129
|
+
return $pos;
|
|
67130
|
+
let pos = $pos.pos, next = null;
|
|
67131
|
+
// Scan up from this position
|
|
67132
|
+
for (let d = $pos.depth;; d--) {
|
|
67133
|
+
let parent = $pos.node(d);
|
|
67134
|
+
if (dir > 0 ? $pos.indexAfter(d) < parent.childCount : $pos.index(d) > 0) {
|
|
67135
|
+
next = parent.child(dir > 0 ? $pos.indexAfter(d) : $pos.index(d) - 1);
|
|
67136
|
+
break;
|
|
67137
|
+
}
|
|
67138
|
+
else if (d == 0) {
|
|
67139
|
+
return null;
|
|
67140
|
+
}
|
|
67141
|
+
pos += dir;
|
|
67142
|
+
let $cur = $pos.doc.resolve(pos);
|
|
67143
|
+
if (GapCursor.valid($cur))
|
|
67144
|
+
return $cur;
|
|
67145
|
+
}
|
|
67146
|
+
// And then down into the next node
|
|
67147
|
+
for (;;) {
|
|
67148
|
+
let inside = dir > 0 ? next.firstChild : next.lastChild;
|
|
67149
|
+
if (!inside) {
|
|
67150
|
+
if (next.isAtom && !next.isText && !NodeSelection.isSelectable(next)) {
|
|
67151
|
+
$pos = $pos.doc.resolve(pos + next.nodeSize * dir);
|
|
67152
|
+
mustMove = false;
|
|
67153
|
+
continue search;
|
|
67154
|
+
}
|
|
67155
|
+
break;
|
|
67156
|
+
}
|
|
67157
|
+
next = inside;
|
|
67158
|
+
pos += dir;
|
|
67159
|
+
let $cur = $pos.doc.resolve(pos);
|
|
67160
|
+
if (GapCursor.valid($cur))
|
|
67161
|
+
return $cur;
|
|
67162
|
+
}
|
|
67163
|
+
return null;
|
|
67164
|
+
}
|
|
66954
67165
|
}
|
|
66955
67166
|
}
|
|
66956
|
-
|
|
66957
|
-
|
|
66958
|
-
|
|
66959
|
-
|
|
66960
|
-
|
|
66961
|
-
|
|
66962
|
-
|
|
66963
|
-
|
|
66964
|
-
|
|
66965
|
-
|
|
66966
|
-
|
|
66967
|
-
|
|
67167
|
+
GapCursor.prototype.visible = false;
|
|
67168
|
+
GapCursor.findFrom = GapCursor.findGapCursorFrom;
|
|
67169
|
+
Selection$2.jsonID("gapcursor", GapCursor);
|
|
67170
|
+
class GapBookmark {
|
|
67171
|
+
constructor(pos) {
|
|
67172
|
+
this.pos = pos;
|
|
67173
|
+
}
|
|
67174
|
+
map(mapping) {
|
|
67175
|
+
return new GapBookmark(mapping.map(this.pos));
|
|
67176
|
+
}
|
|
67177
|
+
resolve(doc) {
|
|
67178
|
+
let $pos = doc.resolve(this.pos);
|
|
67179
|
+
return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$2.near($pos);
|
|
67180
|
+
}
|
|
66968
67181
|
}
|
|
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;
|
|
67182
|
+
function needsGap(type) {
|
|
67183
|
+
return type.isAtom || type.spec.isolating || type.spec.createGapCursor;
|
|
66974
67184
|
}
|
|
66975
|
-
function
|
|
66976
|
-
|
|
66977
|
-
|
|
66978
|
-
|
|
66979
|
-
|
|
66980
|
-
|
|
66981
|
-
|
|
66982
|
-
|
|
67185
|
+
function closedBefore($pos) {
|
|
67186
|
+
for (let d = $pos.depth; d >= 0; d--) {
|
|
67187
|
+
let index = $pos.index(d), parent = $pos.node(d);
|
|
67188
|
+
// At the start of this parent, look at next one
|
|
67189
|
+
if (index == 0) {
|
|
67190
|
+
if (parent.type.spec.isolating)
|
|
67191
|
+
return true;
|
|
67192
|
+
continue;
|
|
67193
|
+
}
|
|
67194
|
+
// See if the node before (or its first ancestor) is closed
|
|
67195
|
+
for (let before = parent.child(index - 1);; before = before.lastChild) {
|
|
67196
|
+
if ((before.childCount == 0 && !before.inlineContent) || needsGap(before.type))
|
|
67197
|
+
return true;
|
|
67198
|
+
if (before.inlineContent)
|
|
67199
|
+
return false;
|
|
67200
|
+
}
|
|
66983
67201
|
}
|
|
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 });
|
|
67202
|
+
// Hit start of document
|
|
67203
|
+
return true;
|
|
66998
67204
|
}
|
|
66999
|
-
|
|
67000
|
-
|
|
67001
|
-
|
|
67002
|
-
|
|
67003
|
-
|
|
67004
|
-
|
|
67005
|
-
|
|
67006
|
-
|
|
67007
|
-
|
|
67008
|
-
|
|
67009
|
-
|
|
67010
|
-
if (
|
|
67011
|
-
|
|
67012
|
-
|
|
67013
|
-
}
|
|
67205
|
+
function closedAfter($pos) {
|
|
67206
|
+
for (let d = $pos.depth; d >= 0; d--) {
|
|
67207
|
+
let index = $pos.indexAfter(d), parent = $pos.node(d);
|
|
67208
|
+
if (index == parent.childCount) {
|
|
67209
|
+
if (parent.type.spec.isolating)
|
|
67210
|
+
return true;
|
|
67211
|
+
continue;
|
|
67212
|
+
}
|
|
67213
|
+
for (let after = parent.child(index);; after = after.firstChild) {
|
|
67214
|
+
if ((after.childCount == 0 && !after.inlineContent) || needsGap(after.type))
|
|
67215
|
+
return true;
|
|
67216
|
+
if (after.inlineContent)
|
|
67217
|
+
return false;
|
|
67218
|
+
}
|
|
67014
67219
|
}
|
|
67015
|
-
return
|
|
67220
|
+
return true;
|
|
67016
67221
|
}
|
|
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
67222
|
|
|
67024
|
-
|
|
67025
|
-
|
|
67026
|
-
|
|
67223
|
+
/**
|
|
67224
|
+
Create a gap cursor plugin. When enabled, this will capture clicks
|
|
67225
|
+
near and arrow-key-motion past places that don't have a normally
|
|
67226
|
+
selectable position nearby, and create a gap cursor selection for
|
|
67227
|
+
them. The cursor is drawn as an element with class
|
|
67228
|
+
`ProseMirror-gapcursor`. You can either include
|
|
67229
|
+
`style/gapcursor.css` from the package's directory or add your own
|
|
67230
|
+
styles to make it visible.
|
|
67027
67231
|
*/
|
|
67028
|
-
function
|
|
67029
|
-
config = { depth: config.depth || 100,
|
|
67030
|
-
newGroupDelay: config.newGroupDelay || 500 };
|
|
67232
|
+
function gapCursor() {
|
|
67031
67233
|
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
67234
|
props: {
|
|
67043
|
-
|
|
67044
|
-
|
|
67045
|
-
|
|
67046
|
-
|
|
67047
|
-
|
|
67048
|
-
|
|
67049
|
-
|
|
67050
|
-
return command(view.state, view.dispatch);
|
|
67051
|
-
}
|
|
67052
|
-
}
|
|
67235
|
+
decorations: drawGapCursor,
|
|
67236
|
+
createSelectionBetween(_view, $anchor, $head) {
|
|
67237
|
+
return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null;
|
|
67238
|
+
},
|
|
67239
|
+
handleClick,
|
|
67240
|
+
handleKeyDown,
|
|
67241
|
+
handleDOMEvents: { beforeinput: beforeinput }
|
|
67053
67242
|
}
|
|
67054
67243
|
});
|
|
67055
67244
|
}
|
|
67056
|
-
|
|
67057
|
-
|
|
67058
|
-
|
|
67059
|
-
|
|
67060
|
-
|
|
67061
|
-
|
|
67062
|
-
|
|
67063
|
-
|
|
67064
|
-
|
|
67245
|
+
const handleKeyDown = keydownHandler({
|
|
67246
|
+
"ArrowLeft": arrow("horiz", -1),
|
|
67247
|
+
"ArrowRight": arrow("horiz", 1),
|
|
67248
|
+
"ArrowUp": arrow("vert", -1),
|
|
67249
|
+
"ArrowDown": arrow("vert", 1)
|
|
67250
|
+
});
|
|
67251
|
+
function arrow(axis, dir) {
|
|
67252
|
+
const dirStr = axis == "vert" ? (dir > 0 ? "down" : "up") : (dir > 0 ? "right" : "left");
|
|
67253
|
+
return function (state, dispatch, view) {
|
|
67254
|
+
let sel = state.selection;
|
|
67255
|
+
let $start = dir > 0 ? sel.$to : sel.$from, mustMove = sel.empty;
|
|
67256
|
+
if (sel instanceof TextSelection) {
|
|
67257
|
+
if (!view.endOfTextblock(dirStr) || $start.depth == 0)
|
|
67258
|
+
return false;
|
|
67259
|
+
mustMove = false;
|
|
67260
|
+
$start = state.doc.resolve(dir > 0 ? $start.after() : $start.before());
|
|
67065
67261
|
}
|
|
67262
|
+
let $found = GapCursor.findGapCursorFrom($start, dir, mustMove);
|
|
67263
|
+
if (!$found)
|
|
67264
|
+
return false;
|
|
67265
|
+
if (dispatch)
|
|
67266
|
+
dispatch(state.tr.setSelection(new GapCursor($found)));
|
|
67066
67267
|
return true;
|
|
67067
67268
|
};
|
|
67068
67269
|
}
|
|
67069
|
-
|
|
67070
|
-
|
|
67071
|
-
|
|
67072
|
-
|
|
67073
|
-
|
|
67074
|
-
|
|
67075
|
-
|
|
67076
|
-
|
|
67270
|
+
function handleClick(view, pos, event) {
|
|
67271
|
+
if (!view || !view.editable)
|
|
67272
|
+
return false;
|
|
67273
|
+
let $pos = view.state.doc.resolve(pos);
|
|
67274
|
+
if (!GapCursor.valid($pos))
|
|
67275
|
+
return false;
|
|
67276
|
+
let clickPos = view.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
67277
|
+
if (clickPos && clickPos.inside > -1 && NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside)))
|
|
67278
|
+
return false;
|
|
67279
|
+
view.dispatch(view.state.tr.setSelection(new GapCursor($pos)));
|
|
67280
|
+
return true;
|
|
67281
|
+
}
|
|
67282
|
+
// This is a hack that, when a composition starts while a gap cursor
|
|
67283
|
+
// is active, quickly creates an inline context for the composition to
|
|
67284
|
+
// happen in, to avoid it being aborted by the DOM selection being
|
|
67285
|
+
// moved into a valid position.
|
|
67286
|
+
function beforeinput(view, event) {
|
|
67287
|
+
if (event.inputType != "insertCompositionText" || !(view.state.selection instanceof GapCursor))
|
|
67288
|
+
return false;
|
|
67289
|
+
let { $from } = view.state.selection;
|
|
67290
|
+
let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text);
|
|
67291
|
+
if (!insert)
|
|
67292
|
+
return false;
|
|
67293
|
+
let frag = Fragment.empty;
|
|
67294
|
+
for (let i = insert.length - 1; i >= 0; i--)
|
|
67295
|
+
frag = Fragment.from(insert[i].createAndFill(null, frag));
|
|
67296
|
+
let tr = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0));
|
|
67297
|
+
tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + 1)));
|
|
67298
|
+
view.dispatch(tr);
|
|
67299
|
+
return false;
|
|
67300
|
+
}
|
|
67301
|
+
function drawGapCursor(state) {
|
|
67302
|
+
if (!(state.selection instanceof GapCursor))
|
|
67303
|
+
return null;
|
|
67304
|
+
let node = document.createElement("div");
|
|
67305
|
+
node.className = "ProseMirror-gapcursor";
|
|
67306
|
+
return DecorationSet.create(state.doc, [Decoration.widget(state.selection.head, node, { key: "gapcursor" })]);
|
|
67307
|
+
}
|
|
67077
67308
|
|
|
67078
67309
|
//#region src/character-count/character-count.ts
|
|
67079
67310
|
/**
|
|
@@ -97669,12 +97900,12 @@ focus outline in that case.
|
|
|
97669
97900
|
toDOMStream(options) {
|
|
97670
97901
|
return streamAdapters.toDOMStream((this._closedPromiseResolve || this._error)
|
|
97671
97902
|
? this
|
|
97672
|
-
: this._values
|
|
97903
|
+
: this._values);
|
|
97673
97904
|
}
|
|
97674
97905
|
toNodeStream(options) {
|
|
97675
97906
|
return streamAdapters.toNodeStream((this._closedPromiseResolve || this._error)
|
|
97676
97907
|
? this
|
|
97677
|
-
: this._values
|
|
97908
|
+
: this._values);
|
|
97678
97909
|
}
|
|
97679
97910
|
throw(_) {
|
|
97680
97911
|
return __awaiter(this, void 0, void 0, function* () { yield this.abort(_); return ITERATOR_DONE; });
|
|
@@ -100065,7 +100296,7 @@ focus outline in that case.
|
|
|
100065
100296
|
toNodeStream() {
|
|
100066
100297
|
return streamAdapters.toNodeStream((this.isSync()
|
|
100067
100298
|
? { [Symbol.iterator]: () => this }
|
|
100068
|
-
: { [Symbol.asyncIterator]: () => this })
|
|
100299
|
+
: { [Symbol.asyncIterator]: () => this }));
|
|
100069
100300
|
}
|
|
100070
100301
|
/** @nocollapse */
|
|
100071
100302
|
// @ts-ignore
|
|
@@ -106734,15 +106965,17 @@ focus outline in that case.
|
|
|
106734
106965
|
id="${(_, c) => `${c.parent.menuId}-option-${c.index}`}"
|
|
106735
106966
|
class="chip-selector-option"
|
|
106736
106967
|
data-option-value="${x => x}"
|
|
106968
|
+
aria-selected="${(_, c) => String(c.index === c.parent.activeOptionIndex)}"
|
|
106737
106969
|
>
|
|
106738
106970
|
${x => x}
|
|
106739
106971
|
</${menuItemTag}>
|
|
106740
|
-
|
|
106972
|
+
`, { positioning: true })}
|
|
106741
106973
|
${when(x => x.customValueCandidate.length > 0, html `
|
|
106742
106974
|
<${menuItemTag}
|
|
106743
106975
|
id="${x => `${x.menuId}-option-create`}"
|
|
106744
106976
|
class="chip-selector-option chip-selector-create-option"
|
|
106745
106977
|
data-option-value="${x => x.customValueCandidate}"
|
|
106978
|
+
aria-selected="${x => String(x.activeOptionIndex === x.visibleOptionList.length)}"
|
|
106746
106979
|
>
|
|
106747
106980
|
${x => x.createOptionLabel}
|
|
106748
106981
|
</${menuItemTag}>
|
|
@@ -107007,10 +107240,6 @@ focus outline in that case.
|
|
|
107007
107240
|
}
|
|
107008
107241
|
}
|
|
107009
107242
|
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
107243
|
if (this.activeOptionIndex < 0) {
|
|
107015
107244
|
this.activeOptionId = null;
|
|
107016
107245
|
}
|