@sqx717/element-tiptap-vue3-fixed
Version:
🌸A modern WYSIWYG rich-text editor using tiptap and Element Plus for Vue3
1,554 lines • 1.66 MB
JavaScript
import { defineComponent, ref, onMounted, onBeforeUnmount, h, markRaw, getCurrentInstance, watchEffect, nextTick, unref, shallowRef, customRef, reactive, render as render$G, provide, computed, watch, inject, openBlock, createElementBlock, Fragment as Fragment$1, renderList, createBlock, resolveDynamicComponent, mergeProps, toHandlers, defineAsyncComponent, readonly, getCurrentScope, onScopeDispose, isRef, warn as warn$2, renderSlot, createElementVNode, toRef, onUnmounted, useAttrs as useAttrs$1, useSlots, normalizeClass, normalizeStyle, createCommentVNode, withCtx, withModifiers, createVNode, toDisplayString, Transition, withDirectives, vShow, onActivated, onUpdated, cloneVNode, Text as Text$2, Comment, Teleport as Teleport$1, onBeforeMount, onDeactivated, toRaw, vModelCheckbox, createTextVNode, toRefs, createSlots, resolveComponent, normalizeProps, guardReactiveProps, TransitionGroup, withKeys, createApp, isVNode, createStaticVNode } from "vue";
function OrderedMap(content) {
this.content = content;
}
OrderedMap.prototype = {
constructor: OrderedMap,
find: function(key) {
for (var i = 0; i < this.content.length; i += 2)
if (this.content[i] === key)
return i;
return -1;
},
get: function(key) {
var found2 = this.find(key);
return found2 == -1 ? void 0 : this.content[found2 + 1];
},
update: function(key, value, newKey) {
var self2 = newKey && newKey != key ? this.remove(newKey) : this;
var found2 = self2.find(key), content = self2.content.slice();
if (found2 == -1) {
content.push(newKey || key, value);
} else {
content[found2 + 1] = value;
if (newKey)
content[found2] = newKey;
}
return new OrderedMap(content);
},
remove: function(key) {
var found2 = this.find(key);
if (found2 == -1)
return this;
var content = this.content.slice();
content.splice(found2, 2);
return new OrderedMap(content);
},
addToStart: function(key, value) {
return new OrderedMap([key, value].concat(this.remove(key).content));
},
addToEnd: function(key, value) {
var content = this.remove(key).content.slice();
content.push(key, value);
return new OrderedMap(content);
},
addBefore: function(place, key, value) {
var without = this.remove(key), content = without.content.slice();
var found2 = without.find(place);
content.splice(found2 == -1 ? content.length : found2, 0, key, value);
return new OrderedMap(content);
},
forEach: function(f) {
for (var i = 0; i < this.content.length; i += 2)
f(this.content[i], this.content[i + 1]);
},
prepend: function(map2) {
map2 = OrderedMap.from(map2);
if (!map2.size)
return this;
return new OrderedMap(map2.content.concat(this.subtract(map2).content));
},
append: function(map2) {
map2 = OrderedMap.from(map2);
if (!map2.size)
return this;
return new OrderedMap(this.subtract(map2).content.concat(map2.content));
},
subtract: function(map2) {
var result = this;
map2 = OrderedMap.from(map2);
for (var i = 0; i < map2.content.length; i += 2)
result = result.remove(map2.content[i]);
return result;
},
toObject: function() {
var result = {};
this.forEach(function(key, value) {
result[key] = value;
});
return result;
},
get size() {
return this.content.length >> 1;
}
};
OrderedMap.from = function(value) {
if (value instanceof OrderedMap)
return value;
var content = [];
if (value)
for (var prop in value)
content.push(prop, value[prop]);
return new OrderedMap(content);
};
function findDiffStart(a, b, pos) {
for (let i = 0; ; i++) {
if (i == a.childCount || i == b.childCount)
return a.childCount == b.childCount ? null : pos;
let childA = a.child(i), childB = b.child(i);
if (childA == childB) {
pos += childA.nodeSize;
continue;
}
if (!childA.sameMarkup(childB))
return pos;
if (childA.isText && childA.text != childB.text) {
for (let j = 0; childA.text[j] == childB.text[j]; j++)
pos++;
return pos;
}
if (childA.content.size || childB.content.size) {
let inner = findDiffStart(childA.content, childB.content, pos + 1);
if (inner != null)
return inner;
}
pos += childA.nodeSize;
}
}
function findDiffEnd(a, b, posA, posB) {
for (let iA = a.childCount, iB = b.childCount; ; ) {
if (iA == 0 || iB == 0)
return iA == iB ? null : { a: posA, b: posB };
let childA = a.child(--iA), childB = b.child(--iB), size2 = childA.nodeSize;
if (childA == childB) {
posA -= size2;
posB -= size2;
continue;
}
if (!childA.sameMarkup(childB))
return { a: posA, b: posB };
if (childA.isText && childA.text != childB.text) {
let same = 0, minSize = Math.min(childA.text.length, childB.text.length);
while (same < minSize && childA.text[childA.text.length - same - 1] == childB.text[childB.text.length - same - 1]) {
same++;
posA--;
posB--;
}
return { a: posA, b: posB };
}
if (childA.content.size || childB.content.size) {
let inner = findDiffEnd(childA.content, childB.content, posA - 1, posB - 1);
if (inner)
return inner;
}
posA -= size2;
posB -= size2;
}
}
class Fragment {
constructor(content, size2) {
this.content = content;
this.size = size2 || 0;
if (size2 == null)
for (let i = 0; i < content.length; i++)
this.size += content[i].nodeSize;
}
nodesBetween(from2, to, f, nodeStart = 0, parent) {
for (let i = 0, pos = 0; pos < to; i++) {
let child = this.content[i], end2 = pos + child.nodeSize;
if (end2 > from2 && f(child, nodeStart + pos, parent || null, i) !== false && child.content.size) {
let start2 = pos + 1;
child.nodesBetween(Math.max(0, from2 - start2), Math.min(child.content.size, to - start2), f, nodeStart + start2);
}
pos = end2;
}
}
descendants(f) {
this.nodesBetween(0, this.size, f);
}
textBetween(from2, to, blockSeparator, leafText) {
let text = "", first2 = true;
this.nodesBetween(from2, to, (node, pos) => {
let nodeText = node.isText ? node.text.slice(Math.max(from2, pos) - pos, to - pos) : !node.isLeaf ? "" : leafText ? typeof leafText === "function" ? leafText(node) : leafText : node.type.spec.leafText ? node.type.spec.leafText(node) : "";
if (node.isBlock && (node.isLeaf && nodeText || node.isTextblock) && blockSeparator) {
if (first2)
first2 = false;
else
text += blockSeparator;
}
text += nodeText;
}, 0);
return text;
}
append(other) {
if (!other.size)
return this;
if (!this.size)
return other;
let last = this.lastChild, first2 = other.firstChild, content = this.content.slice(), i = 0;
if (last.isText && last.sameMarkup(first2)) {
content[content.length - 1] = last.withText(last.text + first2.text);
i = 1;
}
for (; i < other.content.length; i++)
content.push(other.content[i]);
return new Fragment(content, this.size + other.size);
}
cut(from2, to = this.size) {
if (from2 == 0 && to == this.size)
return this;
let result = [], size2 = 0;
if (to > from2)
for (let i = 0, pos = 0; pos < to; i++) {
let child = this.content[i], end2 = pos + child.nodeSize;
if (end2 > from2) {
if (pos < from2 || end2 > to) {
if (child.isText)
child = child.cut(Math.max(0, from2 - pos), Math.min(child.text.length, to - pos));
else
child = child.cut(Math.max(0, from2 - pos - 1), Math.min(child.content.size, to - pos - 1));
}
result.push(child);
size2 += child.nodeSize;
}
pos = end2;
}
return new Fragment(result, size2);
}
cutByIndex(from2, to) {
if (from2 == to)
return Fragment.empty;
if (from2 == 0 && to == this.content.length)
return this;
return new Fragment(this.content.slice(from2, to));
}
replaceChild(index, node) {
let current = this.content[index];
if (current == node)
return this;
let copy2 = this.content.slice();
let size2 = this.size + node.nodeSize - current.nodeSize;
copy2[index] = node;
return new Fragment(copy2, size2);
}
addToStart(node) {
return new Fragment([node].concat(this.content), this.size + node.nodeSize);
}
addToEnd(node) {
return new Fragment(this.content.concat(node), this.size + node.nodeSize);
}
eq(other) {
if (this.content.length != other.content.length)
return false;
for (let i = 0; i < this.content.length; i++)
if (!this.content[i].eq(other.content[i]))
return false;
return true;
}
get firstChild() {
return this.content.length ? this.content[0] : null;
}
get lastChild() {
return this.content.length ? this.content[this.content.length - 1] : null;
}
get childCount() {
return this.content.length;
}
child(index) {
let found2 = this.content[index];
if (!found2)
throw new RangeError("Index " + index + " out of range for " + this);
return found2;
}
maybeChild(index) {
return this.content[index] || null;
}
forEach(f) {
for (let i = 0, p = 0; i < this.content.length; i++) {
let child = this.content[i];
f(child, p, i);
p += child.nodeSize;
}
}
findDiffStart(other, pos = 0) {
return findDiffStart(this, other, pos);
}
findDiffEnd(other, pos = this.size, otherPos = other.size) {
return findDiffEnd(this, other, pos, otherPos);
}
findIndex(pos, round2 = -1) {
if (pos == 0)
return retIndex(0, pos);
if (pos == this.size)
return retIndex(this.content.length, pos);
if (pos > this.size || pos < 0)
throw new RangeError(`Position ${pos} outside of fragment (${this})`);
for (let i = 0, curPos = 0; ; i++) {
let cur = this.child(i), end2 = curPos + cur.nodeSize;
if (end2 >= pos) {
if (end2 == pos || round2 > 0)
return retIndex(i + 1, end2);
return retIndex(i, curPos);
}
curPos = end2;
}
}
toString() {
return "<" + this.toStringInner() + ">";
}
toStringInner() {
return this.content.join(", ");
}
toJSON() {
return this.content.length ? this.content.map((n) => n.toJSON()) : null;
}
static fromJSON(schema, value) {
if (!value)
return Fragment.empty;
if (!Array.isArray(value))
throw new RangeError("Invalid input for Fragment.fromJSON");
return new Fragment(value.map(schema.nodeFromJSON));
}
static fromArray(array4) {
if (!array4.length)
return Fragment.empty;
let joined, size2 = 0;
for (let i = 0; i < array4.length; i++) {
let node = array4[i];
size2 += node.nodeSize;
if (i && node.isText && array4[i - 1].sameMarkup(node)) {
if (!joined)
joined = array4.slice(0, i);
joined[joined.length - 1] = node.withText(joined[joined.length - 1].text + node.text);
} else if (joined) {
joined.push(node);
}
}
return new Fragment(joined || array4, size2);
}
static from(nodes) {
if (!nodes)
return Fragment.empty;
if (nodes instanceof Fragment)
return nodes;
if (Array.isArray(nodes))
return this.fromArray(nodes);
if (nodes.attrs)
return new Fragment([nodes], nodes.nodeSize);
throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
}
}
Fragment.empty = new Fragment([], 0);
const found = { index: 0, offset: 0 };
function retIndex(index, offset2) {
found.index = index;
found.offset = offset2;
return found;
}
function compareDeep(a, b) {
if (a === b)
return true;
if (!(a && typeof a == "object") || !(b && typeof b == "object"))
return false;
let array4 = Array.isArray(a);
if (Array.isArray(b) != array4)
return false;
if (array4) {
if (a.length != b.length)
return false;
for (let i = 0; i < a.length; i++)
if (!compareDeep(a[i], b[i]))
return false;
} else {
for (let p in a)
if (!(p in b) || !compareDeep(a[p], b[p]))
return false;
for (let p in b)
if (!(p in a))
return false;
}
return true;
}
class Mark$1 {
constructor(type4, attrs) {
this.type = type4;
this.attrs = attrs;
}
addToSet(set2) {
let copy2, placed = false;
for (let i = 0; i < set2.length; i++) {
let other = set2[i];
if (this.eq(other))
return set2;
if (this.type.excludes(other.type)) {
if (!copy2)
copy2 = set2.slice(0, i);
} else if (other.type.excludes(this.type)) {
return set2;
} else {
if (!placed && other.type.rank > this.type.rank) {
if (!copy2)
copy2 = set2.slice(0, i);
copy2.push(this);
placed = true;
}
if (copy2)
copy2.push(other);
}
}
if (!copy2)
copy2 = set2.slice();
if (!placed)
copy2.push(this);
return copy2;
}
removeFromSet(set2) {
for (let i = 0; i < set2.length; i++)
if (this.eq(set2[i]))
return set2.slice(0, i).concat(set2.slice(i + 1));
return set2;
}
isInSet(set2) {
for (let i = 0; i < set2.length; i++)
if (this.eq(set2[i]))
return true;
return false;
}
eq(other) {
return this == other || this.type == other.type && compareDeep(this.attrs, other.attrs);
}
toJSON() {
let obj = { type: this.type.name };
for (let _ in this.attrs) {
obj.attrs = this.attrs;
break;
}
return obj;
}
static fromJSON(schema, json) {
if (!json)
throw new RangeError("Invalid input for Mark.fromJSON");
let type4 = schema.marks[json.type];
if (!type4)
throw new RangeError(`There is no mark type ${json.type} in this schema`);
let mark = type4.create(json.attrs);
type4.checkAttrs(mark.attrs);
return mark;
}
static sameSet(a, b) {
if (a == b)
return true;
if (a.length != b.length)
return false;
for (let i = 0; i < a.length; i++)
if (!a[i].eq(b[i]))
return false;
return true;
}
static setFrom(marks) {
if (!marks || Array.isArray(marks) && marks.length == 0)
return Mark$1.none;
if (marks instanceof Mark$1)
return [marks];
let copy2 = marks.slice();
copy2.sort((a, b) => a.type.rank - b.type.rank);
return copy2;
}
}
Mark$1.none = [];
class ReplaceError extends Error {
}
class Slice {
constructor(content, openStart, openEnd) {
this.content = content;
this.openStart = openStart;
this.openEnd = openEnd;
}
get size() {
return this.content.size - this.openStart - this.openEnd;
}
insertAt(pos, fragment) {
let content = insertInto(this.content, pos + this.openStart, fragment);
return content && new Slice(content, this.openStart, this.openEnd);
}
removeBetween(from2, to) {
return new Slice(removeRange(this.content, from2 + this.openStart, to + this.openStart), this.openStart, this.openEnd);
}
eq(other) {
return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd;
}
toString() {
return this.content + "(" + this.openStart + "," + this.openEnd + ")";
}
toJSON() {
if (!this.content.size)
return null;
let json = { content: this.content.toJSON() };
if (this.openStart > 0)
json.openStart = this.openStart;
if (this.openEnd > 0)
json.openEnd = this.openEnd;
return json;
}
static fromJSON(schema, json) {
if (!json)
return Slice.empty;
let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
if (typeof openStart != "number" || typeof openEnd != "number")
throw new RangeError("Invalid input for Slice.fromJSON");
return new Slice(Fragment.fromJSON(schema, json.content), openStart, openEnd);
}
static maxOpen(fragment, openIsolating = true) {
let openStart = 0, openEnd = 0;
for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild)
openStart++;
for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild)
openEnd++;
return new Slice(fragment, openStart, openEnd);
}
}
Slice.empty = new Slice(Fragment.empty, 0, 0);
function removeRange(content, from2, to) {
let { index, offset: offset2 } = content.findIndex(from2), child = content.maybeChild(index);
let { index: indexTo, offset: offsetTo } = content.findIndex(to);
if (offset2 == from2 || child.isText) {
if (offsetTo != to && !content.child(indexTo).isText)
throw new RangeError("Removing non-flat range");
return content.cut(0, from2).append(content.cut(to));
}
if (index != indexTo)
throw new RangeError("Removing non-flat range");
return content.replaceChild(index, child.copy(removeRange(child.content, from2 - offset2 - 1, to - offset2 - 1)));
}
function insertInto(content, dist, insert, parent) {
let { index, offset: offset2 } = content.findIndex(dist), child = content.maybeChild(index);
if (offset2 == dist || child.isText) {
if (parent && !parent.canReplace(index, index, insert))
return null;
return content.cut(0, dist).append(insert).append(content.cut(dist));
}
let inner = insertInto(child.content, dist - offset2 - 1, insert);
return inner && content.replaceChild(index, child.copy(inner));
}
function replace($from, $to, slice2) {
if (slice2.openStart > $from.depth)
throw new ReplaceError("Inserted content deeper than insertion position");
if ($from.depth - slice2.openStart != $to.depth - slice2.openEnd)
throw new ReplaceError("Inconsistent open depths");
return replaceOuter($from, $to, slice2, 0);
}
function replaceOuter($from, $to, slice2, depth) {
let index = $from.index(depth), node = $from.node(depth);
if (index == $to.index(depth) && depth < $from.depth - slice2.openStart) {
let inner = replaceOuter($from, $to, slice2, depth + 1);
return node.copy(node.content.replaceChild(index, inner));
} else if (!slice2.content.size) {
return close(node, replaceTwoWay($from, $to, depth));
} else if (!slice2.openStart && !slice2.openEnd && $from.depth == depth && $to.depth == depth) {
let parent = $from.parent, content = parent.content;
return close(parent, content.cut(0, $from.parentOffset).append(slice2.content).append(content.cut($to.parentOffset)));
} else {
let { start: start2, end: end2 } = prepareSliceForReplace(slice2, $from);
return close(node, replaceThreeWay($from, start2, end2, $to, depth));
}
}
function checkJoin(main2, sub) {
if (!sub.type.compatibleContent(main2.type))
throw new ReplaceError("Cannot join " + sub.type.name + " onto " + main2.type.name);
}
function joinable$1($before, $after, depth) {
let node = $before.node(depth);
checkJoin(node, $after.node(depth));
return node;
}
function addNode(child, target) {
let last = target.length - 1;
if (last >= 0 && child.isText && child.sameMarkup(target[last]))
target[last] = child.withText(target[last].text + child.text);
else
target.push(child);
}
function addRange($start, $end, depth, target) {
let node = ($end || $start).node(depth);
let startIndex = 0, endIndex = $end ? $end.index(depth) : node.childCount;
if ($start) {
startIndex = $start.index(depth);
if ($start.depth > depth) {
startIndex++;
} else if ($start.textOffset) {
addNode($start.nodeAfter, target);
startIndex++;
}
}
for (let i = startIndex; i < endIndex; i++)
addNode(node.child(i), target);
if ($end && $end.depth == depth && $end.textOffset)
addNode($end.nodeBefore, target);
}
function close(node, content) {
node.type.checkContent(content);
return node.copy(content);
}
function replaceThreeWay($from, $start, $end, $to, depth) {
let openStart = $from.depth > depth && joinable$1($from, $start, depth + 1);
let openEnd = $to.depth > depth && joinable$1($end, $to, depth + 1);
let content = [];
addRange(null, $from, depth, content);
if (openStart && openEnd && $start.index(depth) == $end.index(depth)) {
checkJoin(openStart, openEnd);
addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content);
} else {
if (openStart)
addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content);
addRange($start, $end, depth, content);
if (openEnd)
addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
}
addRange($to, null, depth, content);
return new Fragment(content);
}
function replaceTwoWay($from, $to, depth) {
let content = [];
addRange(null, $from, depth, content);
if ($from.depth > depth) {
let type4 = joinable$1($from, $to, depth + 1);
addNode(close(type4, replaceTwoWay($from, $to, depth + 1)), content);
}
addRange($to, null, depth, content);
return new Fragment(content);
}
function prepareSliceForReplace(slice2, $along) {
let extra = $along.depth - slice2.openStart, parent = $along.node(extra);
let node = parent.copy(slice2.content);
for (let i = extra - 1; i >= 0; i--)
node = $along.node(i).copy(Fragment.from(node));
return {
start: node.resolveNoCache(slice2.openStart + extra),
end: node.resolveNoCache(node.content.size - slice2.openEnd - extra)
};
}
class ResolvedPos {
constructor(pos, path, parentOffset) {
this.pos = pos;
this.path = path;
this.parentOffset = parentOffset;
this.depth = path.length / 3 - 1;
}
resolveDepth(val) {
if (val == null)
return this.depth;
if (val < 0)
return this.depth + val;
return val;
}
get parent() {
return this.node(this.depth);
}
get doc() {
return this.node(0);
}
node(depth) {
return this.path[this.resolveDepth(depth) * 3];
}
index(depth) {
return this.path[this.resolveDepth(depth) * 3 + 1];
}
indexAfter(depth) {
depth = this.resolveDepth(depth);
return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1);
}
start(depth) {
depth = this.resolveDepth(depth);
return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
}
end(depth) {
depth = this.resolveDepth(depth);
return this.start(depth) + this.node(depth).content.size;
}
before(depth) {
depth = this.resolveDepth(depth);
if (!depth)
throw new RangeError("There is no position before the top-level node");
return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1];
}
after(depth) {
depth = this.resolveDepth(depth);
if (!depth)
throw new RangeError("There is no position after the top-level node");
return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize;
}
get textOffset() {
return this.pos - this.path[this.path.length - 1];
}
get nodeAfter() {
let parent = this.parent, index = this.index(this.depth);
if (index == parent.childCount)
return null;
let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index);
return dOff ? parent.child(index).cut(dOff) : child;
}
get nodeBefore() {
let index = this.index(this.depth);
let dOff = this.pos - this.path[this.path.length - 1];
if (dOff)
return this.parent.child(index).cut(0, dOff);
return index == 0 ? null : this.parent.child(index - 1);
}
posAtIndex(index, depth) {
depth = this.resolveDepth(depth);
let node = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
for (let i = 0; i < index; i++)
pos += node.child(i).nodeSize;
return pos;
}
marks() {
let parent = this.parent, index = this.index();
if (parent.content.size == 0)
return Mark$1.none;
if (this.textOffset)
return parent.child(index).marks;
let main2 = parent.maybeChild(index - 1), other = parent.maybeChild(index);
if (!main2) {
let tmp = main2;
main2 = other;
other = tmp;
}
let marks = main2.marks;
for (var i = 0; i < marks.length; i++)
if (marks[i].type.spec.inclusive === false && (!other || !marks[i].isInSet(other.marks)))
marks = marks[i--].removeFromSet(marks);
return marks;
}
marksAcross($end) {
let after = this.parent.maybeChild(this.index());
if (!after || !after.isInline)
return null;
let marks = after.marks, next = $end.parent.maybeChild($end.index());
for (var i = 0; i < marks.length; i++)
if (marks[i].type.spec.inclusive === false && (!next || !marks[i].isInSet(next.marks)))
marks = marks[i--].removeFromSet(marks);
return marks;
}
sharedDepth(pos) {
for (let depth = this.depth; depth > 0; depth--)
if (this.start(depth) <= pos && this.end(depth) >= pos)
return depth;
return 0;
}
blockRange(other = this, pred) {
if (other.pos < this.pos)
return other.blockRange(this);
for (let d = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d >= 0; d--)
if (other.pos <= this.end(d) && (!pred || pred(this.node(d))))
return new NodeRange(this, other, d);
return null;
}
sameParent(other) {
return this.pos - this.parentOffset == other.pos - other.parentOffset;
}
max(other) {
return other.pos > this.pos ? other : this;
}
min(other) {
return other.pos < this.pos ? other : this;
}
toString() {
let str = "";
for (let i = 1; i <= this.depth; i++)
str += (str ? "/" : "") + this.node(i).type.name + "_" + this.index(i - 1);
return str + ":" + this.parentOffset;
}
static resolve(doc2, pos) {
if (!(pos >= 0 && pos <= doc2.content.size))
throw new RangeError("Position " + pos + " out of range");
let path = [];
let start2 = 0, parentOffset = pos;
for (let node = doc2; ; ) {
let { index, offset: offset2 } = node.content.findIndex(parentOffset);
let rem = parentOffset - offset2;
path.push(node, index, start2 + offset2);
if (!rem)
break;
node = node.child(index);
if (node.isText)
break;
parentOffset = rem - 1;
start2 += offset2 + 1;
}
return new ResolvedPos(pos, path, parentOffset);
}
static resolveCached(doc2, pos) {
let cache2 = resolveCache.get(doc2);
if (cache2) {
for (let i = 0; i < cache2.elts.length; i++) {
let elt = cache2.elts[i];
if (elt.pos == pos)
return elt;
}
} else {
resolveCache.set(doc2, cache2 = new ResolveCache());
}
let result = cache2.elts[cache2.i] = ResolvedPos.resolve(doc2, pos);
cache2.i = (cache2.i + 1) % resolveCacheSize;
return result;
}
}
class ResolveCache {
constructor() {
this.elts = [];
this.i = 0;
}
}
const resolveCacheSize = 12, resolveCache = /* @__PURE__ */ new WeakMap();
class NodeRange {
constructor($from, $to, depth) {
this.$from = $from;
this.$to = $to;
this.depth = depth;
}
get start() {
return this.$from.before(this.depth + 1);
}
get end() {
return this.$to.after(this.depth + 1);
}
get parent() {
return this.$from.node(this.depth);
}
get startIndex() {
return this.$from.index(this.depth);
}
get endIndex() {
return this.$to.indexAfter(this.depth);
}
}
const emptyAttrs = /* @__PURE__ */ Object.create(null);
class Node$1 {
constructor(type4, attrs, content, marks = Mark$1.none) {
this.type = type4;
this.attrs = attrs;
this.marks = marks;
this.content = content || Fragment.empty;
}
get children() {
return this.content.content;
}
get nodeSize() {
return this.isLeaf ? 1 : 2 + this.content.size;
}
get childCount() {
return this.content.childCount;
}
child(index) {
return this.content.child(index);
}
maybeChild(index) {
return this.content.maybeChild(index);
}
forEach(f) {
this.content.forEach(f);
}
nodesBetween(from2, to, f, startPos = 0) {
this.content.nodesBetween(from2, to, f, startPos, this);
}
descendants(f) {
this.nodesBetween(0, this.content.size, f);
}
get textContent() {
return this.isLeaf && this.type.spec.leafText ? this.type.spec.leafText(this) : this.textBetween(0, this.content.size, "");
}
textBetween(from2, to, blockSeparator, leafText) {
return this.content.textBetween(from2, to, blockSeparator, leafText);
}
get firstChild() {
return this.content.firstChild;
}
get lastChild() {
return this.content.lastChild;
}
eq(other) {
return this == other || this.sameMarkup(other) && this.content.eq(other.content);
}
sameMarkup(other) {
return this.hasMarkup(other.type, other.attrs, other.marks);
}
hasMarkup(type4, attrs, marks) {
return this.type == type4 && compareDeep(this.attrs, attrs || type4.defaultAttrs || emptyAttrs) && Mark$1.sameSet(this.marks, marks || Mark$1.none);
}
copy(content = null) {
if (content == this.content)
return this;
return new Node$1(this.type, this.attrs, content, this.marks);
}
mark(marks) {
return marks == this.marks ? this : new Node$1(this.type, this.attrs, this.content, marks);
}
cut(from2, to = this.content.size) {
if (from2 == 0 && to == this.content.size)
return this;
return this.copy(this.content.cut(from2, to));
}
slice(from2, to = this.content.size, includeParents = false) {
if (from2 == to)
return Slice.empty;
let $from = this.resolve(from2), $to = this.resolve(to);
let depth = includeParents ? 0 : $from.sharedDepth(to);
let start2 = $from.start(depth), node = $from.node(depth);
let content = node.content.cut($from.pos - start2, $to.pos - start2);
return new Slice(content, $from.depth - depth, $to.depth - depth);
}
replace(from2, to, slice2) {
return replace(this.resolve(from2), this.resolve(to), slice2);
}
nodeAt(pos) {
for (let node = this; ; ) {
let { index, offset: offset2 } = node.content.findIndex(pos);
node = node.maybeChild(index);
if (!node)
return null;
if (offset2 == pos || node.isText)
return node;
pos -= offset2 + 1;
}
}
childAfter(pos) {
let { index, offset: offset2 } = this.content.findIndex(pos);
return { node: this.content.maybeChild(index), index, offset: offset2 };
}
childBefore(pos) {
if (pos == 0)
return { node: null, index: 0, offset: 0 };
let { index, offset: offset2 } = this.content.findIndex(pos);
if (offset2 < pos)
return { node: this.content.child(index), index, offset: offset2 };
let node = this.content.child(index - 1);
return { node, index: index - 1, offset: offset2 - node.nodeSize };
}
resolve(pos) {
return ResolvedPos.resolveCached(this, pos);
}
resolveNoCache(pos) {
return ResolvedPos.resolve(this, pos);
}
rangeHasMark(from2, to, type4) {
let found2 = false;
if (to > from2)
this.nodesBetween(from2, to, (node) => {
if (type4.isInSet(node.marks))
found2 = true;
return !found2;
});
return found2;
}
get isBlock() {
return this.type.isBlock;
}
get isTextblock() {
return this.type.isTextblock;
}
get inlineContent() {
return this.type.inlineContent;
}
get isInline() {
return this.type.isInline;
}
get isText() {
return this.type.isText;
}
get isLeaf() {
return this.type.isLeaf;
}
get isAtom() {
return this.type.isAtom;
}
toString() {
if (this.type.spec.toDebugString)
return this.type.spec.toDebugString(this);
let name = this.type.name;
if (this.content.size)
name += "(" + this.content.toStringInner() + ")";
return wrapMarks(this.marks, name);
}
contentMatchAt(index) {
let match = this.type.contentMatch.matchFragment(this.content, 0, index);
if (!match)
throw new Error("Called contentMatchAt on a node with invalid content");
return match;
}
canReplace(from2, to, replacement = Fragment.empty, start2 = 0, end2 = replacement.childCount) {
let one = this.contentMatchAt(from2).matchFragment(replacement, start2, end2);
let two = one && one.matchFragment(this.content, to);
if (!two || !two.validEnd)
return false;
for (let i = start2; i < end2; i++)
if (!this.type.allowsMarks(replacement.child(i).marks))
return false;
return true;
}
canReplaceWith(from2, to, type4, marks) {
if (marks && !this.type.allowsMarks(marks))
return false;
let start2 = this.contentMatchAt(from2).matchType(type4);
let end2 = start2 && start2.matchFragment(this.content, to);
return end2 ? end2.validEnd : false;
}
canAppend(other) {
if (other.content.size)
return this.canReplace(this.childCount, this.childCount, other.content);
else
return this.type.compatibleContent(other.type);
}
check() {
this.type.checkContent(this.content);
this.type.checkAttrs(this.attrs);
let copy2 = Mark$1.none;
for (let i = 0; i < this.marks.length; i++) {
let mark = this.marks[i];
mark.type.checkAttrs(mark.attrs);
copy2 = mark.addToSet(copy2);
}
if (!Mark$1.sameSet(copy2, this.marks))
throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map((m) => m.type.name)}`);
this.content.forEach((node) => node.check());
}
toJSON() {
let obj = { type: this.type.name };
for (let _ in this.attrs) {
obj.attrs = this.attrs;
break;
}
if (this.content.size)
obj.content = this.content.toJSON();
if (this.marks.length)
obj.marks = this.marks.map((n) => n.toJSON());
return obj;
}
static fromJSON(schema, json) {
if (!json)
throw new RangeError("Invalid input for Node.fromJSON");
let marks = void 0;
if (json.marks) {
if (!Array.isArray(json.marks))
throw new RangeError("Invalid mark data for Node.fromJSON");
marks = json.marks.map(schema.markFromJSON);
}
if (json.type == "text") {
if (typeof json.text != "string")
throw new RangeError("Invalid text node in JSON");
return schema.text(json.text, marks);
}
let content = Fragment.fromJSON(schema, json.content);
let node = schema.nodeType(json.type).create(json.attrs, content, marks);
node.type.checkAttrs(node.attrs);
return node;
}
}
Node$1.prototype.text = void 0;
class TextNode extends Node$1 {
constructor(type4, attrs, content, marks) {
super(type4, attrs, null, marks);
if (!content)
throw new RangeError("Empty text nodes are not allowed");
this.text = content;
}
toString() {
if (this.type.spec.toDebugString)
return this.type.spec.toDebugString(this);
return wrapMarks(this.marks, JSON.stringify(this.text));
}
get textContent() {
return this.text;
}
textBetween(from2, to) {
return this.text.slice(from2, to);
}
get nodeSize() {
return this.text.length;
}
mark(marks) {
return marks == this.marks ? this : new TextNode(this.type, this.attrs, this.text, marks);
}
withText(text) {
if (text == this.text)
return this;
return new TextNode(this.type, this.attrs, text, this.marks);
}
cut(from2 = 0, to = this.text.length) {
if (from2 == 0 && to == this.text.length)
return this;
return this.withText(this.text.slice(from2, to));
}
eq(other) {
return this.sameMarkup(other) && this.text == other.text;
}
toJSON() {
let base2 = super.toJSON();
base2.text = this.text;
return base2;
}
}
function wrapMarks(marks, str) {
for (let i = marks.length - 1; i >= 0; i--)
str = marks[i].type.name + "(" + str + ")";
return str;
}
class ContentMatch {
constructor(validEnd) {
this.validEnd = validEnd;
this.next = [];
this.wrapCache = [];
}
static parse(string3, nodeTypes) {
let stream = new TokenStream(string3, nodeTypes);
if (stream.next == null)
return ContentMatch.empty;
let expr = parseExpr(stream);
if (stream.next)
stream.err("Unexpected trailing text");
let match = dfa(nfa(expr));
checkForDeadEnds(match, stream);
return match;
}
matchType(type4) {
for (let i = 0; i < this.next.length; i++)
if (this.next[i].type == type4)
return this.next[i].next;
return null;
}
matchFragment(frag, start2 = 0, end2 = frag.childCount) {
let cur = this;
for (let i = start2; cur && i < end2; i++)
cur = cur.matchType(frag.child(i).type);
return cur;
}
get inlineContent() {
return this.next.length != 0 && this.next[0].type.isInline;
}
get defaultType() {
for (let i = 0; i < this.next.length; i++) {
let { type: type4 } = this.next[i];
if (!(type4.isText || type4.hasRequiredAttrs()))
return type4;
}
return null;
}
compatible(other) {
for (let i = 0; i < this.next.length; i++)
for (let j = 0; j < other.next.length; j++)
if (this.next[i].type == other.next[j].type)
return true;
return false;
}
fillBefore(after, toEnd = false, startIndex = 0) {
let seen = [this];
function search(match, types2) {
let finished = match.matchFragment(after, startIndex);
if (finished && (!toEnd || finished.validEnd))
return Fragment.from(types2.map((tp) => tp.createAndFill()));
for (let i = 0; i < match.next.length; i++) {
let { type: type4, next } = match.next[i];
if (!(type4.isText || type4.hasRequiredAttrs()) && seen.indexOf(next) == -1) {
seen.push(next);
let found2 = search(next, types2.concat(type4));
if (found2)
return found2;
}
}
return null;
}
return search(this, []);
}
findWrapping(target) {
for (let i = 0; i < this.wrapCache.length; i += 2)
if (this.wrapCache[i] == target)
return this.wrapCache[i + 1];
let computed2 = this.computeWrapping(target);
this.wrapCache.push(target, computed2);
return computed2;
}
computeWrapping(target) {
let seen = /* @__PURE__ */ Object.create(null), active = [{ match: this, type: null, via: null }];
while (active.length) {
let current = active.shift(), match = current.match;
if (match.matchType(target)) {
let result = [];
for (let obj = current; obj.type; obj = obj.via)
result.push(obj.type);
return result.reverse();
}
for (let i = 0; i < match.next.length; i++) {
let { type: type4, next } = match.next[i];
if (!type4.isLeaf && !type4.hasRequiredAttrs() && !(type4.name in seen) && (!current.type || next.validEnd)) {
active.push({ match: type4.contentMatch, type: type4, via: current });
seen[type4.name] = true;
}
}
}
return null;
}
get edgeCount() {
return this.next.length;
}
edge(n) {
if (n >= this.next.length)
throw new RangeError(`There's no ${n}th edge in this content match`);
return this.next[n];
}
toString() {
let seen = [];
function scan(m) {
seen.push(m);
for (let i = 0; i < m.next.length; i++)
if (seen.indexOf(m.next[i].next) == -1)
scan(m.next[i].next);
}
scan(this);
return seen.map((m, i) => {
let out = i + (m.validEnd ? "*" : " ") + " ";
for (let i2 = 0; i2 < m.next.length; i2++)
out += (i2 ? ", " : "") + m.next[i2].type.name + "->" + seen.indexOf(m.next[i2].next);
return out;
}).join("\n");
}
}
ContentMatch.empty = new ContentMatch(true);
class TokenStream {
constructor(string3, nodeTypes) {
this.string = string3;
this.nodeTypes = nodeTypes;
this.inline = null;
this.pos = 0;
this.tokens = string3.split(/\s*(?=\b|\W|$)/);
if (this.tokens[this.tokens.length - 1] == "")
this.tokens.pop();
if (this.tokens[0] == "")
this.tokens.shift();
}
get next() {
return this.tokens[this.pos];
}
eat(tok) {
return this.next == tok && (this.pos++ || true);
}
err(str) {
throw new SyntaxError(str + " (in content expression '" + this.string + "')");
}
}
function parseExpr(stream) {
let exprs = [];
do {
exprs.push(parseExprSeq(stream));
} while (stream.eat("|"));
return exprs.length == 1 ? exprs[0] : { type: "choice", exprs };
}
function parseExprSeq(stream) {
let exprs = [];
do {
exprs.push(parseExprSubscript(stream));
} while (stream.next && stream.next != ")" && stream.next != "|");
return exprs.length == 1 ? exprs[0] : { type: "seq", exprs };
}
function parseExprSubscript(stream) {
let expr = parseExprAtom(stream);
for (; ; ) {
if (stream.eat("+"))
expr = { type: "plus", expr };
else if (stream.eat("*"))
expr = { type: "star", expr };
else if (stream.eat("?"))
expr = { type: "opt", expr };
else if (stream.eat("{"))
expr = parseExprRange(stream, expr);
else
break;
}
return expr;
}
function parseNum(stream) {
if (/\D/.test(stream.next))
stream.err("Expected number, got '" + stream.next + "'");
let result = Number(stream.next);
stream.pos++;
return result;
}
function parseExprRange(stream, expr) {
let min2 = parseNum(stream), max2 = min2;
if (stream.eat(",")) {
if (stream.next != "}")
max2 = parseNum(stream);
else
max2 = -1;
}
if (!stream.eat("}"))
stream.err("Unclosed braced range");
return { type: "range", min: min2, max: max2, expr };
}
function resolveName(stream, name) {
let types2 = stream.nodeTypes, type4 = types2[name];
if (type4)
return [type4];
let result = [];
for (let typeName in types2) {
let type5 = types2[typeName];
if (type5.isInGroup(name))
result.push(type5);
}
if (result.length == 0)
stream.err("No node type or group '" + name + "' found");
return result;
}
function parseExprAtom(stream) {
if (stream.eat("(")) {
let expr = parseExpr(stream);
if (!stream.eat(")"))
stream.err("Missing closing paren");
return expr;
} else if (!/\W/.test(stream.next)) {
let exprs = resolveName(stream, stream.next).map((type4) => {
if (stream.inline == null)
stream.inline = type4.isInline;
else if (stream.inline != type4.isInline)
stream.err("Mixing inline and block content");
return { type: "name", value: type4 };
});
stream.pos++;
return exprs.length == 1 ? exprs[0] : { type: "choice", exprs };
} else {
stream.err("Unexpected token '" + stream.next + "'");
}
}
function nfa(expr) {
let nfa2 = [[]];
connect(compile(expr, 0), node());
return nfa2;
function node() {
return nfa2.push([]) - 1;
}
function edge(from2, to, term) {
let edge2 = { term, to };
nfa2[from2].push(edge2);
return edge2;
}
function connect(edges, to) {
edges.forEach((edge2) => edge2.to = to);
}
function compile(expr2, from2) {
if (expr2.type == "choice") {
return expr2.exprs.reduce((out, expr3) => out.concat(compile(expr3, from2)), []);
} else if (expr2.type == "seq") {
for (let i = 0; ; i++) {
let next = compile(expr2.exprs[i], from2);
if (i == expr2.exprs.length - 1)
return next;
connect(next, from2 = node());
}
} else if (expr2.type == "star") {
let loop = node();
edge(from2, loop);
connect(compile(expr2.expr, loop), loop);
return [edge(loop)];
} else if (expr2.type == "plus") {
let loop = node();
connect(compile(expr2.expr, from2), loop);
connect(compile(expr2.expr, loop), loop);
return [edge(loop)];
} else if (expr2.type == "opt") {
return [edge(from2)].concat(compile(expr2.expr, from2));
} else if (expr2.type == "range") {
let cur = from2;
for (let i = 0; i < expr2.min; i++) {
let next = node();
connect(compile(expr2.expr, cur), next);
cur = next;
}
if (expr2.max == -1) {
connect(compile(expr2.expr, cur), cur);
} else {
for (let i = expr2.min; i < expr2.max; i++) {
let next = node();
edge(cur, next);
connect(compile(expr2.expr, cur), next);
cur = next;
}
}
return [edge(cur)];
} else if (expr2.type == "name") {
return [edge(from2, void 0, expr2.value)];
} else {
throw new Error("Unknown expr type");
}
}
}
function cmp(a, b) {
return b - a;
}
function nullFrom(nfa2, node) {
let result = [];
scan(node);
return result.sort(cmp);
function scan(node2) {
let edges = nfa2[node2];
if (edges.length == 1 && !edges[0].term)
return scan(edges[0].to);
result.push(node2);
for (let i = 0; i < edges.length; i++) {
let { term, to } = edges[i];
if (!term && result.indexOf(to) == -1)
scan(to);
}
}
}
function dfa(nfa2) {
let labeled = /* @__PURE__ */ Object.create(null);
return explore(nullFrom(nfa2, 0));
function explore(states) {
let out = [];
states.forEach((node) => {
nfa2[node].forEach(({ term, to }) => {
if (!term)
return;
let set2;
for (let i = 0; i < out.length; i++)
if (out[i][0] == term)
set2 = out[i][1];
nullFrom(nfa2, to).forEach((node2) => {
if (!set2)
out.push([term, set2 = []]);
if (set2.indexOf(node2) == -1)
set2.push(node2);
});
});
});
let state = labeled[states.join(",")] = new ContentMatch(states.indexOf(nfa2.length - 1) > -1);
for (let i = 0; i < out.length; i++) {
let states2 = out[i][1].sort(cmp);
state.next.push({ type: out[i][0], next: labeled[states2.join(",")] || explore(states2) });
}
return state;
}
}
function checkForDeadEnds(match, stream) {
for (let i = 0, work = [match]; i < work.length; i++) {
let state = work[i], dead = !state.validEnd, nodes = [];
for (let j = 0; j < state.next.length; j++) {
let { type: type4, next } = state.next[j];
nodes.push(type4.name);
if (dead && !(type4.isText || type4.hasRequiredAttrs()))
dead = false;
if (work.indexOf(next) == -1)
work.push(next);
}
if (dead)
stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)");
}
}
function defaultAttrs(attrs) {
let defaults2 = /* @__PURE__ */ Object.create(null);
for (let attrName in attrs) {
let attr = attrs[attrName];
if (!attr.hasDefault)
return null;
defaults2[attrName] = attr.default;
}
return defaults2;
}
function computeAttrs(attrs, value) {
let built = /* @__PURE__ */ Object.create(null);
for (let name in attrs) {
let given = value && value[name];
if (given === void 0) {
let attr = attrs[name];
if (attr.hasDefault)
given = attr.default;
else
throw new RangeError("No value supplied for attribute " + name);
}
built[name] = given;
}
return built;
}
function checkAttrs(attrs, values, type4, name) {
for (let name2 in values)
if (!(name2 in attrs))
throw new RangeError(`Unsupported attribute ${name2} for ${type4} of type ${name2}`);
for (let name2 in attrs) {
let attr = attrs[name2];
if (attr.validate)
attr.validate(values[name2]);
}
}
function initAttrs(typeName, attrs) {
let result = /* @__PURE__ */ Object.create(null);
if (attrs)
for (let name in attrs)
result[name] = new Attribute(typeName, name, attrs[name]);
return result;
}
class NodeType$1 {
constructor(name, schema, spec) {
this.name = name;
this.schema = schema;
this.spec = spec;
this.markSet = null;
this.groups = spec.group ? spec.group.split(" ") : [];
this.attrs = initAttrs(name, spec.attrs);
this.defaultAttrs = defaultAttrs(this.attrs);
this.contentMatch = null;
this.inlineContent = null;
this.isBlock = !(spec.inline || name == "text");
this.isText = name == "text";
}
get isInline() {
return !this.isBlock;
}
get isTextblock() {
return this.isBlock && this.inlineContent;
}
get isLeaf() {
return this.contentMatch == ContentMatch.empty;
}
get isAtom() {
return this.isLeaf || !!this.spec.atom;
}
isInGroup(group) {
return this.groups.indexOf(group) > -1;
}
get whitespace() {
return this.spec.whitespace || (this.spec.code ? "pre" : "normal");
}
hasRequiredAttrs() {
for (let n in this.attrs)
if (this.attrs[n].isRequired)
return true;
return false;
}
compatibleContent(other) {
return this == other || this.contentMatch.compatible(other.contentMatch);
}
computeAttrs(attrs) {
if (!attrs && this.defaultAttrs)
return this.defaultAttrs;
else
return computeAttrs(this.attrs, attrs);
}
create(attrs = null, content, marks) {
if (this.isText)
throw new Error("NodeType.create can't construct text nodes");
return new Node$1(this, this.computeAttrs(attrs), Fragment.from(content), Mark$1.setFrom(marks));
}
createChecked(attrs = null, content, marks) {
content = Fragment.from(content);
this.checkContent(content);
return new Node$1(this, this.computeAttrs(attrs), content, Mark$1.setFrom(marks));
}
createAndFill(attrs = null, content, marks) {
attrs = this.computeAttrs(attrs);
content = Fragment.from(content);
if (content.size) {
let before = this.contentMatch.fillBefore(content);
if (!before)
return null;
content = before.append(content);
}
let matched = this.contentMatch.matchFragment(content);
let after = matched && matched.fillBefor