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