1import { d as defineComponent, r as ref, k as onMounted, a3 as onBeforeUnmount, a4 as h, a5 as getCurrentInstance, a6 as watchEffect, q as nextTick, t as unref, T as Teleport, a7 as shallowRef, j as reactive, a8 as markRaw, a9 as customRef, n as watch, o as openBlock, a as createElementBlock, f as createBaseVNode, v as normalizeClass, x as createCommentVNode, e as createVNode, aa as createStaticVNode, p as pushScopeId, h as popScopeId, _ as _export_sfc } from "./main-a531d117.js"; 2function OrderedMap(content) { 3 this.content = content; 4} 5OrderedMap.prototype = { 6 constructor: OrderedMap, 7 find: function(key) { 8 for (var i = 0; i < this.content.length; i += 2) 9 if (this.content[i] === key) 10 return i; 11 return -1; 12 }, 13 // :: (string) â ?any 14 // Retrieve the value stored under `key`, or return undefined when 15 // no such key exists. 16 get: function(key) { 17 var found2 = this.find(key); 18 return found2 == -1 ? void 0 : this.content[found2 + 1]; 19 }, 20 // :: (string, any, ?string) â OrderedMap 21 // Create a new map by replacing the value of `key` with a new 22 // value, or adding a binding to the end of the map. If `newKey` is 23 // given, the key of the binding will be replaced with that key. 24 update: function(key, value, newKey) { 25 var self = newKey && newKey != key ? this.remove(newKey) : this; 26 var found2 = self.find(key), content = self.content.slice(); 27 if (found2 == -1) { 28 content.push(newKey || key, value); 29 } else { 30 content[found2 + 1] = value; 31 if (newKey) 32 content[found2] = newKey; 33 } 34 return new OrderedMap(content); 35 }, 36 // :: (string) â OrderedMap 37 // Return a map with the given key removed, if it existed. 38 remove: function(key) { 39 var found2 = this.find(key); 40 if (found2 == -1) 41 return this; 42 var content = this.content.slice(); 43 content.splice(found2, 2); 44 return new OrderedMap(content); 45 }, 46 // :: (string, any) â OrderedMap 47 // Add a new key to the start of the map. 48 addToStart: function(key, value) { 49 return new OrderedMap([key, value].concat(this.remove(key).content)); 50 }, 51 // :: (string, any) â OrderedMap 52 // Add a new key to the end of the map. 53 addToEnd: function(key, value) { 54 var content = this.remove(key).content.slice(); 55 content.push(key, value); 56 return new OrderedMap(content); 57 }, 58 // :: (string, string, any) â OrderedMap 59 // Add a key after the given key. If `place` is not found, the new 60 // key is added to the end. 61 addBefore: function(place, key, value) { 62 var without = this.remove(key), content = without.content.slice(); 63 var found2 = without.find(place); 64 content.splice(found2 == -1 ? content.length : found2, 0, key, value); 65 return new OrderedMap(content); 66 }, 67 // :: ((key: string, value: any)) 68 // Call the given function for each key/value pair in the map, in 69 // order. 70 forEach: function(f) { 71 for (var i = 0; i < this.content.length; i += 2) 72 f(this.content[i], this.content[i + 1]); 73 }, 74 // :: (union<Object, OrderedMap>) â OrderedMap 75 // Create a new map by prepending the keys in this map that don't 76 // appear in `map` before the keys in `map`. 77 prepend: function(map2) { 78 map2 = OrderedMap.from(map2); 79 if (!map2.size) 80 return this; 81 return new OrderedMap(map2.content.concat(this.subtract(map2).content)); 82 }, 83 // :: (union<Object, OrderedMap>) â OrderedMap 84 // Create a new map by appending the keys in this map that don't 85 // appear in `map` after the keys in `map`. 86 append: function(map2) { 87 map2 = OrderedMap.from(map2); 88 if (!map2.size) 89 return this; 90 return new OrderedMap(this.subtract(map2).content.concat(map2.content)); 91 }, 92 // :: (union<Object, OrderedMap>) â OrderedMap 93 // Create a map containing all the keys in this map that don't 94 // appear in `map`. 95 subtract: function(map2) { 96 var result = this; 97 map2 = OrderedMap.from(map2); 98 for (var i = 0; i < map2.content.length; i += 2) 99 result = result.remove(map2.content[i]); 100 return result; 101 }, 102 // :: () â Object 103 // Turn ordered map into a plain object. 104 toObject: function() { 105 var result = {}; 106 this.forEach(function(key, value) { 107 result[key] = value; 108 }); 109 return result; 110 }, 111 // :: number 112 // The amount of keys in this map. 113 get size() { 114 return this.content.length >> 1; 115 } 116}; 117OrderedMap.from = function(value) { 118 if (value instanceof OrderedMap) 119 return value; 120 var content = []; 121 if (value) 122 for (var prop in value) 123 content.push(prop, value[prop]); 124 return new OrderedMap(content); 125}; 126function findDiffStart(a, b, pos) { 127 for (let i = 0; ; i++) { 128 if (i == a.childCount || i == b.childCount) 129 return a.childCount == b.childCount ? null : pos;
vendor: 29,221 bytes, lines 130-1032
130 let childA = a.child(i), childB = b.child(i); 131 if (childA == childB) { 132 pos += childA.nodeSize; 133 continue; 134 } 135 if (!childA.sameMarkup(childB)) 136 return pos; 137 if (childA.isText && childA.text != childB.text) { 138 for (let j = 0; childA.text[j] == childB.text[j]; j++) 139 pos++; 140 return pos; 141 } 142 if (childA.content.size || childB.content.size) { 143 let inner = findDiffStart(childA.content, childB.content, pos + 1); 144 if (inner != null) 145 return inner; 146 } 147 pos += childA.nodeSize; 148 } 149} 150function findDiffEnd(a, b, posA, posB) { 151 for (let iA = a.childCount, iB = b.childCount; ; ) { 152 if (iA == 0 || iB == 0) 153 return iA == iB ? null : { a: posA, b: posB }; 154 let childA = a.child(--iA), childB = b.child(--iB), size = childA.nodeSize; 155 if (childA == childB) { 156 posA -= size; 157 posB -= size; 158 continue; 159 } 160 if (!childA.sameMarkup(childB)) 161 return { a: posA, b: posB }; 162 if (childA.isText && childA.text != childB.text) { 163 let same = 0, minSize = Math.min(childA.text.length, childB.text.length); 164 while (same < minSize && childA.text[childA.text.length - same - 1] == childB.text[childB.text.length - same - 1]) { 165 same++; 166 posA--; 167 posB--; 168 } 169 return { a: posA, b: posB }; 170 } 171 if (childA.content.size || childB.content.size) { 172 let inner = findDiffEnd(childA.content, childB.content, posA - 1, posB - 1); 173 if (inner) 174 return inner; 175 } 176 posA -= size; 177 posB -= size; 178 } 179} 180class Fragment { 181 /** 182 @internal 183 */ 184 constructor(content, size) { 185 this.content = content; 186 this.size = size || 0; 187 if (size == null) 188 for (let i = 0; i < content.length; i++) 189 this.size += content[i].nodeSize; 190 } 191 /** 192 Invoke a callback for all descendant nodes between the given two 193 positions (relative to start of this fragment). Doesn't descend 194 into a node when the callback returns `false`. 195 */ 196 nodesBetween(from2, to, f, nodeStart = 0, parent) { 197 for (let i = 0, pos = 0; pos < to; i++) { 198 let child = this.content[i], end2 = pos + child.nodeSize; 199 if (end2 > from2 && f(child, nodeStart + pos, parent || null, i) !== false && child.content.size) { 200 let start2 = pos + 1; 201 child.nodesBetween(Math.max(0, from2 - start2), Math.min(child.content.size, to - start2), f, nodeStart + start2); 202 } 203 pos = end2; 204 } 205 } 206 /** 207 Call the given callback for every descendant node. `pos` will be 208 relative to the start of the fragment. The callback may return 209 `false` to prevent traversal of a given node's children. 210 */ 211 descendants(f) { 212 this.nodesBetween(0, this.size, f); 213 } 214 /** 215 Extract the text between `from` and `to`. See the same method on 216 [`Node`](https://prosemirror.net/docs/ref/#model.Node.textBetween). 217 */ 218 textBetween(from2, to, blockSeparator, leafText) { 219 let text = "", first2 = true; 220 this.nodesBetween(from2, to, (node, pos) => { 221 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) : ""; 222 if (node.isBlock && (node.isLeaf && nodeText || node.isTextblock) && blockSeparator) { 223 if (first2) 224 first2 = false; 225 else 226 text += blockSeparator; 227 } 228 text += nodeText; 229 }, 0); 230 return text; 231 } 232 /** 233 Create a new fragment containing the combined content of this 234 fragment and the other. 235 */ 236 append(other) { 237 if (!other.size) 238 return this; 239 if (!this.size) 240 return other; 241 let last = this.lastChild, first2 = other.firstChild, content = this.content.slice(), i = 0; 242 if (last.isText && last.sameMarkup(first2)) { 243 content[content.length - 1] = last.withText(last.text + first2.text); 244 i = 1; 245 } 246 for (; i < other.content.length; i++) 247 content.push(other.content[i]); 248 return new Fragment(content, this.size + other.size); 249 } 250 /** 251 Cut out the sub-fragment between the two given positions. 252 */ 253 cut(from2, to = this.size) { 254 if (from2 == 0 && to == this.size) 255 return this; 256 let result = [], size = 0; 257 if (to > from2) 258 for (let i = 0, pos = 0; pos < to; i++) { 259 let child = this.content[i], end2 = pos + child.nodeSize; 260 if (end2 > from2) { 261 if (pos < from2 || end2 > to) { 262 if (child.isText) 263 child = child.cut(Math.max(0, from2 - pos), Math.min(child.text.length, to - pos)); 264 else 265 child = child.cut(Math.max(0, from2 - pos - 1), Math.min(child.content.size, to - pos - 1)); 266 } 267 result.push(child); 268 size += child.nodeSize; 269 } 270 pos = end2; 271 } 272 return new Fragment(result, size); 273 } 274 /** 275 @internal 276 */ 277 cutByIndex(from2, to) { 278 if (from2 == to) 279 return Fragment.empty; 280 if (from2 == 0 && to == this.content.length) 281 return this; 282 return new Fragment(this.content.slice(from2, to)); 283 } 284 /** 285 Create a new fragment in which the node at the given index is 286 replaced by the given node. 287 */ 288 replaceChild(index, node) { 289 let current = this.content[index]; 290 if (current == node) 291 return this; 292 let copy2 = this.content.slice(); 293 let size = this.size + node.nodeSize - current.nodeSize; 294 copy2[index] = node; 295 return new Fragment(copy2, size); 296 } 297 /** 298 Create a new fragment by prepending the given node to this 299 fragment. 300 */ 301 addToStart(node) { 302 return new Fragment([node].concat(this.content), this.size + node.nodeSize); 303 } 304 /** 305 Create a new fragment by appending the given node to this 306 fragment. 307 */ 308 addToEnd(node) { 309 return new Fragment(this.content.concat(node), this.size + node.nodeSize); 310 } 311 /** 312 Compare this fragment to another one. 313 */ 314 eq(other) { 315 if (this.content.length != other.content.length) 316 return false; 317 for (let i = 0; i < this.content.length; i++) 318 if (!this.content[i].eq(other.content[i])) 319 return false; 320 return true; 321 } 322 /** 323 The first child of the fragment, or `null` if it is empty. 324 */ 325 get firstChild() { 326 return this.content.length ? this.content[0] : null; 327 } 328 /** 329 The last child of the fragment, or `null` if it is empty. 330 */ 331 get lastChild() { 332 return this.content.length ? this.content[this.content.length - 1] : null; 333 } 334 /** 335 The number of child nodes in this fragment. 336 */ 337 get childCount() { 338 return this.content.length; 339 } 340 /** 341 Get the child node at the given index. Raise an error when the 342 index is out of range. 343 */ 344 child(index) { 345 let found2 = this.content[index]; 346 if (!found2) 347 throw new RangeError("Index " + index + " out of range for " + this); 348 return found2; 349 } 350 /** 351 Get the child node at the given index, if it exists. 352 */ 353 maybeChild(index) { 354 return this.content[index] || null; 355 } 356 /** 357 Call `f` for every child node, passing the node, its offset 358 into this parent node, and its index. 359 */ 360 forEach(f) { 361 for (let i = 0, p = 0; i < this.content.length; i++) { 362 let child = this.content[i]; 363 f(child, p, i); 364 p += child.nodeSize; 365 } 366 } 367 /** 368 Find the first position at which this fragment and another 369 fragment differ, or `null` if they are the same. 370 */ 371 findDiffStart(other, pos = 0) { 372 return findDiffStart(this, other, pos); 373 } 374 /** 375 Find the first position, searching from the end, at which this 376 fragment and the given fragment differ, or `null` if they are 377 the same. Since this position will not be the same in both 378 nodes, an object with two separate positions is returned. 379 */ 380 findDiffEnd(other, pos = this.size, otherPos = other.size) { 381 return findDiffEnd(this, other, pos, otherPos); 382 } 383 /** 384 Find the index and inner offset corresponding to a given relative 385 position in this fragment. The result object will be reused 386 (overwritten) the next time the function is called. (Not public.) 387 */ 388 findIndex(pos, round2 = -1) { 389 if (pos == 0) 390 return retIndex(0, pos); 391 if (pos == this.size) 392 return retIndex(this.content.length, pos); 393 if (pos > this.size || pos < 0) 394 throw new RangeError(`Position ${pos} outside of fragment (${this})`); 395 for (let i = 0, curPos = 0; ; i++) { 396 let cur = this.child(i), end2 = curPos + cur.nodeSize; 397 if (end2 >= pos) { 398 if (end2 == pos || round2 > 0) 399 return retIndex(i + 1, end2); 400 return retIndex(i, curPos); 401 } 402 curPos = end2; 403 } 404 } 405 /** 406 Return a debugging string that describes this fragment. 407 */ 408 toString() { 409 return "<" + this.toStringInner() + ">"; 410 } 411 /** 412 @internal 413 */ 414 toStringInner() { 415 return this.content.join(", "); 416 } 417 /** 418 Create a JSON-serializeable representation of this fragment. 419 */ 420 toJSON() { 421 return this.content.length ? this.content.map((n) => n.toJSON()) : null; 422 } 423 /** 424 Deserialize a fragment from its JSON representation. 425 */ 426 static fromJSON(schema, value) { 427 if (!value) 428 return Fragment.empty; 429 if (!Array.isArray(value)) 430 throw new RangeError("Invalid input for Fragment.fromJSON"); 431 return new Fragment(value.map(schema.nodeFromJSON)); 432 } 433 /** 434 Build a fragment from an array of nodes. Ensures that adjacent 435 text nodes with the same marks are joined together. 436 */ 437 static fromArray(array) { 438 if (!array.length) 439 return Fragment.empty; 440 let joined, size = 0; 441 for (let i = 0; i < array.length; i++) { 442 let node = array[i]; 443 size += node.nodeSize; 444 if (i && node.isText && array[i - 1].sameMarkup(node)) { 445 if (!joined) 446 joined = array.slice(0, i); 447 joined[joined.length - 1] = node.withText(joined[joined.length - 1].text + node.text); 448 } else if (joined) { 449 joined.push(node); 450 } 451 } 452 return new Fragment(joined || array, size); 453 } 454 /** 455 Create a fragment from something that can be interpreted as a 456 set of nodes. For `null`, it returns the empty fragment. For a 457 fragment, the fragment itself. For a node or array of nodes, a 458 fragment containing those nodes. 459 */ 460 static from(nodes) { 461 if (!nodes) 462 return Fragment.empty; 463 if (nodes instanceof Fragment) 464 return nodes; 465 if (Array.isArray(nodes)) 466 return this.fromArray(nodes); 467 if (nodes.attrs) 468 return new Fragment([nodes], nodes.nodeSize); 469 throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : "")); 470 } 471} 472Fragment.empty = new Fragment([], 0); 473const found = { index: 0, offset: 0 }; 474function retIndex(index, offset2) { 475 found.index = index; 476 found.offset = offset2; 477 return found; 478} 479function compareDeep(a, b) { 480 if (a === b) 481 return true; 482 if (!(a && typeof a == "object") || !(b && typeof b == "object")) 483 return false; 484 let array = Array.isArray(a); 485 if (Array.isArray(b) != array) 486 return false; 487 if (array) { 488 if (a.length != b.length) 489 return false; 490 for (let i = 0; i < a.length; i++) 491 if (!compareDeep(a[i], b[i])) 492 return false; 493 } else { 494 for (let p in a) 495 if (!(p in b) || !compareDeep(a[p], b[p])) 496 return false; 497 for (let p in b) 498 if (!(p in a)) 499 return false; 500 } 501 return true; 502} 503let Mark$1 = class Mark { 504 /** 505 @internal 506 */ 507 constructor(type, attrs) { 508 this.type = type; 509 this.attrs = attrs; 510 } 511 /** 512 Given a set of marks, create a new set which contains this one as 513 well, in the right position. If this mark is already in the set, 514 the set itself is returned. If any marks that are set to be 515 [exclusive](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) with this mark are present, 516 those are replaced by this one. 517 */ 518 addToSet(set) { 519 let copy2, placed = false; 520 for (let i = 0; i < set.length; i++) { 521 let other = set[i]; 522 if (this.eq(other)) 523 return set; 524 if (this.type.excludes(other.type)) { 525 if (!copy2) 526 copy2 = set.slice(0, i); 527 } else if (other.type.excludes(this.type)) { 528 return set; 529 } else { 530 if (!placed && other.type.rank > this.type.rank) { 531 if (!copy2) 532 copy2 = set.slice(0, i); 533 copy2.push(this); 534 placed = true; 535 } 536 if (copy2) 537 copy2.push(other); 538 } 539 } 540 if (!copy2) 541 copy2 = set.slice(); 542 if (!placed) 543 copy2.push(this); 544 return copy2; 545 } 546 /** 547 Remove this mark from the given set, returning a new set. If this 548 mark is not in the set, the set itself is returned. 549 */ 550 removeFromSet(set) { 551 for (let i = 0; i < set.length; i++) 552 if (this.eq(set[i])) 553 return set.slice(0, i).concat(set.slice(i + 1)); 554 return set; 555 } 556 /** 557 Test whether this mark is in the given set of marks. 558 */ 559 isInSet(set) { 560 for (let i = 0; i < set.length; i++) 561 if (this.eq(set[i])) 562 return true; 563 return false; 564 } 565 /** 566 Test whether this mark has the same type and attributes as 567 another mark. 568 */ 569 eq(other) { 570 return this == other || this.type == other.type && compareDeep(this.attrs, other.attrs); 571 } 572 /** 573 Convert this mark to a JSON-serializeable representation. 574 */ 575 toJSON() { 576 let obj = { type: this.type.name }; 577 for (let _ in this.attrs) { 578 obj.attrs = this.attrs; 579 break; 580 } 581 return obj; 582 } 583 /** 584 Deserialize a mark from JSON. 585 */ 586 static fromJSON(schema, json) { 587 if (!json) 588 throw new RangeError("Invalid input for Mark.fromJSON"); 589 let type = schema.marks[json.type]; 590 if (!type) 591 throw new RangeError(`There is no mark type ${json.type} in this schema`); 592 return type.create(json.attrs); 593 } 594 /** 595 Test whether two sets of marks are identical. 596 */ 597 static sameSet(a, b) { 598 if (a == b) 599 return true; 600 if (a.length != b.length) 601 return false; 602 for (let i = 0; i < a.length; i++) 603 if (!a[i].eq(b[i])) 604 return false; 605 return true; 606 } 607 /** 608 Create a properly sorted mark set from null, a single mark, or an 609 unsorted array of marks. 610 */ 611 static setFrom(marks) { 612 if (!marks || Array.isArray(marks) && marks.length == 0) 613 return Mark.none; 614 if (marks instanceof Mark) 615 return [marks]; 616 let copy2 = marks.slice(); 617 copy2.sort((a, b) => a.type.rank - b.type.rank); 618 return copy2; 619 } 620}; 621Mark$1.none = []; 622class ReplaceError extends Error { 623} 624class Slice { 625 /** 626 Create a slice. When specifying a non-zero open depth, you must 627 make sure that there are nodes of at least that depth at the 628 appropriate side of the fragmentâi.e. if the fragment is an 629 empty paragraph node, `openStart` and `openEnd` can't be greater 630 than 1. 631 632 It is not necessary for the content of open nodes to conform to 633 the schema's content constraints, though it should be a valid 634 start/end/middle for such a node, depending on which sides are 635 open. 636 */ 637 constructor(content, openStart, openEnd) { 638 this.content = content; 639 this.openStart = openStart; 640 this.openEnd = openEnd; 641 } 642 /** 643 The size this slice would add when inserted into a document. 644 */ 645 get size() { 646 return this.content.size - this.openStart - this.openEnd; 647 } 648 /** 649 @internal 650 */ 651 insertAt(pos, fragment) { 652 let content = insertInto(this.content, pos + this.openStart, fragment); 653 return content && new Slice(content, this.openStart, this.openEnd); 654 } 655 /** 656 @internal 657 */ 658 removeBetween(from2, to) { 659 return new Slice(removeRange(this.content, from2 + this.openStart, to + this.openStart), this.openStart, this.openEnd); 660 } 661 /** 662 Tests whether this slice is equal to another slice. 663 */ 664 eq(other) { 665 return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd; 666 } 667 /** 668 @internal 669 */ 670 toString() { 671 return this.content + "(" + this.openStart + "," + this.openEnd + ")"; 672 } 673 /** 674 Convert a slice to a JSON-serializable representation. 675 */ 676 toJSON() { 677 if (!this.content.size) 678 return null; 679 let json = { content: this.content.toJSON() }; 680 if (this.openStart > 0) 681 json.openStart = this.openStart; 682 if (this.openEnd > 0) 683 json.openEnd = this.openEnd; 684 return json; 685 } 686 /** 687 Deserialize a slice from its JSON representation. 688 */ 689 static fromJSON(schema, json) { 690 if (!json) 691 return Slice.empty; 692 let openStart = json.openStart || 0, openEnd = json.openEnd || 0; 693 if (typeof openStart != "number" || typeof openEnd != "number") 694 throw new RangeError("Invalid input for Slice.fromJSON"); 695 return new Slice(Fragment.fromJSON(schema, json.content), openStart, openEnd); 696 } 697 /** 698 Create a slice from a fragment by taking the maximum possible 699 open value on both side of the fragment. 700 */ 701 static maxOpen(fragment, openIsolating = true) { 702 let openStart = 0, openEnd = 0; 703 for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild) 704 openStart++; 705 for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild) 706 openEnd++; 707 return new Slice(fragment, openStart, openEnd); 708 } 709} 710Slice.empty = new Slice(Fragment.empty, 0, 0); 711function removeRange(content, from2, to) { 712 let { index, offset: offset2 } = content.findIndex(from2), child = content.maybeChild(index); 713 let { index: indexTo, offset: offsetTo } = content.findIndex(to); 714 if (offset2 == from2 || child.isText) { 715 if (offsetTo != to && !content.child(indexTo).isText) 716 throw new RangeError("Removing non-flat range"); 717 return content.cut(0, from2).append(content.cut(to)); 718 } 719 if (index != indexTo) 720 throw new RangeError("Removing non-flat range"); 721 return content.replaceChild(index, child.copy(removeRange(child.content, from2 - offset2 - 1, to - offset2 - 1))); 722} 723function insertInto(content, dist, insert, parent) { 724 let { index, offset: offset2 } = content.findIndex(dist), child = content.maybeChild(index); 725 if (offset2 == dist || child.isText) { 726 if (parent && !parent.canReplace(index, index, insert)) 727 return null; 728 return content.cut(0, dist).append(insert).append(content.cut(dist)); 729 } 730 let inner = insertInto(child.content, dist - offset2 - 1, insert); 731 return inner && content.replaceChild(index, child.copy(inner)); 732} 733function replace($from, $to, slice2) { 734 if (slice2.openStart > $from.depth) 735 throw new ReplaceError("Inserted content deeper than insertion position"); 736 if ($from.depth - slice2.openStart != $to.depth - slice2.openEnd) 737 throw new ReplaceError("Inconsistent open depths"); 738 return replaceOuter($from, $to, slice2, 0); 739} 740function replaceOuter($from, $to, slice2, depth) { 741 let index = $from.index(depth), node = $from.node(depth); 742 if (index == $to.index(depth) && depth < $from.depth - slice2.openStart) { 743 let inner = replaceOuter($from, $to, slice2, depth + 1); 744 return node.copy(node.content.replaceChild(index, inner)); 745 } else if (!slice2.content.size) { 746 return close(node, replaceTwoWay($from, $to, depth)); 747 } else if (!slice2.openStart && !slice2.openEnd && $from.depth == depth && $to.depth == depth) { 748 let parent = $from.parent, content = parent.content; 749 return close(parent, content.cut(0, $from.parentOffset).append(slice2.content).append(content.cut($to.parentOffset))); 750 } else { 751 let { start: start2, end: end2 } = prepareSliceForReplace(slice2, $from); 752 return close(node, replaceThreeWay($from, start2, end2, $to, depth)); 753 } 754} 755function checkJoin(main2, sub) { 756 if (!sub.type.compatibleContent(main2.type)) 757 throw new ReplaceError("Cannot join " + sub.type.name + " onto " + main2.type.name); 758} 759function joinable$1($before, $after, depth) { 760 let node = $before.node(depth); 761 checkJoin(node, $after.node(depth)); 762 return node; 763} 764function addNode(child, target) { 765 let last = target.length - 1; 766 if (last >= 0 && child.isText && child.sameMarkup(target[last])) 767 target[last] = child.withText(target[last].text + child.text); 768 else 769 target.push(child); 770} 771function addRange($start, $end, depth, target) { 772 let node = ($end || $start).node(depth); 773 let startIndex = 0, endIndex = $end ? $end.index(depth) : node.childCount; 774 if ($start) { 775 startIndex = $start.index(depth); 776 if ($start.depth > depth) { 777 startIndex++; 778 } else if ($start.textOffset) { 779 addNode($start.nodeAfter, target); 780 startIndex++; 781 } 782 } 783 for (let i = startIndex; i < endIndex; i++) 784 addNode(node.child(i), target); 785 if ($end && $end.depth == depth && $end.textOffset) 786 addNode($end.nodeBefore, target); 787} 788function close(node, content) { 789 node.type.checkContent(content); 790 return node.copy(content); 791} 792function replaceThreeWay($from, $start, $end, $to, depth) { 793 let openStart = $from.depth > depth && joinable$1($from, $start, depth + 1); 794 let openEnd = $to.depth > depth && joinable$1($end, $to, depth + 1); 795 let content = []; 796 addRange(null, $from, depth, content); 797 if (openStart && openEnd && $start.index(depth) == $end.index(depth)) { 798 checkJoin(openStart, openEnd); 799 addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content); 800 } else { 801 if (openStart) 802 addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content); 803 addRange($start, $end, depth, content); 804 if (openEnd) 805 addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content); 806 } 807 addRange($to, null, depth, content); 808 return new Fragment(content); 809} 810function replaceTwoWay($from, $to, depth) { 811 let content = []; 812 addRange(null, $from, depth, content); 813 if ($from.depth > depth) { 814 let type = joinable$1($from, $to, depth + 1); 815 addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content); 816 } 817 addRange($to, null, depth, content); 818 return new Fragment(content); 819} 820function prepareSliceForReplace(slice2, $along) { 821 let extra = $along.depth - slice2.openStart, parent = $along.node(extra); 822 let node = parent.copy(slice2.content); 823 for (let i = extra - 1; i >= 0; i--) 824 node = $along.node(i).copy(Fragment.from(node)); 825 return { 826 start: node.resolveNoCache(slice2.openStart + extra), 827 end: node.resolveNoCache(node.content.size - slice2.openEnd - extra) 828 }; 829} 830class ResolvedPos { 831 /** 832 @internal 833 */ 834 constructor(pos, path, parentOffset) { 835 this.pos = pos; 836 this.path = path; 837 this.parentOffset = parentOffset; 838 this.depth = path.length / 3 - 1; 839 } 840 /** 841 @internal 842 */ 843 resolveDepth(val) { 844 if (val == null) 845 return this.depth; 846 if (val < 0) 847 return this.depth + val; 848 return val; 849 } 850 /** 851 The parent node that the position points into. Note that even if 852 a position points into a text node, that node is not considered 853 the parentâtext nodes are âflatâ in this model, and have no content. 854 */ 855 get parent() { 856 return this.node(this.depth); 857 } 858 /** 859 The root node in which the position was resolved. 860 */ 861 get doc() { 862 return this.node(0); 863 } 864 /** 865 The ancestor node at the given level. `p.node(p.depth)` is the 866 same as `p.parent`. 867 */ 868 node(depth) { 869 return this.path[this.resolveDepth(depth) * 3]; 870 } 871 /** 872 The index into the ancestor at the given level. If this points 873 at the 3rd node in the 2nd paragraph on the top level, for 874 example, `p.index(0)` is 1 and `p.index(1)` is 2. 875 */ 876 index(depth) { 877 return this.path[this.resolveDepth(depth) * 3 + 1]; 878 } 879 /** 880 The index pointing after this position into the ancestor at the 881 given level. 882 */ 883 indexAfter(depth) { 884 depth = this.resolveDepth(depth); 885 return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1); 886 } 887 /** 888 The (absolute) position at the start of the node at the given 889 level. 890 */ 891 start(depth) { 892 depth = this.resolveDepth(depth); 893 return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1; 894 } 895 /** 896 The (absolute) position at the end of the node at the given 897 level. 898 */ 899 end(depth) { 900 depth = this.resolveDepth(depth); 901 return this.start(depth) + this.node(depth).content.size; 902 } 903 /** 904 The (absolute) position directly before the wrapping node at the 905 given level, or, when `depth` is `this.depth + 1`, the original 906 position. 907 */ 908 before(depth) { 909 depth = this.resolveDepth(depth); 910 if (!depth) 911 throw new RangeError("There is no position before the top-level node"); 912 return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1]; 913 } 914 /** 915 The (absolute) position directly after the wrapping node at the 916 given level, or the original position when `depth` is `this.depth + 1`. 917 */ 918 after(depth) { 919 depth = this.resolveDepth(depth); 920 if (!depth) 921 throw new RangeError("There is no position after the top-level node"); 922 return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize; 923 } 924 /** 925 When this position points into a text node, this returns the 926 distance between the position and the start of the text node. 927 Will be zero for positions that point between nodes. 928 */ 929 get textOffset() { 930 return this.pos - this.path[this.path.length - 1]; 931 } 932 /** 933 Get the node directly after the position, if any. If the position 934 points into a text node, only the part of that node after the 935 position is returned. 936 */ 937 get nodeAfter() { 938 let parent = this.parent, index = this.index(this.depth); 939 if (index == parent.childCount) 940 return null; 941 let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index); 942 return dOff ? parent.child(index).cut(dOff) : child; 943 } 944 /** 945 Get the node directly before the position, if any. If the 946 position points into a text node, only the part of that node 947 before the position is returned. 948 */ 949 get nodeBefore() { 950 let index = this.index(this.depth); 951 let dOff = this.pos - this.path[this.path.length - 1]; 952 if (dOff) 953 return this.parent.child(index).cut(0, dOff); 954 return index == 0 ? null : this.parent.child(index - 1); 955 } 956 /** 957 Get the position at the given index in the parent node at the 958 given depth (which defaults to `this.depth`). 959 */ 960 posAtIndex(index, depth) { 961 depth = this.resolveDepth(depth); 962 let node = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1; 963 for (let i = 0; i < index; i++) 964 pos += node.child(i).nodeSize; 965 return pos; 966 } 967 /** 968 Get the marks at this position, factoring in the surrounding 969 marks' [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) property. If the 970 position is at the start of a non-empty node, the marks of the 971 node after it (if any) are returned. 972 */ 973 marks() { 974 let parent = this.parent, index = this.index(); 975 if (parent.content.size == 0) 976 return Mark$1.none; 977 if (this.textOffset) 978 return parent.child(index).marks; 979 let main2 = parent.maybeChild(index - 1), other = parent.maybeChild(index); 980 if (!main2) { 981 let tmp = main2; 982 main2 = other; 983 other = tmp; 984 } 985 let marks = main2.marks; 986 for (var i = 0; i < marks.length; i++) 987 if (marks[i].type.spec.inclusive === false && (!other || !marks[i].isInSet(other.marks))) 988 marks = marks[i--].removeFromSet(marks); 989 return marks; 990 } 991 /** 992 Get the marks after the current position, if any, except those 993 that are non-inclusive and not present at position `$end`. This 994 is mostly useful for getting the set of marks to preserve after a 995 deletion. Will return `null` if this position is at the end of 996 its parent node or its parent node isn't a textblock (in which 997 case no marks should be preserved). 998 */ 999 marksAcross($end) { 1000 let after = this.parent.maybeChild(this.index()); 1001 if (!after || !after.isInline) 1002 return null; 1003 let marks = after.marks, next = $end.parent.maybeChild($end.index()); 1004 for (var i = 0; i < marks.length; i++) 1005 if (marks[i].type.spec.inclusive === false && (!next || !marks[i].isInSet(next.marks))) 1006 marks = marks[i--].removeFromSet(marks); 1007 return marks; 1008 } 1009 /** 1010 The depth up to which this position and the given (non-resolved) 1011 position share the same parent nodes. 1012 */ 1013 sharedDepth(pos) { 1014 for (let depth = this.depth; depth > 0; depth--) 1015 if (this.start(depth) <= pos && this.end(depth) >= pos) 1016 return depth; 1017 return 0; 1018 } 1019 /** 1020 Returns a range based on the place where this position and the 1021 given position diverge around block content. If both point into 1022 the same textblock, for example, a range around that textblock 1023 will be returned. If they point into different blocks, the range 1024 around those blocks in their shared ancestor is returned. You can 1025 pass in an optional predicate that will be called with a parent 1026 node to see if a range into that parent is acceptable. 1027 */ 1028 blockRange(other = this, pred) { 1029 if (other.pos < this.pos) 1030 return other.blockRange(this); 1031 for (let d = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d >= 0; d--) 1032 if (other.pos <= this.end(d) && (!pred || pred(this.node(d
vendor: 1,609 bytes, lines 1032-1093
1032)))) 1033 return new NodeRange(this, other, d); 1034 return null; 1035 } 1036 /** 1037 Query whether the given position shares the same parent node. 1038 */ 1039 sameParent(other) { 1040 return this.pos - this.parentOffset == other.pos - other.parentOffset; 1041 } 1042 /** 1043 Return the greater of this and the given position. 1044 */ 1045 max(other) { 1046 return other.pos > this.pos ? other : this; 1047 } 1048 /** 1049 Return the smaller of this and the given position. 1050 */ 1051 min(other) { 1052 return other.pos < this.pos ? other : this; 1053 } 1054 /** 1055 @internal 1056 */ 1057 toString() { 1058 let str = ""; 1059 for (let i = 1; i <= this.depth; i++) 1060 str += (str ? "/" : "") + this.node(i).type.name + "_" + this.index(i - 1); 1061 return str + ":" + this.parentOffset; 1062 } 1063 /** 1064 @internal 1065 */ 1066 static resolve(doc2, pos) { 1067 if (!(pos >= 0 && pos <= doc2.content.size)) 1068 throw new RangeError("Position " + pos + " out of range"); 1069 let path = []; 1070 let start2 = 0, parentOffset = pos; 1071 for (let node = doc2; ; ) { 1072 let { index, offset: offset2 } = node.content.findIndex(parentOffset); 1073 let rem = parentOffset - offset2; 1074 path.push(node, index, start2 + offset2); 1075 if (!rem) 1076 break; 1077 node = node.child(index); 1078 if (node.isText) 1079 break; 1080 parentOffset = rem - 1; 1081 start2 += offset2 + 1; 1082 } 1083 return new ResolvedPos(pos, path, parentOffset); 1084 } 1085 /** 1086 @internal 1087 */ 1088 static resolveCached(doc2, pos) { 1089 for (let i = 0; i < resolveCache.length; i++) { 1090 let cached = resolveCache[i]; 1091 if (cached.pos == pos && cached.doc == doc2) 1092 return cached; 1093 }
1094 let result = resolveCache[resolveCachePos] = ResolvedPos.resolve(doc2, pos); 1095 resolveCachePos = (resolveCachePos + 1) % resolveCacheSize; 1096 return result; 1097 } 1098} 1099let resolveCache = [], resolveCachePos = 0, resolveCacheSize = 12; 1100class NodeRange { 1101 /** 1102 Construct a node range. `$from` and `$to` should point into the 1103 same node until at least the given `depth`, since a node range 1104 denotes an adjacent set of nodes in a single parent node. 1105 */ 1106 constructor($from, $to, depth) { 1107 this.$from = $from; 1108 this.$to = $to; 1109 this.depth = depth; 1110 } 1111 /** 1112 The position at the start of the range. 1113 */ 1114 get start() { 1115 return this.$from.before(this.depth + 1); 1116 } 1117 /** 1118 The position at the end of the range. 1119 */ 1120 get end() { 1121 return this.$to.after(this.depth + 1); 1122 } 1123 /** 1124 The parent node that the range points into. 1125 */ 1126 get parent() { 1127 return this.$from.node(this.depth); 1128 } 1129 /** 1130 The start index of the range in the parent node. 1131 */ 1132 get startIndex() { 1133 return this.$from.index(this.depth); 1134 } 1135 /** 1136 The end index of the range in the parent node. 1137 */ 1138 get endIndex() { 1139 return this.$to.indexAfter(this.depth); 1140 } 1141} 1142const emptyAttrs = /* @__PURE__ */ Object.create(null); 1143let Node$1 = class Node { 1144 /** 1145 @internal 1146 */ 1147 constructor(type, attrs, content, marks = Mark$1.none) { 1148 this.type = type; 1149 this.attrs = attrs; 1150 this.marks = marks; 1151 this.content = content || Fragment.empty; 1152 } 1153 /** 1154 The size of this node, as defined by the integer-based [indexing 1155 scheme](/docs/guide/#doc.indexing). For text nodes, this is the 1156 amount of characters. For other leaf nodes, it is one. For 1157 non-leaf nodes, it is the size of the content plus two (the 1158 start and end token). 1159 */ 1160 get nodeSize() { 1161 return this.isLeaf ? 1 : 2 + this.content.size; 1162 } 1163 /** 1164 The number of children that the node has. 1165 */ 1166 get childCount() { 1167 return this.content.childCount; 1168 } 1169 /** 1170 Get the child node at the given index. Raises an error when the 1171 index is out of range. 1172 */ 1173 child(index) { 1174 return this.content.child(index); 1175 } 1176 /** 1177 Get the child node at the given index, if it exists. 1178 */ 1179 maybeChild(index) { 1180 return this.content.maybeChild(index); 1181 } 1182 /** 1183 Call `f` for every child node, passing the node, its offset 1184 into this parent node, and its index. 1185 */ 1186 forEach(f) { 1187 this.content.forEach(f); 1188 } 1189 /** 1190 Invoke a callback for all descendant nodes recursively between 1191 the given two positions that are relative to start of this 1192 node's content. The callback is invoked with the node, its 1193 position relative to the original node (method receiver), 1194 its parent node, and its child index. When the callback returns 1195 false for a given node, that node's children will not be 1196 recursed over. The last parameter can be used to specify a 1197 starting position to count from. 1198 */ 1199 nodesBetween(from2, to, f, startPos = 0) { 1200 this.content.nodesBetween(from2, to, f, startPos, this); 1201 } 1202 /** 1203 Call the given callback for every descendant node. Doesn't 1204 descend into a node when the callback returns `false`. 1205 */ 1206 descendants(f) { 1207 this.nodesBetween(0, this.content.size, f); 1208 } 1209 /** 1210 Concatenates all the text nodes found in this fragment and its 1211 children. 1212 */ 1213 get textContent() { 1214 return this.isLeaf && this.type.spec.leafText ? this.type.spec.leafText(this) : this.textBetween(0, this.content.size, ""); 1215 } 1216 /** 1217 Get all text between positions `from` and `to`. When 1218 `blockSeparator` is given, it will be inserted to separate text 1219 from different block nodes. If `leafText` is given, it'll be 1220 inserted for every non-text leaf node encountered, otherwise 1221 [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec^leafText) will be used. 1222 */ 1223 textBetween(from2, to, blockSeparator, leafText) { 1224 return this.content.textBetween(from2, to, blockSeparator, leafText); 1225 } 1226 /** 1227 Returns this node's first child, or `null` if there are no 1228 children. 1229 */ 1230 get firstChild() { 1231 return this.content.firstChild; 1232 } 1233 /** 1234 Returns this node's last child, or `null` if there are no 1235 children. 1236 */ 1237 get lastChild() { 1238 return this.content.lastChild; 1239 } 1240 /** 1241 Test whether two nodes represent the same piece of document. 1242 */ 1243 eq(other) { 1244 return this == other || this.sameMarkup(other) && this.content.eq(other.content); 1245 } 1246 /** 1247 Compare the markup (type, attributes, and marks) of this node to 1248 those of another. Returns `true` if both have the same markup. 1249 */ 1250 sameMarkup(other) { 1251 return this.hasMarkup(other.type, other.attrs, other.marks); 1252 } 1253 /** 1254 Check whether this node's markup correspond to the given type, 1255 attributes, and marks. 1256 */ 1257 hasMarkup(type, attrs, marks) { 1258 return this.type == type && compareDeep(this.attrs, attrs || type.defaultAttrs || emptyAttrs) && Mark$1.sameSet(this.marks, marks || Mark$1.none); 1259 } 1260 /** 1261 Create a new node with the same markup as this node, containing 1262 the given content (or empty, if no content is given). 1263 */ 1264 copy(content = null) { 1265 if (content == this.content) 1266 return this; 1267 return new Node(this.type, this.attrs, content, this.marks); 1268 } 1269 /** 1270 Create a copy of this node, with the given set of marks instead 1271 of the node's own marks. 1272 */ 1273 mark(marks) {
1274 return marks == this.marks ? this : new Node(this.type, this.attrs, this.content, marks); 1275 } 1276 /** 1277 Create a copy of this node with only the content between the 1278 given positions. If `to` is not given, it defaults to the end of 1279 the node. 1280 */ 1281 cut(from2, to = this.content.size) { 1282 if (from2 == 0 && to == this.content.size) 1283 return this; 1284 return this.copy(this.content.cut(from2, to)); 1285 } 1286 /** 1287 Cut out the part of the document between the given positions, and 1288 return it as a `Slice` object. 1289 */ 1290 slice(from2, to = this.content.size, includeParents = false) { 1291 if (from2 == to) 1292 return Slice.empty; 1293 let $from = this.resolve(from2), $to = this.resolve(to); 1294 let depth = includeParents ? 0 : $from.sharedDepth(to); 1295 let start2 = $from.start(depth), node = $from.node(depth); 1296 let content = node.content.cut($from.pos - start2, $to.pos - start2); 1297 return new Slice(content, $from.depth - depth, $to.depth - depth); 1298 } 1299 /** 1300 Replace the part of the document between the given positions with 1301 the given slice. The slice must 'fit', meaning its open sides 1302 must be able to connect to the surrounding content, and its 1303 content nodes must be valid children for the node they are placed 1304 into. If any of this is violated, an error of type 1305 [`ReplaceError`](https://prosemirror.net/docs/ref/#model.ReplaceError) is thrown. 1306 */ 1307 replace(from2, to, slice2) { 1308 return replace(this.resolve(from2), this.resolve(to), slice2); 1309 } 1310 /** 1311 Find the node directly after the given position. 1312 */ 1313 nodeAt(pos) { 1314 for (let node = this; ; ) { 1315 let { index, offset: offset2 } = node.content.findIndex(pos); 1316 node = node.maybeChild(index); 1317 if (!node) 1318 return null; 1319 if (offset2 == pos || node.isText) 1320 return node; 1321 pos -= offset2 + 1; 1322 } 1323 } 1324 /** 1325 Find the (direct) child node after the given offset, if any, 1326 and return it along with its index and offset relative to this 1327 node. 1328 */ 1329 childAfter(pos) { 1330 let { index, offset: offset2 } = this.content.findIndex(pos); 1331 return { node: this.content.maybeChild(index), index, offset: offset2 }; 1332 } 1333 /** 1334 Find the (direct) child node before the given offset, if any, 1335 and return it along with its index and offset relative to this 1336 node. 1337 */ 1338 childBefore(pos) { 1339 if (pos == 0) 1340 return { node: null, index: 0, offset: 0 }; 1341 let { index, offset: offset2 } = this.content.findIndex(pos); 1342 if (offset2 < pos) 1343 return { node: this.content.child(index), index, offset: offset2 }; 1344 let node = this.content.child(index - 1); 1345 return { node, index: index - 1, offset: offset2 - node.nodeSize }; 1346 } 1347 /** 1348 Resolve the given position in the document, returning an 1349 [object](https://prosemirror.net/docs/ref/#model.ResolvedPos) with information about its context. 1350 */ 1351 resolve(pos) { 1352 return ResolvedPos.resolveCached(this, pos); 1353 } 1354 /** 1355 @internal 1356 */ 1357 resolveNoCache(pos) { 1358 return ResolvedPos.resolve(this, pos); 1359 } 1360 /** 1361 Test whether a given mark or mark type occurs in this document 1362 between the two given positions. 1363 */ 1364 rangeHasMark(from2, to, type) { 1365 let found2 = false; 1366 if (to > from2) 1367 this.nodesBetween(from2, to, (node) => { 1368 if (type.isInSet(node.marks)) 1369 found2 = true; 1370 return !found2; 1371 }); 1372 return found2; 1373 } 1374 /** 1375 True when this is a block (non-inline node) 1376 */ 1377 get isBlock() { 1378 return this.type.isBlock; 1379 } 1380 /** 1381 True when this is a textblock node, a block node with inline 1382 content. 1383 */ 1384 get isTextblock() { 1385 return this.type.isTextblock; 1386 } 1387 /** 1388 True when this node allows inline content. 1389 */ 1390 get inlineContent() { 1391 return this.type.inlineContent; 1392 } 1393 /** 1394 True when this is an inline node (a text node or a node that can 1395 appear among text). 1396 */ 1397 get isInline() { 1398 return this.type.isInline; 1399 } 1400 /** 1401 True when this is a text node. 1402 */ 1403 get isText() { 1404 return this.type.isText; 1405 } 1406 /** 1407 True when this is a leaf node. 1408 */ 1409 get isLeaf() { 1410 return this.type.isLeaf; 1411 } 1412 /** 1413 True when this is an atom, i.e. when it does not have directly 1414 editable content. This is usually the same as `isLeaf`, but can 1415 be configured with the [`atom` property](https://prosemirror.net/docs/ref/#model.NodeSpec.atom) 1416 on a node's spec (typically used when the node is displayed as 1417 an uneditable [node view](https://prosemirror.net/docs/ref/#view.NodeView)). 1418 */ 1419 get isAtom() { 1420 return this.type.isAtom; 1421 } 1422 /** 1423 Return a string representation of this node for debugging 1424 purposes. 1425 */ 1426 toString() {
vendor: 1,444 bytes, lines 1427-1464
1427 if (this.type.spec.toDebugString) 1428 return this.type.spec.toDebugString(this); 1429 let name = this.type.name; 1430 if (this.content.size) 1431 name += "(" + this.content.toStringInner() + ")"; 1432 return wrapMarks(this.marks, name); 1433 } 1434 /** 1435 Get the content match in this node at the given index. 1436 */ 1437 contentMatchAt(index) { 1438 let match = this.type.contentMatch.matchFragment(this.content, 0, index); 1439 if (!match) 1440 throw new Error("Called contentMatchAt on a node with invalid content"); 1441 return match; 1442 } 1443 /** 1444 Test whether replacing the range between `from` and `to` (by 1445 child index) with the given replacement fragment (which defaults 1446 to the empty fragment) would leave the node's content valid. You 1447 can optionally pass `start` and `end` indices into the 1448 replacement fragment. 1449 */ 1450 canReplace(from2, to, replacement = Fragment.empty, start2 = 0, end2 = replacement.childCount) { 1451 let one = this.contentMatchAt(from2).matchFragment(replacement, start2, end2); 1452 let two = one && one.matchFragment(this.content, to); 1453 if (!two || !two.validEnd) 1454 return false; 1455 for (let i = start2; i < end2; i++) 1456 if (!this.type.allowsMarks(replacement.child(i).marks)) 1457 return false; 1458 return true; 1459 } 1460 /** 1461 Test whether replacing the range `from` to `to` (by index) with 1462 a node of the given type would leave the node's content valid. 1463 */ 1464 canReplaceWith(from2, to, type, marks) {
vendor: 4,152 bytes, lines 1465-1607
1465 if (marks && !this.type.allowsMarks(marks)) 1466 return false; 1467 let start2 = this.contentMatchAt(from2).matchType(type); 1468 let end2 = start2 && start2.matchFragment(this.content, to); 1469 return end2 ? end2.validEnd : false; 1470 } 1471 /** 1472 Test whether the given node's content could be appended to this 1473 node. If that node is empty, this will only return true if there 1474 is at least one node type that can appear in both nodes (to avoid 1475 merging completely incompatible nodes). 1476 */ 1477 canAppend(other) { 1478 if (other.content.size) 1479 return this.canReplace(this.childCount, this.childCount, other.content); 1480 else 1481 return this.type.compatibleContent(other.type); 1482 } 1483 /** 1484 Check whether this node and its descendants conform to the 1485 schema, and raise error when they do not. 1486 */ 1487 check() { 1488 this.type.checkContent(this.content); 1489 let copy2 = Mark$1.none; 1490 for (let i = 0; i < this.marks.length; i++) 1491 copy2 = this.marks[i].addToSet(copy2); 1492 if (!Mark$1.sameSet(copy2, this.marks)) 1493 throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map((m) => m.type.name)}`); 1494 this.content.forEach((node) => node.check()); 1495 } 1496 /** 1497 Return a JSON-serializeable representation of this node. 1498 */ 1499 toJSON() { 1500 let obj = { type: this.type.name }; 1501 for (let _ in this.attrs) { 1502 obj.attrs = this.attrs; 1503 break; 1504 } 1505 if (this.content.size) 1506 obj.content = this.content.toJSON(); 1507 if (this.marks.length) 1508 obj.marks = this.marks.map((n) => n.toJSON()); 1509 return obj; 1510 } 1511 /** 1512 Deserialize a node from its JSON representation. 1513 */ 1514 static fromJSON(schema, json) { 1515 if (!json) 1516 throw new RangeError("Invalid input for Node.fromJSON"); 1517 let marks = null; 1518 if (json.marks) { 1519 if (!Array.isArray(json.marks)) 1520 throw new RangeError("Invalid mark data for Node.fromJSON"); 1521 marks = json.marks.map(schema.markFromJSON); 1522 } 1523 if (json.type == "text") { 1524 if (typeof json.text != "string") 1525 throw new RangeError("Invalid text node in JSON"); 1526 return schema.text(json.text, marks); 1527 } 1528 let content = Fragment.fromJSON(schema, json.content); 1529 return schema.nodeType(json.type).create(json.attrs, content, marks); 1530 } 1531}; 1532Node$1.prototype.text = void 0; 1533class TextNode extends Node$1 { 1534 /** 1535 @internal 1536 */ 1537 constructor(type, attrs, content, marks) { 1538 super(type, attrs, null, marks); 1539 if (!content) 1540 throw new RangeError("Empty text nodes are not allowed"); 1541 this.text = content; 1542 } 1543 toString() { 1544 if (this.type.spec.toDebugString) 1545 return this.type.spec.toDebugString(this); 1546 return wrapMarks(this.marks, JSON.stringify(this.text)); 1547 } 1548 get textContent() { 1549 return this.text; 1550 } 1551 textBetween(from2, to) { 1552 return this.text.slice(from2, to); 1553 } 1554 get nodeSize() { 1555 return this.text.length; 1556 } 1557 mark(marks) { 1558 return marks == this.marks ? this : new TextNode(this.type, this.attrs, this.text, marks); 1559 } 1560 withText(text) { 1561 if (text == this.text) 1562 return this; 1563 return new TextNode(this.type, this.attrs, text, this.marks); 1564 } 1565 cut(from2 = 0, to = this.text.length) { 1566 if (from2 == 0 && to == this.text.length) 1567 return this; 1568 return this.withText(this.text.slice(from2, to)); 1569 } 1570 eq(other) { 1571 return this.sameMarkup(other) && this.text == other.text; 1572 } 1573 toJSON() { 1574 let base2 = super.toJSON(); 1575 base2.text = this.text; 1576 return base2; 1577 } 1578} 1579function wrapMarks(marks, str) { 1580 for (let i = marks.length - 1; i >= 0; i--) 1581 str = marks[i].type.name + "(" + str + ")"; 1582 return str; 1583} 1584class ContentMatch { 1585 /** 1586 @internal 1587 */ 1588 constructor(validEnd) { 1589 this.validEnd = validEnd; 1590 this.next = []; 1591 this.wrapCache = []; 1592 } 1593 /** 1594 @internal 1595 */ 1596 static parse(string, nodeTypes) { 1597 let stream = new TokenStream(string, nodeTypes); 1598 if (stream.next == null) 1599 return ContentMatch.empty; 1600 let expr = parseExpr(stream); 1601 if (stream.next) 1602 stream.err("Unexpected trailing text"); 1603 let match = dfa(nfa(expr)); 1604 checkForDeadEnds(match, stream); 1605 return match; 1606 } 1607 /**
vendor: 4,668 bytes, lines 1608-1761
1608 Match a node type, returning a match after that node if 1609 successful. 1610 */ 1611 matchType(type) { 1612 for (let i = 0; i < this.next.length; i++) 1613 if (this.next[i].type == type) 1614 return this.next[i].next; 1615 return null; 1616 } 1617 /** 1618 Try to match a fragment. Returns the resulting match when 1619 successful. 1620 */ 1621 matchFragment(frag, start2 = 0, end2 = frag.childCount) { 1622 let cur = this; 1623 for (let i = start2; cur && i < end2; i++) 1624 cur = cur.matchType(frag.child(i).type); 1625 return cur; 1626 } 1627 /** 1628 @internal 1629 */ 1630 get inlineContent() { 1631 return this.next.length != 0 && this.next[0].type.isInline; 1632 } 1633 /** 1634 Get the first matching node type at this match position that can 1635 be generated. 1636 */ 1637 get defaultType() { 1638 for (let i = 0; i < this.next.length; i++) { 1639 let { type } = this.next[i]; 1640 if (!(type.isText || type.hasRequiredAttrs())) 1641 return type; 1642 } 1643 return null; 1644 } 1645 /** 1646 @internal 1647 */ 1648 compatible(other) { 1649 for (let i = 0; i < this.next.length; i++) 1650 for (let j = 0; j < other.next.length; j++) 1651 if (this.next[i].type == other.next[j].type) 1652 return true; 1653 return false; 1654 } 1655 /** 1656 Try to match the given fragment, and if that fails, see if it can 1657 be made to match by inserting nodes in front of it. When 1658 successful, return a fragment of inserted nodes (which may be 1659 empty if nothing had to be inserted). When `toEnd` is true, only 1660 return a fragment if the resulting match goes to the end of the 1661 content expression. 1662 */ 1663 fillBefore(after, toEnd = false, startIndex = 0) { 1664 let seen = [this]; 1665 function search(match, types) { 1666 let finished = match.matchFragment(after, startIndex); 1667 if (finished && (!toEnd || finished.validEnd)) 1668 return Fragment.from(types.map((tp) => tp.createAndFill())); 1669 for (let i = 0; i < match.next.length; i++) { 1670 let { type, next } = match.next[i]; 1671 if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) { 1672 seen.push(next); 1673 let found2 = search(next, types.concat(type)); 1674 if (found2) 1675 return found2; 1676 } 1677 } 1678 return null; 1679 } 1680 return search(this, []); 1681 } 1682 /** 1683 Find a set of wrapping node types that would allow a node of the 1684 given type to appear at this position. The result may be empty 1685 (when it fits directly) and will be null when no such wrapping 1686 exists. 1687 */ 1688 findWrapping(target) { 1689 for (let i = 0; i < this.wrapCache.length; i += 2) 1690 if (this.wrapCache[i] == target) 1691 return this.wrapCache[i + 1]; 1692 let computed = this.computeWrapping(target); 1693 this.wrapCache.push(target, computed); 1694 return computed; 1695 } 1696 /** 1697 @internal 1698 */ 1699 computeWrapping(target) { 1700 let seen = /* @__PURE__ */ Object.create(null), active = [{ match: this, type: null, via: null }]; 1701 while (active.length) { 1702 let current = active.shift(), match = current.match; 1703 if (match.matchType(target)) { 1704 let result = []; 1705 for (let obj = current; obj.type; obj = obj.via) 1706 result.push(obj.type); 1707 return result.reverse(); 1708 } 1709 for (let i = 0; i < match.next.length; i++) { 1710 let { type, next } = match.next[i]; 1711 if (!type.isLeaf && !type.hasRequiredAttrs() && !(type.name in seen) && (!current.type || next.validEnd)) { 1712 active.push({ match: type.contentMatch, type, via: current }); 1713 seen[type.name] = true; 1714 } 1715 } 1716 } 1717 return null; 1718 } 1719 /** 1720 The number of outgoing edges this node has in the finite 1721 automaton that describes the content expression. 1722 */ 1723 get edgeCount() { 1724 return this.next.length; 1725 } 1726 /** 1727 Get the _n_âth outgoing edge from this node in the finite 1728 automaton that describes the content expression. 1729 */ 1730 edge(n) { 1731 if (n >= this.next.length) 1732 throw new RangeError(`There's no ${n}th edge in this content match`); 1733 return this.next[n]; 1734 } 1735 /** 1736 @internal 1737 */ 1738 toString() { 1739 let seen = []; 1740 function scan(m) { 1741 seen.push(m); 1742 for (let i = 0; i < m.next.length; i++) 1743 if (seen.indexOf(m.next[i].next) == -1) 1744 scan(m.next[i].next); 1745 } 1746 scan(this); 1747 return seen.map((m, i) => { 1748 let out = i + (m.validEnd ? "*" : " ") + " "; 1749 for (let i2 = 0; i2 < m.next.length; i2++) 1750 out += (i2 ? ", " : "") + m.next[i2].type.name + "->" + seen.indexOf(m.next[i2].next); 1751 return out; 1752 }).join("\n"); 1753 } 1754} 1755ContentMatch.empty = new ContentMatch(true); 1756class TokenStream { 1757 constructor(string, nodeTypes) { 1758 this.string = string; 1759 this.nodeTypes = nodeTypes; 1760 this.inline = null; 1761 this.pos = 0;
vendor: 15,881 bytes, lines 1762-2290
1762 this.tokens = string.split(/\s*(?=\b|\W|$)/); 1763 if (this.tokens[this.tokens.length - 1] == "") 1764 this.tokens.pop(); 1765 if (this.tokens[0] == "") 1766 this.tokens.shift(); 1767 } 1768 get next() { 1769 return this.tokens[this.pos]; 1770 } 1771 eat(tok) { 1772 return this.next == tok && (this.pos++ || true); 1773 } 1774 err(str) { 1775 throw new SyntaxError(str + " (in content expression '" + this.string + "')"); 1776 } 1777} 1778function parseExpr(stream) { 1779 let exprs = []; 1780 do { 1781 exprs.push(parseExprSeq(stream)); 1782 } while (stream.eat("|")); 1783 return exprs.length == 1 ? exprs[0] : { type: "choice", exprs }; 1784} 1785function parseExprSeq(stream) { 1786 let exprs = []; 1787 do { 1788 exprs.push(parseExprSubscript(stream)); 1789 } while (stream.next && stream.next != ")" && stream.next != "|"); 1790 return exprs.length == 1 ? exprs[0] : { type: "seq", exprs }; 1791} 1792function parseExprSubscript(stream) { 1793 let expr = parseExprAtom(stream); 1794 for (; ; ) { 1795 if (stream.eat("+")) 1796 expr = { type: "plus", expr }; 1797 else if (stream.eat("*")) 1798 expr = { type: "star", expr }; 1799 else if (stream.eat("?")) 1800 expr = { type: "opt", expr }; 1801 else if (stream.eat("{")) 1802 expr = parseExprRange(stream, expr); 1803 else 1804 break; 1805 } 1806 return expr; 1807} 1808function parseNum(stream) { 1809 if (/\D/.test(stream.next)) 1810 stream.err("Expected number, got '" + stream.next + "'"); 1811 let result = Number(stream.next); 1812 stream.pos++; 1813 return result; 1814} 1815function parseExprRange(stream, expr) { 1816 let min2 = parseNum(stream), max2 = min2; 1817 if (stream.eat(",")) { 1818 if (stream.next != "}") 1819 max2 = parseNum(stream); 1820 else 1821 max2 = -1; 1822 } 1823 if (!stream.eat("}")) 1824 stream.err("Unclosed braced range"); 1825 return { type: "range", min: min2, max: max2, expr }; 1826} 1827function resolveName(stream, name) { 1828 let types = stream.nodeTypes, type = types[name]; 1829 if (type) 1830 return [type]; 1831 let result = []; 1832 for (let typeName in types) { 1833 let type2 = types[typeName]; 1834 if (type2.groups.indexOf(name) > -1) 1835 result.push(type2); 1836 } 1837 if (result.length == 0) 1838 stream.err("No node type or group '" + name + "' found"); 1839 return result; 1840} 1841function parseExprAtom(stream) { 1842 if (stream.eat("(")) { 1843 let expr = parseExpr(stream); 1844 if (!stream.eat(")")) 1845 stream.err("Missing closing paren"); 1846 return expr; 1847 } else if (!/\W/.test(stream.next)) { 1848 let exprs = resolveName(stream, stream.next).map((type) => { 1849 if (stream.inline == null) 1850 stream.inline = type.isInline; 1851 else if (stream.inline != type.isInline) 1852 stream.err("Mixing inline and block content"); 1853 return { type: "name", value: type }; 1854 }); 1855 stream.pos++; 1856 return exprs.length == 1 ? exprs[0] : { type: "choice", exprs }; 1857 } else { 1858 stream.err("Unexpected token '" + stream.next + "'"); 1859 } 1860} 1861function nfa(expr) { 1862 let nfa2 = [[]]; 1863 connect(compile(expr, 0), node()); 1864 return nfa2; 1865 function node() { 1866 return nfa2.push([]) - 1; 1867 } 1868 function edge(from2, to, term) { 1869 let edge2 = { term, to }; 1870 nfa2[from2].push(edge2); 1871 return edge2; 1872 } 1873 function connect(edges, to) { 1874 edges.forEach((edge2) => edge2.to = to); 1875 } 1876 function compile(expr2, from2) { 1877 if (expr2.type == "choice") { 1878 return expr2.exprs.reduce((out, expr3) => out.concat(compile(expr3, from2)), []); 1879 } else if (expr2.type == "seq") { 1880 for (let i = 0; ; i++) { 1881 let next = compile(expr2.exprs[i], from2); 1882 if (i == expr2.exprs.length - 1) 1883 return next; 1884 connect(next, from2 = node()); 1885 } 1886 } else if (expr2.type == "star") { 1887 let loop = node(); 1888 edge(from2, loop); 1889 connect(compile(expr2.expr, loop), loop); 1890 return [edge(loop)]; 1891 } else if (expr2.type == "plus") { 1892 let loop = node(); 1893 connect(compile(expr2.expr, from2), loop); 1894 connect(compile(expr2.expr, loop), loop); 1895 return [edge(loop)]; 1896 } else if (expr2.type == "opt") { 1897 return [edge(from2)].concat(compile(expr2.expr, from2)); 1898 } else if (expr2.type == "range") { 1899 let cur = from2; 1900 for (let i = 0; i < expr2.min; i++) { 1901 let next = node(); 1902 connect(compile(expr2.expr, cur), next); 1903 cur = next; 1904 } 1905 if (expr2.max == -1) { 1906 connect(compile(expr2.expr, cur), cur); 1907 } else { 1908 for (let i = expr2.min; i < expr2.max; i++) { 1909 let next = node(); 1910 edge(cur, next); 1911 connect(compile(expr2.expr, cur), next); 1912 cur = next; 1913 } 1914 } 1915 return [edge(cur)]; 1916 } else if (expr2.type == "name") { 1917 return [edge(from2, void 0, expr2.value)]; 1918 } else { 1919 throw new Error("Unknown expr type"); 1920 } 1921 } 1922} 1923function cmp(a, b) { 1924 return b - a; 1925} 1926function nullFrom(nfa2, node) { 1927 let result = []; 1928 scan(node); 1929 return result.sort(cmp); 1930 function scan(node2) { 1931 let edges = nfa2[node2]; 1932 if (edges.length == 1 && !edges[0].term) 1933 return scan(edges[0].to); 1934 result.push(node2); 1935 for (let i = 0; i < edges.length; i++) { 1936 let { term, to } = edges[i]; 1937 if (!term && result.indexOf(to) == -1) 1938 scan(to); 1939 } 1940 } 1941} 1942function dfa(nfa2) { 1943 let labeled = /* @__PURE__ */ Object.create(null); 1944 return explore(nullFrom(nfa2, 0)); 1945 function explore(states) { 1946 let out = []; 1947 states.forEach((node) => { 1948 nfa2[node].forEach(({ term, to }) => { 1949 if (!term) 1950 return; 1951 let set; 1952 for (let i = 0; i < out.length; i++) 1953 if (out[i][0] == term) 1954 set = out[i][1]; 1955 nullFrom(nfa2, to).forEach((node2) => { 1956 if (!set) 1957 out.push([term, set = []]); 1958 if (set.indexOf(node2) == -1) 1959 set.push(node2); 1960 }); 1961 }); 1962 }); 1963 let state = labeled[states.join(",")] = new ContentMatch(states.indexOf(nfa2.length - 1) > -1); 1964 for (let i = 0; i < out.length; i++) { 1965 let states2 = out[i][1].sort(cmp); 1966 state.next.push({ type: out[i][0], next: labeled[states2.join(",")] || explore(states2) }); 1967 } 1968 return state; 1969 } 1970} 1971function checkForDeadEnds(match, stream) { 1972 for (let i = 0, work = [match]; i < work.length; i++) { 1973 let state = work[i], dead = !state.validEnd, nodes = []; 1974 for (let j = 0; j < state.next.length; j++) { 1975 let { type, next } = state.next[j]; 1976 nodes.push(type.name); 1977 if (dead && !(type.isText || type.hasRequiredAttrs())) 1978 dead = false; 1979 if (work.indexOf(next) == -1) 1980 work.push(next); 1981 } 1982 if (dead) 1983 stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)"); 1984 } 1985} 1986function defaultAttrs(attrs) { 1987 let defaults2 = /* @__PURE__ */ Object.create(null); 1988 for (let attrName in attrs) { 1989 let attr = attrs[attrName]; 1990 if (!attr.hasDefault) 1991 return null; 1992 defaults2[attrName] = attr.default; 1993 } 1994 return defaults2; 1995} 1996function computeAttrs(attrs, value) { 1997 let built = /* @__PURE__ */ Object.create(null); 1998 for (let name in attrs) { 1999 let given = value && value[name]; 2000 if (given === void 0) { 2001 let attr = attrs[name]; 2002 if (attr.hasDefault) 2003 given = attr.default; 2004 else 2005 throw new RangeError("No value supplied for attribute " + name); 2006 } 2007 built[name] = given; 2008 } 2009 return built; 2010} 2011function initAttrs(attrs) { 2012 let result = /* @__PURE__ */ Object.create(null); 2013 if (attrs) 2014 for (let name in attrs) 2015 result[name] = new Attribute(attrs[name]); 2016 return result; 2017} 2018let NodeType$1 = class NodeType { 2019 /** 2020 @internal 2021 */ 2022 constructor(name, schema, spec) { 2023 this.name = name; 2024 this.schema = schema; 2025 this.spec = spec; 2026 this.markSet = null; 2027 this.groups = spec.group ? spec.group.split(" ") : []; 2028 this.attrs = initAttrs(spec.attrs); 2029 this.defaultAttrs = defaultAttrs(this.attrs); 2030 this.contentMatch = null; 2031 this.inlineContent = null; 2032 this.isBlock = !(spec.inline || name == "text"); 2033 this.isText = name == "text"; 2034 } 2035 /** 2036 True if this is an inline type. 2037 */ 2038 get isInline() { 2039 return !this.isBlock; 2040 } 2041 /** 2042 True if this is a textblock type, a block that contains inline 2043 content. 2044 */ 2045 get isTextblock() { 2046 return this.isBlock && this.inlineContent; 2047 } 2048 /** 2049 True for node types that allow no content. 2050 */ 2051 get isLeaf() { 2052 return this.contentMatch == ContentMatch.empty; 2053 } 2054 /** 2055 True when this node is an atom, i.e. when it does not have 2056 directly editable content. 2057 */ 2058 get isAtom() { 2059 return this.isLeaf || !!this.spec.atom; 2060 } 2061 /** 2062 The node type's [whitespace](https://prosemirror.net/docs/ref/#model.NodeSpec.whitespace) option. 2063 */ 2064 get whitespace() { 2065 return this.spec.whitespace || (this.spec.code ? "pre" : "normal"); 2066 } 2067 /** 2068 Tells you whether this node type has any required attributes. 2069 */ 2070 hasRequiredAttrs() { 2071 for (let n in this.attrs) 2072 if (this.attrs[n].isRequired) 2073 return true; 2074 return false; 2075 } 2076 /** 2077 Indicates whether this node allows some of the same content as 2078 the given node type. 2079 */ 2080 compatibleContent(other) { 2081 return this == other || this.contentMatch.compatible(other.contentMatch); 2082 } 2083 /** 2084 @internal 2085 */ 2086 computeAttrs(attrs) { 2087 if (!attrs && this.defaultAttrs) 2088 return this.defaultAttrs; 2089 else 2090 return computeAttrs(this.attrs, attrs); 2091 } 2092 /** 2093 Create a `Node` of this type. The given attributes are 2094 checked and defaulted (you can pass `null` to use the type's 2095 defaults entirely, if no required attributes exist). `content` 2096 may be a `Fragment`, a node, an array of nodes, or 2097 `null`. Similarly `marks` may be `null` to default to the empty 2098 set of marks. 2099 */ 2100 create(attrs = null, content, marks) { 2101 if (this.isText) 2102 throw new Error("NodeType.create can't construct text nodes"); 2103 return new Node$1(this, this.computeAttrs(attrs), Fragment.from(content), Mark$1.setFrom(marks)); 2104 } 2105 /** 2106 Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but check the given content 2107 against the node type's content restrictions, and throw an error 2108 if it doesn't match. 2109 */ 2110 createChecked(attrs = null, content, marks) { 2111 content = Fragment.from(content); 2112 this.checkContent(content); 2113 return new Node$1(this, this.computeAttrs(attrs), content, Mark$1.setFrom(marks)); 2114 } 2115 /** 2116 Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but see if it is 2117 necessary to add nodes to the start or end of the given fragment 2118 to make it fit the node. If no fitting wrapping can be found, 2119 return null. Note that, due to the fact that required nodes can 2120 always be created, this will always succeed if you pass null or 2121 `Fragment.empty` as content. 2122 */ 2123 createAndFill(attrs = null, content, marks) { 2124 attrs = this.computeAttrs(attrs); 2125 content = Fragment.from(content); 2126 if (content.size) { 2127 let before = this.contentMatch.fillBefore(content); 2128 if (!before) 2129 return null; 2130 content = before.append(content); 2131 } 2132 let matched = this.contentMatch.matchFragment(content); 2133 let after = matched && matched.fillBefore(Fragment.empty, true); 2134 if (!after) 2135 return null; 2136 return new Node$1(this, attrs, content.append(after), Mark$1.setFrom(marks)); 2137 } 2138 /** 2139 Returns true if the given fragment is valid content for this node 2140 type with the given attributes. 2141 */ 2142 validContent(content) { 2143 let result = this.contentMatch.matchFragment(content); 2144 if (!result || !result.validEnd) 2145 return false; 2146 for (let i = 0; i < content.childCount; i++) 2147 if (!this.allowsMarks(content.child(i).marks)) 2148 return false; 2149 return true; 2150 } 2151 /** 2152 Throws a RangeError if the given fragment is not valid content for this 2153 node type. 2154 @internal 2155 */ 2156 checkContent(content) { 2157 if (!this.validContent(content)) 2158 throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`); 2159 } 2160 /** 2161 Check whether the given mark type is allowed in this node. 2162 */ 2163 allowsMarkType(markType) { 2164 return this.markSet == null || this.markSet.indexOf(markType) > -1; 2165 } 2166 /** 2167 Test whether the given set of marks are allowed in this node. 2168 */ 2169 allowsMarks(marks) { 2170 if (this.markSet == null) 2171 return true; 2172 for (let i = 0; i < marks.length; i++) 2173 if (!this.allowsMarkType(marks[i].type)) 2174 return false; 2175 return true; 2176 } 2177 /** 2178 Removes the marks that are not allowed in this node from the given set. 2179 */ 2180 allowedMarks(marks) { 2181 if (this.markSet == null) 2182 return marks; 2183 let copy2; 2184 for (let i = 0; i < marks.length; i++) { 2185 if (!this.allowsMarkType(marks[i].type)) { 2186 if (!copy2) 2187 copy2 = marks.slice(0, i); 2188 } else if (copy2) { 2189 copy2.push(marks[i]); 2190 } 2191 } 2192 return !copy2 ? marks : copy2.length ? copy2 : Mark$1.none; 2193 } 2194 /** 2195 @internal 2196 */ 2197 static compile(nodes, schema) { 2198 let result = /* @__PURE__ */ Object.create(null); 2199 nodes.forEach((name, spec) => result[name] = new NodeType(name, schema, spec)); 2200 let topType = schema.spec.topNode || "doc"; 2201 if (!result[topType]) 2202 throw new RangeError("Schema is missing its top node type ('" + topType + "')"); 2203 if (!result.text) 2204 throw new RangeError("Every schema needs a 'text' type"); 2205 for (let _ in result.text.attrs) 2206 throw new RangeError("The text node type should not have attributes"); 2207 return result; 2208 } 2209}; 2210class Attribute { 2211 constructor(options) { 2212 this.hasDefault = Object.prototype.hasOwnProperty.call(options, "default"); 2213 this.default = options.default; 2214 } 2215 get isRequired() { 2216 return !this.hasDefault; 2217 } 2218} 2219class MarkType { 2220 /** 2221 @internal 2222 */ 2223 constructor(name, rank, schema, spec) { 2224 this.name = name; 2225 this.rank = rank; 2226 this.schema = schema; 2227 this.spec = spec; 2228 this.attrs = initAttrs(spec.attrs); 2229 this.excluded = null; 2230 let defaults2 = defaultAttrs(this.attrs); 2231 this.instance = defaults2 ? new Mark$1(this, defaults2) : null; 2232 } 2233 /** 2234 Create a mark of this type. `attrs` may be `null` or an object 2235 containing only some of the mark's attributes. The others, if 2236 they have defaults, will be added. 2237 */ 2238 create(attrs = null) { 2239 if (!attrs && this.instance) 2240 return this.instance; 2241 return new Mark$1(this, computeAttrs(this.attrs, attrs)); 2242 } 2243 /** 2244 @internal 2245 */ 2246 static compile(marks, schema) { 2247 let result = /* @__PURE__ */ Object.create(null), rank = 0; 2248 marks.forEach((name, spec) => result[name] = new MarkType(name, rank++, schema, spec)); 2249 return result; 2250 } 2251 /** 2252 When there is a mark of this type in the given set, a new set 2253 without it is returned. Otherwise, the input set is returned. 2254 */ 2255 removeFromSet(set) { 2256 for (var i = 0; i < set.length; i++) 2257 if (set[i].type == this) { 2258 set = set.slice(0, i).concat(set.slice(i + 1)); 2259 i--; 2260 } 2261 return set; 2262 } 2263 /** 2264 Tests whether there is a mark of this type in the given set. 2265 */ 2266 isInSet(set) { 2267 for (let i = 0; i < set.length; i++) 2268 if (set[i].type == this) 2269 return set[i]; 2270 } 2271 /** 2272 Queries whether a given mark type is 2273 [excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one. 2274 */ 2275 excludes(other) { 2276 return this.excluded.indexOf(other) > -1; 2277 } 2278} 2279class Schema { 2280 /** 2281 Construct a schema from a schema [specification](https://prosemirror.net/docs/ref/#model.SchemaSpec). 2282 */ 2283 constructor(spec) { 2284 this.linebreakReplacement = null; 2285 this.cached = /* @__PURE__ */ Object.create(null); 2286 let instanceSpec = this.spec = {}; 2287 for (let prop in spec) 2288 instanceSpec[prop] = spec[prop]; 2289 instanceSpec.nodes = OrderedMap.from(spec.nodes), instanceSpec.marks = OrderedMap.from(spec.marks || {}), this.nodes = NodeType$1.compile(this.spec.nodes, this); 2290 this.marks = MarkType.compile(this.spec.marks, this);
vendor: 3,829 bytes, lines 2291-2404
2291 let contentExprCache = /* @__PURE__ */ Object.create(null); 2292 for (let prop in this.nodes) { 2293 if (prop in this.marks) 2294 throw new RangeError(prop + " can not be both a node and a mark"); 2295 let type = this.nodes[prop], contentExpr = type.spec.content || "", markExpr = type.spec.marks; 2296 type.contentMatch = contentExprCache[contentExpr] || (contentExprCache[contentExpr] = ContentMatch.parse(contentExpr, this.nodes)); 2297 type.inlineContent = type.contentMatch.inlineContent; 2298 if (type.spec.linebreakReplacement) { 2299 if (this.linebreakReplacement) 2300 throw new RangeError("Multiple linebreak nodes defined"); 2301 if (!type.isInline || !type.isLeaf) 2302 throw new RangeError("Linebreak replacement nodes must be inline leaf nodes"); 2303 this.linebreakReplacement = type; 2304 } 2305 type.markSet = markExpr == "_" ? null : markExpr ? gatherMarks(this, markExpr.split(" ")) : markExpr == "" || !type.inlineContent ? [] : null; 2306 } 2307 for (let prop in this.marks) { 2308 let type = this.marks[prop], excl = type.spec.excludes; 2309 type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" ")); 2310 } 2311 this.nodeFromJSON = this.nodeFromJSON.bind(this); 2312 this.markFromJSON = this.markFromJSON.bind(this); 2313 this.topNodeType = this.nodes[this.spec.topNode || "doc"]; 2314 this.cached.wrappings = /* @__PURE__ */ Object.create(null); 2315 } 2316 /** 2317 Create a node in this schema. The `type` may be a string or a 2318 `NodeType` instance. Attributes will be extended with defaults, 2319 `content` may be a `Fragment`, `null`, a `Node`, or an array of 2320 nodes. 2321 */ 2322 node(type, attrs = null, content, marks) { 2323 if (typeof type == "string") 2324 type = this.nodeType(type); 2325 else if (!(type instanceof NodeType$1)) 2326 throw new RangeError("Invalid node type: " + type); 2327 else if (type.schema != this) 2328 throw new RangeError("Node type from different schema used (" + type.name + ")"); 2329 return type.createChecked(attrs, content, marks); 2330 } 2331 /** 2332 Create a text node in the schema. Empty text nodes are not 2333 allowed. 2334 */ 2335 text(text, marks) { 2336 let type = this.nodes.text; 2337 return new TextNode(type, type.defaultAttrs, text, Mark$1.setFrom(marks)); 2338 } 2339 /** 2340 Create a mark with the given type and attributes. 2341 */ 2342 mark(type, attrs) { 2343 if (typeof type == "string") 2344 type = this.marks[type]; 2345 return type.create(attrs); 2346 } 2347 /** 2348 Deserialize a node from its JSON representation. This method is 2349 bound. 2350 */ 2351 nodeFromJSON(json) { 2352 return Node$1.fromJSON(this, json); 2353 } 2354 /** 2355 Deserialize a mark from its JSON representation. This method is 2356 bound. 2357 */ 2358 markFromJSON(json) { 2359 return Mark$1.fromJSON(this, json); 2360 } 2361 /** 2362 @internal 2363 */ 2364 nodeType(name) { 2365 let found2 = this.nodes[name]; 2366 if (!found2) 2367 throw new RangeError("Unknown node type: " + name); 2368 return found2; 2369 } 2370} 2371function gatherMarks(schema, marks) { 2372 let found2 = []; 2373 for (let i = 0; i < marks.length; i++) { 2374 let name = marks[i], mark = schema.marks[name], ok = mark; 2375 if (mark) { 2376 found2.push(mark); 2377 } else { 2378 for (let prop in schema.marks) { 2379 let mark2 = schema.marks[prop]; 2380 if (name == "_" || mark2.spec.group && mark2.spec.group.split(" ").indexOf(name) > -1) 2381 found2.push(ok = mark2); 2382 } 2383 } 2384 if (!ok) 2385 throw new SyntaxError("Unknown mark type: '" + marks[i] + "'"); 2386 } 2387 return found2; 2388} 2389function isTagRule(rule) { 2390 return rule.tag != null; 2391} 2392function isStyleRule(rule) { 2393 return rule.style != null; 2394} 2395class DOMParser { 2396 /** 2397 Create a parser that targets the given schema, using the given 2398 parsing rules. 2399 */ 2400 constructor(schema, rules) { 2401 this.schema = schema; 2402 this.rules = rules; 2403 this.tags = []; 2404 this.styles = [];
2405 rules.forEach((rule) => { 2406 if (isTagRule(rule)) 2407 this.tags.push(rule); 2408 else if (isStyleRule(rule)) 2409 this.styles.push(rule); 2410 }); 2411 this.normalizeLists = !this.tags.some((r) => { 2412 if (!/^(ul|ol)\b/.test(r.tag) || !r.node) 2413 return false; 2414 let node = schema.nodes[r.node]; 2415 return node.contentMatch.matchType(node); 2416 }); 2417 } 2418 /** 2419 Parse a document from the content of a DOM node. 2420 */ 2421 parse(dom, options = {}) { 2422 let context = new ParseContext(this, options, false); 2423 context.addAll(dom, options.from, options.to); 2424 return context.finish(); 2425 } 2426 /** 2427 Parses the content of the given DOM node, like 2428 [`parse`](https://prosemirror.net/docs/ref/#model.DOMParser.parse), and takes the same set of 2429 options. But unlike that method, which produces a whole node, 2430 this one returns a slice that is open at the sides, meaning that 2431 the schema constraints aren't applied to the start of nodes to 2432 the left of the input and the end of nodes at the end. 2433 */ 2434 parseSlice(dom, options = {}) {
2435 let context = new ParseContext(this, options, true); 2436 context.addAll(dom, options.from, options.to); 2437 return Slice.maxOpen(context.finish()); 2438 } 2439 /** 2440 @internal 2441 */ 2442 matchTag(dom, context, after) { 2443 for (let i = after ? this.tags.indexOf(after) + 1 : 0; i < this.tags.length; i++) { 2444 let rule = this.tags[i]; 2445 if (matches(dom, rule.tag) && (rule.namespace === void 0 || dom.namespaceURI == rule.namespace) && (!rule.context || context.matchesContext(rule.context))) { 2446 if (rule.getAttrs) { 2447 let result = rule.getAttrs(dom); 2448 if (result === false) 2449 continue; 2450 rule.attrs = result || void 0; 2451 } 2452 return rule; 2453 } 2454 } 2455 } 2456 /** 2457 @internal 2458 */ 2459 matchStyle(prop, value, context, after) { 2460 for (let i = after ? this.styles.indexOf(after) + 1 : 0; i < this.styles.length; i++) { 2461 let rule = this.styles[i], style2 = rule.style; 2462 if (style2.indexOf(prop) != 0 || rule.context && !context.matchesContext(rule.context) || // Test that the style string either precisely matches the prop, 2463 // or has an '=' sign after the prop, followed by the given 2464 // value. 2465 style2.length > prop.length && (style2.charCodeAt(prop.length) != 61 || style2.slice(prop.length + 1) != value)) 2466 continue; 2467 if (rule.getAttrs) { 2468 let result = rule.getAttrs(value); 2469 if (result === false) 2470 continue; 2471 rule.attrs = result || void 0; 2472 } 2473 return rule; 2474 } 2475 } 2476 /** 2477 @internal 2478 */ 2479 static schemaRules(schema) { 2480 let result = []; 2481 function insert(rule) { 2482 let priority = rule.priority == null ? 50 : rule.priority, i = 0; 2483 for (; i < result.length; i++) { 2484 let next = result[i], nextPriority = next.priority == null ? 50 : next.priority; 2485 if (nextPriority < priority) 2486 break; 2487 } 2488 result.splice(i, 0, rule); 2489 } 2490 for (let name in schema.marks) { 2491 let rules = schema.marks[name].spec.parseDOM; 2492 if (rules)
2493 rules.forEach((rule) => { 2494 insert(rule = copy(rule)); 2495 if (!(rule.mark || rule.ignore || rule.clearMark)) 2496 rule.mark = name; 2497 }); 2498 } 2499 for (let name in schema.nodes) { 2500 let rules = schema.nodes[name].spec.parseDOM; 2501 if (rules) 2502 rules.forEach((rule) => { 2503 insert(rule = copy(rule)); 2504 if (!(rule.node || rule.ignore || rule.mark)) 2505 rule.node = name; 2506 }); 2507 } 2508 return result; 2509 } 2510 /** 2511 Construct a DOM parser using the parsing rules listed in a 2512 schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by 2513 [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority). 2514 */ 2515 static fromSchema(schema) { 2516 return schema.cached.domParser || (schema.cached.domParser = new DOMParser(schema, DOMParser.schemaRules(schema))); 2517 } 2518} 2519const blockTags = { 2520 address: true, 2521 article: true, 2522 aside: true, 2523 blockquote: true, 2524 canvas: true, 2525 dd: true, 2526 div: true, 2527 dl: true, 2528 fieldset: true, 2529 figcaption: true, 2530 figure: true, 2531 footer: true, 2532 form: true, 2533 h1: true, 2534 h2: true, 2535 h3: true, 2536 h4: true, 2537 h5: true, 2538 h6: true, 2539 header: true, 2540 hgroup: true, 2541 hr: true, 2542 li: true, 2543 noscript: true, 2544 ol: true, 2545 output: true, 2546 p: true, 2547 pre: true, 2548 section: true, 2549 table: true, 2550 tfoot: true, 2551 ul: true 2552}; 2553const ignoreTags = { 2554 head: true, 2555 noscript: true, 2556 object: true, 2557 script: true, 2558 style: true, 2559 title: true 2560}; 2561const listTags = { ol: true, ul: true }; 2562const OPT_PRESERVE_WS = 1, OPT_PRESERVE_WS_FULL = 2, OPT_OPEN_LEFT = 4; 2563function wsOptionsFor(type, preserveWhitespace, base2) { 2564 if (preserveWhitespace != null) 2565 return (preserveWhitespace ? OPT_PRESERVE_WS : 0) | (preserveWhitespace === "full" ? OPT_PRESERVE_WS_FULL : 0); 2566 return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base2 & ~OPT_OPEN_LEFT; 2567} 2568class NodeContext { 2569 constructor(type, attrs, marks, pendingMarks, solid, match, options) { 2570 this.type = type; 2571 this.attrs = attrs; 2572 this.marks = marks; 2573 this.pendingMarks = pendingMarks; 2574 this.solid = solid; 2575 this.options = options; 2576 this.content = []; 2577 this.activeMarks = Mark$1.none; 2578 this.stashMarks = []; 2579 this.match = match || (options & OPT_OPEN_LEFT ? null : type.contentMatch); 2580 } 2581 findWrapping(node) { 2582 if (!this.match) { 2583 if (!this.type) 2584 return []; 2585 let fill = this.type.contentMatch.fillBefore(Fragment.from(node)); 2586 if (fill) { 2587 this.match = this.type.contentMatch.matchFragment(fill); 2588 } else { 2589 let start2 = this.type.contentMatch, wrap2; 2590 if (wrap2 = start2.findWrapping(node.type)) { 2591 this.match = start2; 2592 return wrap2; 2593 } else { 2594 return null; 2595 } 2596 } 2597 } 2598 return this.match.findWrapping(node.type); 2599 } 2600 finish(openEnd) { 2601 if (!(this.options & OPT_PRESERVE_WS)) { 2602 let last = this.content[this.content.length - 1], m; 2603 if (last && last.isText && (m = /[ \t\r\n\u000c]+$/.exec(last.text))) { 2604 let text = last; 2605 if (last.text.length == m[0].length) 2606 this.content.pop(); 2607 else 2608 this.content[this.content.length - 1] = text.withText(text.text.slice(0, text.text.length - m[0].length)); 2609 } 2610 } 2611 let content = Fragment.from(this.content); 2612 if (!openEnd && this.match) 2613 content = content.append(this.match.fillBefore(Fragment.empty, true)); 2614 return this.type ? this.type.create(this.attrs, content, this.marks) : content; 2615 } 2616 popFromStashMark(mark) { 2617 for (let i = this.stashMarks.length - 1; i >= 0; i--) 2618 if (mark.eq(this.stashMarks[i])) 2619 return this.stashMarks.splice(i, 1)[0]; 2620 } 2621 applyPending(nextType) { 2622 for (let i = 0, pending = this.pendingMarks; i < pending.length; i++) { 2623 let mark = pending[i]; 2624 if ((this.type ? this.type.allowsMarkType(mark.type) : markMayApply(mark.type, nextType)) && !mark.isInSet(this.activeMarks)) { 2625 this.activeMarks = mark.addToSet(this.activeMarks); 2626 this.pendingMarks = mark.removeFromSet(this.pendingMarks); 2627 } 2628 } 2629 } 2630 inlineContext(node) {
2631 if (this.type) 2632 return this.type.inlineContent; 2633 if (this.content.length) 2634 return this.content[0].isInline; 2635 return node.parentNode && !blockTags.hasOwnProperty(node.parentNode.nodeName.toLowerCase()); 2636 } 2637} 2638class ParseContext { 2639 constructor(parser, options, isOpen) { 2640 this.parser = parser; 2641 this.options = options; 2642 this.isOpen = isOpen; 2643 this.open = 0; 2644 let topNode = options.topNode, topContext; 2645 let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0); 2646 if (topNode) 2647 topContext = new NodeContext(topNode.type, topNode.attrs, Mark$1.none, Mark$1.none, true, options.topMatch || topNode.type.contentMatch, topOptions); 2648 else if (isOpen) 2649 topContext = new NodeContext(null, null, Mark$1.none, Mark$1.none, true, null, topOptions); 2650 else 2651 topContext = new NodeContext(parser.schema.topNodeType, null, Mark$1.none, Mark$1.none, true, null, topOptions); 2652 this.nodes = [topContext]; 2653 this.find = options.findPositions; 2654 this.needsBlock = false; 2655 } 2656 get top() { 2657 return this.nodes[this.open]; 2658 } 2659 // Add a DOM node to the content. Text is inserted as text node, 2660 // otherwise, the node is passed to `addElement` or, if it has a 2661 // `style` attribute, `addElementWithStyles`. 2662 addDOM(dom) { 2663 if (dom.nodeType == 3) 2664 this.addTextNode(dom); 2665 else if (dom.nodeType == 1) 2666 this.addElement(dom); 2667 } 2668 withStyleRules(dom, f) { 2669 let style2 = dom.getAttribute("style"); 2670 if (!style2) 2671 return f(); 2672 let marks = this.readStyles(parseStyles(style2)); 2673 if (!marks) 2674 return; 2675 let [addMarks, removeMarks] = marks, top2 = this.top; 2676 for (let i = 0; i < removeMarks.length; i++) 2677 this.removePendingMark(removeMarks[i], top2); 2678 for (let i = 0; i < addMarks.length; i++) 2679 this.addPendingMark(addMarks[i]); 2680 f(); 2681 for (let i = 0; i < addMarks.length; i++) 2682 this.removePendingMark(addMarks[i], top2); 2683 for (let i = 0; i < removeMarks.length; i++) 2684 this.addPendingMark(removeMarks[i]); 2685 } 2686 addTextNode(dom) { 2687 let value = dom.nodeValue; 2688 let top2 = this.top; 2689 if (top2.options & OPT_PRESERVE_WS_FULL || top2.inlineContext(dom) || /[^ \t\r\n\u000c]/.test(value)) { 2690 if (!(top2.options & OPT_PRESERVE_WS)) { 2691 value = value.replace(/[ \t\r\n\u000c]+/g, " "); 2692 if (/^[ \t\r\n\u000c]/.test(value) && this.open == this.nodes.length - 1) { 2693 let nodeBefore = top2.content[top2.content.length - 1]; 2694 let domNodeBefore = dom.previousSibling; 2695 if (!nodeBefore || domNodeBefore && domNodeBefore.nodeName == "BR" || nodeBefore.isText && /[ \t\r\n\u000c]$/.test(nodeBefore.text)) 2696 value = value.slice(1); 2697 } 2698 } else if (!(top2.options & OPT_PRESERVE_WS_FULL)) { 2699 value = value.replace(/\r?\n|\r/g, " "); 2700 } else { 2701 value = value.replace(/\r\n?/g, "\n"); 2702 } 2703 if (value) 2704 this.insertNode(this.parser.schema.text(value)); 2705 this.findInText(dom); 2706 } else { 2707 this.findInside(dom); 2708 } 2709 } 2710 // Try to find a handler for the given tag and use that to parse. If 2711 // none is found, the element's content nodes are added directly. 2712 addElement(dom, matchAfter) { 2713 let name = dom.nodeName.toLowerCase(), ruleID; 2714 if (listTags.hasOwnProperty(name) && this.parser.normalizeLists) 2715 normalizeList(dom); 2716 let rule = this.options.ruleFromNode && this.options.ruleFromNode(dom) || (ruleID = this.parser.matchTag(dom, this, matchAfter)); 2717 if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) { 2718 this.findInside(dom); 2719 this.ignoreFallback(dom); 2720 } else if (!rule || rule.skip || rule.closeParent) { 2721 if (rule && rule.closeParent) 2722 this.open = Math.max(0, this.open - 1); 2723 else if (rule && rule.skip.nodeType) 2724 dom = rule.skip; 2725 let sync, top2 = this.top, oldNeedsBlock = this.needsBlock; 2726 if (blockTags.hasOwnProperty(name)) { 2727 if (top2.content.length && top2.content[0].isInline && this.open) { 2728 this.open--; 2729 top2 = this.top; 2730 } 2731 sync = true; 2732 if (!top2.type) 2733 this.needsBlock = true; 2734 } else if (!dom.firstChild) { 2735 this.leafFallback(dom); 2736 return; 2737 } 2738 if (rule && rule.skip) 2739 this.addAll(dom); 2740 else 2741 this.withStyleRules(dom, () => this.addAll(dom)); 2742 if (sync) 2743 this.sync(top2); 2744 this.needsBlock = oldNeedsBlock; 2745 } else { 2746 this.withStyleRules(dom, () => { 2747 this.addElementByRule(dom, rule, rule.consuming === false ? ruleID : void 0); 2748 }); 2749 } 2750 } 2751 // Called for leaf DOM nodes that would otherwise be ignored 2752 leafFallback(dom) { 2753 if (dom.nodeName == "BR" && this.top.type && this.top.type.inlineContent) 2754 this.addTextNode(dom.ownerDocument.createTextNode("\n")); 2755 } 2756 // Called for ignored nodes 2757 ignoreFallback(dom) { 2758 if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent)) 2759 this.findPlace(this.parser.schema.text("-")); 2760 } 2761 // Run any style parser associated with the node's styles. Either 2762 // return an array of marks, or null to indicate some of the styles 2763 // had a rule with `ignore` set. 2764 readStyles(styles) {
2765 let add = Mark$1.none, remove = Mark$1.none; 2766 for (let i = 0; i < styles.length; i += 2) { 2767 for (let after = void 0; ; ) { 2768 let rule = this.parser.matchStyle(styles[i], styles[i + 1], this, after); 2769 if (!rule) 2770 break; 2771 if (rule.ignore) 2772 return null; 2773 if (rule.clearMark) { 2774 this.top.pendingMarks.concat(this.top.activeMarks).forEach((m) => { 2775 if (rule.clearMark(m)) 2776 remove = m.addToSet(remove); 2777 }); 2778 } else { 2779 add = this.parser.schema.marks[rule.mark].create(rule.attrs).addToSet(add); 2780 } 2781 if (rule.consuming === false) 2782 after = rule; 2783 else 2784 break; 2785 } 2786 } 2787 return [add, remove]; 2788 } 2789 // Look up a handler for the given node. If none are found, return 2790 // false. Otherwise, apply it, use its return value to drive the way 2791 // the node's content is wrapped, and return true. 2792 addElementByRule(dom, rule, continueAfter) { 2793 let sync, nodeType, mark; 2794 if (rule.node) { 2795 nodeType = this.parser.schema.nodes[rule.node]; 2796 if (!nodeType.isLeaf) { 2797 sync = this.enter(nodeType, rule.attrs || null, rule.preserveWhitespace); 2798 } else if (!this.insertNode(nodeType.create(rule.attrs))) { 2799 this.leafFallback(dom); 2800 } 2801 } else { 2802 let markType = this.parser.schema.marks[rule.mark]; 2803 mark = markType.create(rule.attrs); 2804 this.addPendingMark(mark); 2805 } 2806 let startIn = this.top; 2807 if (nodeType && nodeType.isLeaf) { 2808 this.findInside(dom); 2809 } else if (continueAfter) { 2810 this.addElement(dom, continueAfter); 2811 } else if (rule.getContent) { 2812 this.findInside(dom); 2813 rule.getContent(dom, this.parser.schema).forEach((node) => this.insertNode(node)); 2814 } else { 2815 let contentDOM = dom; 2816 if (typeof rule.contentElement == "string") 2817 contentDOM = dom.querySelector(rule.contentElement); 2818 else if (typeof rule.contentElement == "function") 2819 contentDOM = rule.contentElement(dom); 2820 else if (rule.contentElement) 2821 contentDOM = rule.contentElement; 2822 this.findAround(dom, contentDOM, true); 2823 this.addAll(contentDOM); 2824 } 2825 if (sync && this.sync(startIn)) 2826 this.open--; 2827 if (mark) 2828 this.removePendingMark(mark, startIn); 2829 } 2830 // Add all child nodes between `startIndex` and `endIndex` (or the 2831 // whole node, if not given). If `sync` is passed, use it to 2832 // synchronize after every block element. 2833 addAll(parent, startIndex, endIndex) { 2834 let index = startIndex || 0; 2835 for (let dom = startIndex ? parent.childNodes[startIndex] : parent.firstChild, end2 = endIndex == null ? null : parent.childNodes[endIndex]; dom != end2; dom = dom.nextSibling, ++index) { 2836 this.findAtPoint(parent, index); 2837 this.addDOM(dom); 2838 } 2839 this.findAtPoint(parent, index); 2840 } 2841 // Try to find a way to fit the given node type into the current 2842 // context. May add intermediate wrappers and/or leave non-solid 2843 // nodes that we're in. 2844 findPlace(node) { 2845 let route, sync; 2846 for (let depth = this.open; depth >= 0; depth--) { 2847 let cx = this.nodes[depth]; 2848 let found2 = cx.findWrapping(node); 2849 if (found2 && (!route || route.length > found2.length)) { 2850 route = found2; 2851 sync = cx; 2852 if (!found2.length) 2853 break; 2854 } 2855 if (cx.solid) 2856 break; 2857 } 2858 if (!route) 2859 return false; 2860 this.sync(sync); 2861 for (let i = 0; i < route.length; i++) 2862 this.enterInner(route[i], null, false); 2863 return true; 2864 } 2865 // Try to insert the given node, adjusting the context when needed. 2866 insertNode(node) { 2867 if (node.isInline && this.needsBlock && !this.top.type) { 2868 let block = this.textblockFromContext(); 2869 if (block) 2870 this.enterInner(block); 2871 } 2872 if (this.findPlace(node)) { 2873 this.closeExtra(); 2874 let top2 = this.top; 2875 top2.applyPending(node.type); 2876 if (top2.match) 2877 top2.match = top2.match.matchType(node.type); 2878 let marks = top2.activeMarks; 2879 for (let i = 0; i < node.marks.length; i++) 2880 if (!top2.type || top2.type.allowsMarkType(node.marks[i].type)) 2881 marks = node.marks[i].addToSet(marks); 2882 top2.content.push(node.mark(marks)); 2883 return true; 2884 } 2885 return false;
2886 } 2887 // Try to start a node of the given type, adjusting the context when 2888 // necessary. 2889 enter(type, attrs, preserveWS) { 2890 let ok = this.findPlace(type.create(attrs)); 2891 if (ok) 2892 this.enterInner(type, attrs, true, preserveWS); 2893 return ok; 2894 } 2895 // Open a node of the given type 2896 enterInner(type, attrs = null, solid = false, preserveWS) { 2897 this.closeExtra(); 2898 let top2 = this.top; 2899 top2.applyPending(type); 2900 top2.match = top2.match && top2.match.matchType(type); 2901 let options = wsOptionsFor(type, preserveWS, top2.options); 2902 if (top2.options & OPT_OPEN_LEFT && top2.content.length == 0) 2903 options |= OPT_OPEN_LEFT; 2904 this.nodes.push(new NodeContext(type, attrs, top2.activeMarks, top2.pendingMarks, solid, null, options)); 2905 this.open++; 2906 } 2907 // Make sure all nodes above this.open are finished and added to 2908 // their parents 2909 closeExtra(openEnd = false) { 2910 let i = this.nodes.length - 1; 2911 if (i > this.open) { 2912 for (; i > this.open; i--) 2913 this.nodes[i - 1].content.push(this.nodes[i].finish(openEnd)); 2914 this.nodes.length = this.open + 1; 2915 } 2916 } 2917 finish() { 2918 this.open = 0; 2919 this.closeExtra(this.isOpen); 2920 return this.nodes[0].finish(this.isOpen || this.options.topOpen); 2921 } 2922 sync(to) { 2923 for (let i = this.open; i >= 0; i--) 2924 if (this.nodes[i] == to) { 2925 this.open = i; 2926 return true; 2927 } 2928 return false; 2929 } 2930 get currentPos() { 2931 this.closeExtra(); 2932 let pos = 0; 2933 for (let i = this.open; i >= 0; i--) { 2934 let content = this.nodes[i].content; 2935 for (let j = content.length - 1; j >= 0; j--) 2936 pos += content[j].nodeSize; 2937 if (i) 2938 pos++; 2939 } 2940 return pos; 2941 } 2942 findAtPoint(parent, offset2) { 2943 if (this.find) 2944 for (let i = 0; i < this.find.length; i++) { 2945 if (this.find[i].node == parent && this.find[i].offset == offset2) 2946 this.find[i].pos = this.currentPos; 2947 } 2948 } 2949 findInside(parent) { 2950 if (this.find) 2951 for (let i = 0; i < this.find.length; i++) { 2952 if (this.find[i].pos == null && parent.nodeType == 1 && parent.contains(this.find[i].node)) 2953 this.find[i].pos = this.currentPos; 2954 } 2955 } 2956 findAround(parent, content, before) { 2957 if (parent != content && this.find) 2958 for (let i = 0; i < this.find.length; i++) { 2959 if (this.find[i].pos == null && parent.nodeType == 1 && parent.contains(this.find[i].node)) { 2960 let pos = content.compareDocumentPosition(this.find[i].node); 2961 if (pos & (before ? 2 : 4)) 2962 this.find[i].pos = this.currentPos; 2963 } 2964 } 2965 } 2966 findInText(textNode) { 2967 if (this.find) 2968 for (let i = 0; i < this.find.length; i++) { 2969 if (this.find[i].node == textNode) 2970 this.find[i].pos = this.currentPos - (textNode.nodeValue.length - this.find[i].offset); 2971 } 2972 } 2973 // Determines whether the given context string matches this context. 2974 matchesContext(context) { 2975 if (context.indexOf("|") > -1) 2976 return context.split(/\s*\|\s*/).some(this.matchesContext, this); 2977 let parts = context.split("/"); 2978 let option = this.options.context; 2979 let useRoot = !this.isOpen && (!option || option.parent.type == this.nodes[0].type); 2980 let minDepth = -(option ? option.depth + 1 : 0) + (useRoot ? 0 : 1); 2981 let match = (i, depth) => { 2982 for (; i >= 0; i--) { 2983 let part = parts[i]; 2984 if (part == "") { 2985 if (i == parts.length - 1 || i == 0) 2986 continue; 2987 for (; depth >= minDepth; depth--) 2988 if (match(i - 1, depth)) 2989 return true; 2990 return false; 2991 } else { 2992 let next = depth > 0 || depth == 0 && useRoot ? this.nodes[depth].type : option && depth >= minDepth ? option.node(depth - minDepth).type : null; 2993 if (!next || next.name != part && next.groups.indexOf(part) == -1) 2994 return false; 2995 depth--; 2996 } 2997 } 2998 return true; 2999 }; 3000 return match(parts.length - 1, this.open); 3001 } 3002 textblockFromContext() { 3003 let $context = this.options.context; 3004 if ($context) 3005 for (let d = $context.depth; d >= 0; d--) {
3006 let deflt = $context.node(d).contentMatchAt($context.indexAfter(d)).defaultType; 3007 if (deflt && deflt.isTextblock && deflt.defaultAttrs) 3008 return deflt; 3009 } 3010 for (let name in this.parser.schema.nodes) { 3011 let type = this.parser.schema.nodes[name]; 3012 if (type.isTextblock && type.defaultAttrs) 3013 return type; 3014 } 3015 } 3016 addPendingMark(mark) { 3017 let found2 = findSameMarkInSet(mark, this.top.pendingMarks); 3018 if (found2) 3019 this.top.stashMarks.push(found2); 3020 this.top.pendingMarks = mark.addToSet(this.top.pendingMarks); 3021 } 3022 removePendingMark(mark, upto) { 3023 for (let depth = this.open; depth >= 0; depth--) { 3024 let level = this.nodes[depth]; 3025 let found2 = level.pendingMarks.lastIndexOf(mark); 3026 if (found2 > -1) { 3027 level.pendingMarks = mark.removeFromSet(level.pendingMarks); 3028 } else { 3029 level.activeMarks = mark.removeFromSet(level.activeMarks); 3030 let stashMark = level.popFromStashMark(mark); 3031 if (stashMark && level.type && level.type.allowsMarkType(stashMark.type)) 3032 level.activeMarks = stashMark.addToSet(level.activeMarks); 3033 } 3034 if (level == upto) 3035 break; 3036 } 3037 } 3038} 3039function normalizeList(dom) { 3040 for (let child = dom.firstChild, prevItem = null; child; child = child.nextSibling) { 3041 let name = child.nodeType == 1 ? child.nodeName.toLowerCase() : null; 3042 if (name && listTags.hasOwnProperty(name) && prevItem) { 3043 prevItem.appendChild(child); 3044 child = prevItem; 3045 } else if (name == "li") { 3046 prevItem = child; 3047 } else if (name) { 3048 prevItem = null; 3049 } 3050 } 3051} 3052function matches(dom, selector) { 3053 return (dom.matches || dom.msMatchesSelector || dom.webkitMatchesSelector || dom.mozMatchesSelector).call(dom, selector); 3054} 3055function parseStyles(style2) { 3056 let re = /\s*([\w-]+)\s*:\s*([^;]+)/g, m, result = []; 3057 while (m = re.exec(style2)) 3058 result.push(m[1], m[2].trim()); 3059 return result; 3060} 3061function copy(obj) { 3062 let copy2 = {}; 3063 for (let prop in obj) 3064 copy2[prop] = obj[prop]; 3065 return copy2; 3066} 3067function markMayApply(markType, nodeType) { 3068 let nodes = nodeType.schema.nodes; 3069 for (let name in nodes) { 3070 let parent = nodes[name]; 3071 if (!parent.allowsMarkType(markType)) 3072 continue; 3073 let seen = [], scan = (match) => { 3074 seen.push(match); 3075 for (let i = 0; i < match.edgeCount; i++) { 3076 let { type, next } = match.edge(i); 3077 if (type == nodeType) 3078 return true; 3079 if (seen.indexOf(next) < 0 && scan(next)) 3080 return true; 3081 } 3082 }; 3083 if (scan(parent.contentMatch)) 3084 return true; 3085 } 3086} 3087function findSameMarkInSet(mark, set) { 3088 for (let i = 0; i < set.length; i++) { 3089 if (mark.eq(set[i])) 3090 return set[i]; 3091 } 3092} 3093class DOMSerializer { 3094 /** 3095 Create a serializer. `nodes` should map node names to functions 3096 that take a node and return a description of the corresponding 3097 DOM. `marks` does the same for mark names, but also gets an 3098 argument that tells it whether the mark's content is block or 3099 inline content (for typical use, it'll always be inline). A mark 3100 serializer may be `null` to indicate that marks of that type 3101 should not be serialized. 3102 */ 3103 constructor(nodes, marks) { 3104 this.nodes = nodes; 3105 this.marks = marks; 3106 } 3107 /** 3108 Serialize the content of this fragment to a DOM fragment. When 3109 not in the browser, the `document` option, containing a DOM 3110 document, should be passed so that the serializer can create 3111 nodes. 3112 */ 3113 serializeFragment(fragment, options = {}, target) { 3114 if (!target) 3115 target = doc$1(options).createDocumentFragment(); 3116 let top2 = target, active = []; 3117 fragment.forEach((node) => { 3118 if (active.length || node.marks.length) { 3119 let keep = 0, rendered = 0; 3120 while (keep < active.length && rendered < node.marks.length) { 3121 let next = node.marks[rendered]; 3122 if (!this.marks[next.type.name]) { 3123 rendered++; 3124 continue; 3125 } 3126 if (!next.eq(active[keep][0]) || next.type.spec.spanning === false) 3127 break; 3128 keep++; 3129 rendered++; 3130 } 3131 while (keep < active.length) 3132 top2 = active.pop()[1]; 3133 while (rendered < node.marks.length) { 3134 let add = node.marks[rendered++]; 3135 let markDOM = this.serializeMark(add, node.isInline, options); 3136 if (markDOM) { 3137 active.push([add, top2]); 3138 top2.appendChild(markDOM.dom); 3139 top2 = markDOM.contentDOM || markDOM.dom; 3140 } 3141 } 3142 } 3143 top2.appendChild(this.serializeNodeInner(node, options)); 3144 }); 3145 return target; 3146 } 3147 /** 3148 @internal 3149 */
3150 serializeNodeInner(node, options) { 3151 let { dom, contentDOM } = DOMSerializer.renderSpec(doc$1(options), this.nodes[node.type.name](node)); 3152 if (contentDOM) { 3153 if (node.isLeaf) 3154 throw new RangeError("Content hole not allowed in a leaf node spec"); 3155 this.serializeFragment(node.content, options, contentDOM); 3156 } 3157 return dom; 3158 } 3159 /** 3160 Serialize this node to a DOM node. This can be useful when you 3161 need to serialize a part of a document, as opposed to the whole 3162 document. To serialize a whole document, use 3163 [`serializeFragment`](https://prosemirror.net/docs/ref/#model.DOMSerializer.serializeFragment) on 3164 its [content](https://prosemirror.net/docs/ref/#model.Node.content). 3165 */ 3166 serializeNode(node, options = {}) { 3167 let dom = this.serializeNodeInner(node, options); 3168 for (let i = node.marks.length - 1; i >= 0; i--) { 3169 let wrap2 = this.serializeMark(node.marks[i], node.isInline, options); 3170 if (wrap2) { 3171 (wrap2.contentDOM || wrap2.dom).appendChild(dom); 3172 dom = wrap2.dom; 3173 } 3174 } 3175 return dom; 3176 } 3177 /** 3178 @internal 3179 */ 3180 serializeMark(mark, inline, options = {}) { 3181 let toDOM = this.marks[mark.type.name]; 3182 return toDOM && DOMSerializer.renderSpec(doc$1(options), toDOM(mark, inline)); 3183 } 3184 /** 3185 Render an [output spec](https://prosemirror.net/docs/ref/#model.DOMOutputSpec) to a DOM node. If 3186 the spec has a hole (zero) in it, `contentDOM` will point at the 3187 node with the hole. 3188 */ 3189 static renderSpec(doc2, structure, xmlNS = null) { 3190 if (typeof structure == "string") 3191 return { dom: doc2.createTextNode(structure) }; 3192 if (structure.nodeType != null) 3193 return { dom: structure }; 3194 if (structure.dom && structure.dom.nodeType != null) 3195 return structure; 3196 let tagName = structure[0], space = tagName.indexOf(" "); 3197 if (space > 0) { 3198 xmlNS = tagName.slice(0, space); 3199 tagName = tagName.slice(space + 1); 3200 } 3201 let contentDOM; 3202 let dom = xmlNS ? doc2.createElementNS(xmlNS, tagName) : doc2.createElement(tagName); 3203 let attrs = structure[1], start2 = 1; 3204 if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) { 3205 start2 = 2; 3206 for (let name in attrs) 3207 if (attrs[name] != null) { 3208 let space2 = name.indexOf(" "); 3209 if (space2 > 0) 3210 dom.setAttributeNS(name.slice(0, space2), name.slice(space2 + 1), attrs[name]); 3211 else 3212 dom.setAttribute(name, attrs[name]); 3213 } 3214 } 3215 for (let i = start2; i < structure.length; i++) { 3216 let child = structure[i]; 3217 if (child === 0) { 3218 if (i < structure.length - 1 || i > start2) 3219 throw new RangeError("Content hole must be the only child of its parent node"); 3220 return { dom, contentDOM: dom }; 3221 } else { 3222 let { dom: inner, contentDOM: innerContent } = DOMSerializer.renderSpec(doc2, child, xmlNS); 3223 dom.appendChild(inner); 3224 if (innerContent) { 3225 if (contentDOM) 3226 throw new RangeError("Multiple content holes"); 3227 contentDOM = innerContent; 3228 } 3229 } 3230 } 3231 return { dom, contentDOM }; 3232 } 3233 /** 3234 Build a serializer using the [`toDOM`](https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM) 3235 properties in a schema's node and mark specs. 3236 */ 3237 static fromSchema(schema) { 3238 return schema.cached.domSerializer || (schema.cached.domSerializer = new DOMSerializer(this.nodesFromSchema(schema), this.marksFromSchema(schema))); 3239 } 3240 /** 3241 Gather the serializers in a schema's node specs into an object. 3242 This can be useful as a base to build a custom serializer from. 3243 */
vendor: 4,275 bytes, lines 3244-3387
3244 static nodesFromSchema(schema) { 3245 let result = gatherToDOM(schema.nodes); 3246 if (!result.text) 3247 result.text = (node) => node.text; 3248 return result; 3249 } 3250 /** 3251 Gather the serializers in a schema's mark specs into an object. 3252 */ 3253 static marksFromSchema(schema) { 3254 return gatherToDOM(schema.marks); 3255 } 3256} 3257function gatherToDOM(obj) { 3258 let result = {}; 3259 for (let name in obj) { 3260 let toDOM = obj[name].spec.toDOM; 3261 if (toDOM) 3262 result[name] = toDOM; 3263 } 3264 return result; 3265} 3266function doc$1(options) { 3267 return options.document || window.document; 3268} 3269const lower16 = 65535; 3270const factor16 = Math.pow(2, 16); 3271function makeRecover(index, offset2) { 3272 return index + offset2 * factor16; 3273} 3274function recoverIndex(value) { 3275 return value & lower16; 3276} 3277function recoverOffset(value) { 3278 return (value - (value & lower16)) / factor16; 3279} 3280const DEL_BEFORE = 1, DEL_AFTER = 2, DEL_ACROSS = 4, DEL_SIDE = 8; 3281class MapResult { 3282 /** 3283 @internal 3284 */ 3285 constructor(pos, delInfo, recover) { 3286 this.pos = pos; 3287 this.delInfo = delInfo; 3288 this.recover = recover; 3289 } 3290 /** 3291 Tells you whether the position was deleted, that is, whether the 3292 step removed the token on the side queried (via the `assoc`) 3293 argument from the document. 3294 */ 3295 get deleted() { 3296 return (this.delInfo & DEL_SIDE) > 0; 3297 } 3298 /** 3299 Tells you whether the token before the mapped position was deleted. 3300 */ 3301 get deletedBefore() { 3302 return (this.delInfo & (DEL_BEFORE | DEL_ACROSS)) > 0; 3303 } 3304 /** 3305 True when the token after the mapped position was deleted. 3306 */ 3307 get deletedAfter() { 3308 return (this.delInfo & (DEL_AFTER | DEL_ACROSS)) > 0; 3309 } 3310 /** 3311 Tells whether any of the steps mapped through deletes across the 3312 position (including both the token before and after the 3313 position). 3314 */ 3315 get deletedAcross() { 3316 return (this.delInfo & DEL_ACROSS) > 0; 3317 } 3318} 3319class StepMap { 3320 /** 3321 Create a position map. The modifications to the document are 3322 represented as an array of numbers, in which each group of three 3323 represents a modified chunk as `[start, oldSize, newSize]`. 3324 */ 3325 constructor(ranges, inverted = false) { 3326 this.ranges = ranges; 3327 this.inverted = inverted; 3328 if (!ranges.length && StepMap.empty) 3329 return StepMap.empty; 3330 } 3331 /** 3332 @internal 3333 */ 3334 recover(value) { 3335 let diff = 0, index = recoverIndex(value); 3336 if (!this.inverted) 3337 for (let i = 0; i < index; i++) 3338 diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]; 3339 return this.ranges[index * 3] + diff + recoverOffset(value); 3340 } 3341 mapResult(pos, assoc = 1) { 3342 return this._map(pos, assoc, false); 3343 } 3344 map(pos, assoc = 1) { 3345 return this._map(pos, assoc, true); 3346 } 3347 /** 3348 @internal 3349 */ 3350 _map(pos, assoc, simple) { 3351 let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; 3352 for (let i = 0; i < this.ranges.length; i += 3) { 3353 let start2 = this.ranges[i] - (this.inverted ? diff : 0); 3354 if (start2 > pos) 3355 break; 3356 let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end2 = start2 + oldSize; 3357 if (pos <= end2) { 3358 let side = !oldSize ? assoc : pos == start2 ? -1 : pos == end2 ? 1 : assoc; 3359 let result = start2 + diff + (side < 0 ? 0 : newSize); 3360 if (simple) 3361 return result; 3362 let recover = pos == (assoc < 0 ? start2 : end2) ? null : makeRecover(i / 3, pos - start2); 3363 let del = pos == start2 ? DEL_AFTER : pos == end2 ? DEL_BEFORE : DEL_ACROSS; 3364 if (assoc < 0 ? pos != start2 : pos != end2) 3365 del |= DEL_SIDE; 3366 return new MapResult(result, del, recover); 3367 } 3368 diff += newSize - oldSize; 3369 } 3370 return simple ? pos + diff : new MapResult(pos + diff, 0, null); 3371 } 3372 /** 3373 @internal 3374 */ 3375 touches(pos, recover) { 3376 let diff = 0, index = recoverIndex(recover); 3377 let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; 3378 for (let i = 0; i < this.ranges.length; i += 3) { 3379 let start2 = this.ranges[i] - (this.inverted ? diff : 0); 3380 if (start2 > pos) 3381 break; 3382 let oldSize = this.ranges[i + oldIndex], end2 = start2 + oldSize; 3383 if (pos <= end2 && i == index * 3) 3384 return true; 3385 diff += this.ranges[i + newIndex] - oldSize; 3386 } 3387 return false;
3388 } 3389 /** 3390 Calls the given function on each of the changed ranges included in 3391 this map. 3392 */ 3393 forEach(f) { 3394 let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; 3395 for (let i = 0, diff = 0; i < this.ranges.length; i += 3) { 3396 let start2 = this.ranges[i], oldStart = start2 - (this.inverted ? diff : 0), newStart = start2 + (this.inverted ? 0 : diff); 3397 let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]; 3398 f(oldStart, oldStart + oldSize, newStart, newStart + newSize); 3399 diff += newSize - oldSize; 3400 } 3401 } 3402 /** 3403 Create an inverted version of this map. The result can be used to 3404 map positions in the post-step document to the pre-step document. 3405 */ 3406 invert() { 3407 return new StepMap(this.ranges, !this.inverted); 3408 } 3409 /** 3410 @internal 3411 */ 3412 toString() { 3413 return (this.inverted ? "-" : "") + JSON.stringify(this.ranges); 3414 } 3415 /** 3416 Create a map that moves all positions by offset `n` (which may be 3417 negative). This can be useful when applying steps meant for a 3418 sub-document to a larger document, or vice-versa. 3419 */ 3420 static offset(n) { 3421 return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n]); 3422 } 3423} 3424StepMap.empty = new StepMap([]); 3425class Mapping { 3426 /** 3427 Create a new mapping with the given position maps. 3428 */ 3429 constructor(maps = [], mirror, from2 = 0, to = maps.length) { 3430 this.maps = maps; 3431 this.mirror = mirror; 3432 this.from = from2; 3433 this.to = to; 3434 } 3435 /** 3436 Create a mapping that maps only through a part of this one. 3437 */ 3438 slice(from2 = 0, to = this.maps.length) { 3439 return new Mapping(this.maps, this.mirror, from2, to); 3440 } 3441 /** 3442 @internal 3443 */ 3444 copy() { 3445 return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to); 3446 } 3447 /** 3448 Add a step map to the end of this mapping. If `mirrors` is 3449 given, it should be the index of the step map that is the mirror 3450 image of this one. 3451 */ 3452 appendMap(map2, mirrors) { 3453 this.to = this.maps.push(map2); 3454 if (mirrors != null) 3455 this.setMirror(this.maps.length - 1, mirrors); 3456 } 3457 /** 3458 Add all the step maps in a given mapping to this one (preserving 3459 mirroring information). 3460 */ 3461 appendMapping(mapping) { 3462 for (let i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) { 3463 let mirr = mapping.getMirror(i); 3464 this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : void 0); 3465 } 3466 } 3467 /** 3468 Finds the offset of the step map that mirrors the map at the 3469 given offset, in this mapping (as per the second argument to 3470 `appendMap`). 3471 */ 3472 getMirror(n) { 3473 if (this.mirror) { 3474 for (let i = 0; i < this.mirror.length; i++) 3475 if (this.mirror[i] == n) 3476 return this.mirror[i + (i % 2 ? -1 : 1)]; 3477 } 3478 } 3479 /** 3480 @internal 3481 */ 3482 setMirror(n, m) { 3483 if (!this.mirror) 3484 this.mirror = []; 3485 this.mirror.push(n, m); 3486 } 3487 /** 3488 Append the inverse of the given mapping to this one. 3489 */ 3490 appendMappingInverted(mapping) { 3491 for (let i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) { 3492 let mirr = mapping.getMirror(i); 3493 this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : void 0); 3494 } 3495 } 3496 /** 3497 Create an inverted version of this mapping. 3498 */ 3499 invert() { 3500 let inverse = new Mapping(); 3501 inverse.appendMappingInverted(this); 3502 return inverse; 3503 } 3504 /** 3505 Map a position through this mapping. 3506 */ 3507 map(pos, assoc = 1) { 3508 if (this.mirror) 3509 return this._map(pos, assoc, true); 3510 for (let i = this.from; i < this.to; i++) 3511 pos = this.maps[i].map(pos, assoc); 3512 return pos; 3513 } 3514 /** 3515 Map a position through this mapping, returning a mapping 3516 result. 3517 */ 3518 mapResult(pos, assoc = 1) { 3519 return this._map(pos, assoc, false); 3520 } 3521 /** 3522 @internal 3523 */ 3524 _map(pos, assoc, simple) { 3525 let delInfo = 0; 3526 for (let i = this.from; i < this.to; i++) { 3527 let map2 = this.maps[i], result = map2.mapResult(pos, assoc); 3528 if (result.recover != null) { 3529 let corr = this.getMirror(i); 3530 if (corr != null && corr > i && corr < this.to) { 3531 i = corr; 3532 pos = this.maps[corr].recover(result.recover); 3533 continue; 3534 } 3535 } 3536 delInfo |= result.delInfo; 3537 pos = result.pos; 3538 } 3539 return simple ? pos : new MapResult(pos, delInfo, null); 3540 } 3541} 3542const stepsByID = /* @__PURE__ */ Object.create(null); 3543class Step { 3544 /**
3545 Get the step map that represents the changes made by this step, 3546 and which can be used to transform between positions in the old 3547 and the new document. 3548 */ 3549 getMap() { 3550 return StepMap.empty; 3551 } 3552 /** 3553 Try to merge this step with another one, to be applied directly 3554 after it. Returns the merged step when possible, null if the 3555 steps can't be merged. 3556 */ 3557 merge(other) { 3558 return null; 3559 } 3560 /** 3561 Deserialize a step from its JSON representation. Will call 3562 through to the step class' own implementation of this method. 3563 */ 3564 static fromJSON(schema, json) { 3565 if (!json || !json.stepType) 3566 throw new RangeError("Invalid input for Step.fromJSON"); 3567 let type = stepsByID[json.stepType]; 3568 if (!type) 3569 throw new RangeError(`No step type ${json.stepType} defined`); 3570 return type.fromJSON(schema, json); 3571 } 3572 /** 3573 To be able to serialize steps to JSON, each step needs a string 3574 ID to attach to its JSON representation. Use this method to 3575 register an ID for your step classes. Try to pick something 3576 that's unlikely to clash with steps from other modules. 3577 */ 3578 static jsonID(id, stepClass) { 3579 if (id in stepsByID) 3580 throw new RangeError("Duplicate use of step JSON ID " + id); 3581 stepsByID[id] = stepClass; 3582 stepClass.prototype.jsonID = id; 3583 return stepClass; 3584 } 3585} 3586class StepResult { 3587 /** 3588 @internal 3589 */ 3590 constructor(doc2, failed) { 3591 this.doc = doc2; 3592 this.failed = failed; 3593 } 3594 /** 3595 Create a successful step result. 3596 */ 3597 static ok(doc2) { 3598 return new StepResult(doc2, null); 3599 } 3600 /** 3601 Create a failed step result. 3602 */ 3603 static fail(message) { 3604 return new StepResult(null, message); 3605 } 3606 /** 3607 Call [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) with the given 3608 arguments. Create a successful result if it succeeds, and a 3609 failed one if it throws a `ReplaceError`. 3610 */ 3611 static fromReplace(doc2, from2, to, slice2) { 3612 try { 3613 return StepResult.ok(doc2.replace(from2, to, slice2)); 3614 } catch (e) { 3615 if (e instanceof ReplaceError) 3616 return StepResult.fail(e.message); 3617 throw e; 3618 } 3619 } 3620} 3621function mapFragment(fragment, f, parent) { 3622 let mapped = []; 3623 for (let i = 0; i < fragment.childCount; i++) {
vendor: 18,382 bytes, lines 3624-4130
3624 let child = fragment.child(i); 3625 if (child.content.size) 3626 child = child.copy(mapFragment(child.content, f, child)); 3627 if (child.isInline) 3628 child = f(child, parent, i); 3629 mapped.push(child); 3630 } 3631 return Fragment.fromArray(mapped); 3632} 3633class AddMarkStep extends Step { 3634 /** 3635 Create a mark step. 3636 */ 3637 constructor(from2, to, mark) { 3638 super(); 3639 this.from = from2; 3640 this.to = to; 3641 this.mark = mark; 3642 } 3643 apply(doc2) { 3644 let oldSlice = doc2.slice(this.from, this.to), $from = doc2.resolve(this.from); 3645 let parent = $from.node($from.sharedDepth(this.to)); 3646 let slice2 = new Slice(mapFragment(oldSlice.content, (node, parent2) => { 3647 if (!node.isAtom || !parent2.type.allowsMarkType(this.mark.type)) 3648 return node; 3649 return node.mark(this.mark.addToSet(node.marks)); 3650 }, parent), oldSlice.openStart, oldSlice.openEnd); 3651 return StepResult.fromReplace(doc2, this.from, this.to, slice2); 3652 } 3653 invert() { 3654 return new RemoveMarkStep(this.from, this.to, this.mark); 3655 } 3656 map(mapping) { 3657 let from2 = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); 3658 if (from2.deleted && to.deleted || from2.pos >= to.pos) 3659 return null; 3660 return new AddMarkStep(from2.pos, to.pos, this.mark); 3661 } 3662 merge(other) { 3663 if (other instanceof AddMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) 3664 return new AddMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark); 3665 return null; 3666 } 3667 toJSON() { 3668 return { 3669 stepType: "addMark", 3670 mark: this.mark.toJSON(), 3671 from: this.from, 3672 to: this.to 3673 }; 3674 } 3675 /** 3676 @internal 3677 */ 3678 static fromJSON(schema, json) { 3679 if (typeof json.from != "number" || typeof json.to != "number") 3680 throw new RangeError("Invalid input for AddMarkStep.fromJSON"); 3681 return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark)); 3682 } 3683} 3684Step.jsonID("addMark", AddMarkStep); 3685class RemoveMarkStep extends Step { 3686 /** 3687 Create a mark-removing step. 3688 */ 3689 constructor(from2, to, mark) { 3690 super(); 3691 this.from = from2; 3692 this.to = to; 3693 this.mark = mark; 3694 } 3695 apply(doc2) { 3696 let oldSlice = doc2.slice(this.from, this.to); 3697 let slice2 = new Slice(mapFragment(oldSlice.content, (node) => { 3698 return node.mark(this.mark.removeFromSet(node.marks)); 3699 }, doc2), oldSlice.openStart, oldSlice.openEnd); 3700 return StepResult.fromReplace(doc2, this.from, this.to, slice2); 3701 } 3702 invert() { 3703 return new AddMarkStep(this.from, this.to, this.mark); 3704 } 3705 map(mapping) { 3706 let from2 = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); 3707 if (from2.deleted && to.deleted || from2.pos >= to.pos) 3708 return null; 3709 return new RemoveMarkStep(from2.pos, to.pos, this.mark); 3710 } 3711 merge(other) { 3712 if (other instanceof RemoveMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) 3713 return new RemoveMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark); 3714 return null; 3715 } 3716 toJSON() { 3717 return { 3718 stepType: "removeMark", 3719 mark: this.mark.toJSON(), 3720 from: this.from, 3721 to: this.to 3722 }; 3723 } 3724 /** 3725 @internal 3726 */ 3727 static fromJSON(schema, json) { 3728 if (typeof json.from != "number" || typeof json.to != "number") 3729 throw new RangeError("Invalid input for RemoveMarkStep.fromJSON"); 3730 return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark)); 3731 } 3732} 3733Step.jsonID("removeMark", RemoveMarkStep); 3734class AddNodeMarkStep extends Step { 3735 /** 3736 Create a node mark step. 3737 */ 3738 constructor(pos, mark) { 3739 super(); 3740 this.pos = pos; 3741 this.mark = mark; 3742 } 3743 apply(doc2) { 3744 let node = doc2.nodeAt(this.pos); 3745 if (!node) 3746 return StepResult.fail("No node at mark step's position"); 3747 let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks)); 3748 return StepResult.fromReplace(doc2, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1)); 3749 } 3750 invert(doc2) { 3751 let node = doc2.nodeAt(this.pos); 3752 if (node) { 3753 let newSet = this.mark.addToSet(node.marks); 3754 if (newSet.length == node.marks.length) { 3755 for (let i = 0; i < node.marks.length; i++) 3756 if (!node.marks[i].isInSet(newSet)) 3757 return new AddNodeMarkStep(this.pos, node.marks[i]); 3758 return new AddNodeMarkStep(this.pos, this.mark); 3759 } 3760 } 3761 return new RemoveNodeMarkStep(this.pos, this.mark); 3762 } 3763 map(mapping) { 3764 let pos = mapping.mapResult(this.pos, 1); 3765 return pos.deletedAfter ? null : new AddNodeMarkStep(pos.pos, this.mark); 3766 } 3767 toJSON() { 3768 return { stepType: "addNodeMark", pos: this.pos, mark: this.mark.toJSON() }; 3769 } 3770 /** 3771 @internal 3772 */ 3773 static fromJSON(schema, json) { 3774 if (typeof json.pos != "number") 3775 throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON"); 3776 return new AddNodeMarkStep(json.pos, schema.markFromJSON(json.mark)); 3777 } 3778} 3779Step.jsonID("addNodeMark", AddNodeMarkStep); 3780class RemoveNodeMarkStep extends Step { 3781 /** 3782 Create a mark-removing step. 3783 */ 3784 constructor(pos, mark) { 3785 super(); 3786 this.pos = pos; 3787 this.mark = mark; 3788 } 3789 apply(doc2) { 3790 let node = doc2.nodeAt(this.pos); 3791 if (!node) 3792 return StepResult.fail("No node at mark step's position"); 3793 let updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks)); 3794 return StepResult.fromReplace(doc2, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1)); 3795 } 3796 invert(doc2) { 3797 let node = doc2.nodeAt(this.pos); 3798 if (!node || !this.mark.isInSet(node.marks)) 3799 return this; 3800 return new AddNodeMarkStep(this.pos, this.mark); 3801 } 3802 map(mapping) { 3803 let pos = mapping.mapResult(this.pos, 1); 3804 return pos.deletedAfter ? null : new RemoveNodeMarkStep(pos.pos, this.mark); 3805 } 3806 toJSON() { 3807 return { stepType: "removeNodeMark", pos: this.pos, mark: this.mark.toJSON() }; 3808 } 3809 /** 3810 @internal 3811 */ 3812 static fromJSON(schema, json) { 3813 if (typeof json.pos != "number") 3814 throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON"); 3815 return new RemoveNodeMarkStep(json.pos, schema.markFromJSON(json.mark)); 3816 } 3817} 3818Step.jsonID("removeNodeMark", RemoveNodeMarkStep); 3819class ReplaceStep extends Step { 3820 /** 3821 The given `slice` should fit the 'gap' between `from` and 3822 `to`âthe depths must line up, and the surrounding nodes must be 3823 able to be joined with the open sides of the slice. When 3824 `structure` is true, the step will fail if the content between 3825 from and to is not just a sequence of closing and then opening 3826 tokens (this is to guard against rebased replace steps 3827 overwriting something they weren't supposed to). 3828 */ 3829 constructor(from2, to, slice2, structure = false) { 3830 super(); 3831 this.from = from2; 3832 this.to = to; 3833 this.slice = slice2; 3834 this.structure = structure; 3835 } 3836 apply(doc2) { 3837 if (this.structure && contentBetween(doc2, this.from, this.to)) 3838 return StepResult.fail("Structure replace would overwrite content"); 3839 return StepResult.fromReplace(doc2, this.from, this.to, this.slice); 3840 } 3841 getMap() { 3842 return new StepMap([this.from, this.to - this.from, this.slice.size]); 3843 } 3844 invert(doc2) { 3845 return new ReplaceStep(this.from, this.from + this.slice.size, doc2.slice(this.from, this.to)); 3846 } 3847 map(mapping) { 3848 let from2 = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); 3849 if (from2.deletedAcross && to.deletedAcross) 3850 return null; 3851 return new ReplaceStep(from2.pos, Math.max(from2.pos, to.pos), this.slice); 3852 } 3853 merge(other) { 3854 if (!(other instanceof ReplaceStep) || other.structure || this.structure) 3855 return null; 3856 if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { 3857 let slice2 = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd); 3858 return new ReplaceStep(this.from, this.to + (other.to - other.from), slice2, this.structure); 3859 } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { 3860 let slice2 = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd); 3861 return new ReplaceStep(other.from, this.to, slice2, this.structure); 3862 } else { 3863 return null; 3864 } 3865 } 3866 toJSON() { 3867 let json = { stepType: "replace", from: this.from, to: this.to }; 3868 if (this.slice.size) 3869 json.slice = this.slice.toJSON(); 3870 if (this.structure) 3871 json.structure = true; 3872 return json; 3873 } 3874 /** 3875 @internal 3876 */ 3877 static fromJSON(schema, json) { 3878 if (typeof json.from != "number" || typeof json.to != "number") 3879 throw new RangeError("Invalid input for ReplaceStep.fromJSON"); 3880 return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure); 3881 } 3882} 3883Step.jsonID("replace", ReplaceStep); 3884class ReplaceAroundStep extends Step { 3885 /** 3886 Create a replace-around step with the given range and gap. 3887 `insert` should be the point in the slice into which the content 3888 of the gap should be moved. `structure` has the same meaning as 3889 it has in the [`ReplaceStep`](https://prosemirror.net/docs/ref/#transform.ReplaceStep) class. 3890 */ 3891 constructor(from2, to, gapFrom, gapTo, slice2, insert, structure = false) { 3892 super(); 3893 this.from = from2; 3894 this.to = to; 3895 this.gapFrom = gapFrom; 3896 this.gapTo = gapTo; 3897 this.slice = slice2; 3898 this.insert = insert; 3899 this.structure = structure; 3900 } 3901 apply(doc2) { 3902 if (this.structure && (contentBetween(doc2, this.from, this.gapFrom) || contentBetween(doc2, this.gapTo, this.to))) 3903 return StepResult.fail("Structure gap-replace would overwrite content"); 3904 let gap = doc2.slice(this.gapFrom, this.gapTo); 3905 if (gap.openStart || gap.openEnd) 3906 return StepResult.fail("Gap is not a flat range"); 3907 let inserted = this.slice.insertAt(this.insert, gap.content); 3908 if (!inserted) 3909 return StepResult.fail("Content does not fit in gap"); 3910 return StepResult.fromReplace(doc2, this.from, this.to, inserted); 3911 } 3912 getMap() { 3913 return new StepMap([ 3914 this.from, 3915 this.gapFrom - this.from, 3916 this.insert, 3917 this.gapTo, 3918 this.to - this.gapTo, 3919 this.slice.size - this.insert 3920 ]); 3921 } 3922 invert(doc2) { 3923 let gap = this.gapTo - this.gapFrom; 3924 return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap, this.from + this.insert, this.from + this.insert + gap, doc2.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), this.gapFrom - this.from, this.structure); 3925 } 3926 map(mapping) { 3927 let from2 = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); 3928 let gapFrom = this.from == this.gapFrom ? from2.pos : mapping.map(this.gapFrom, -1); 3929 let gapTo = this.to == this.gapTo ? to.pos : mapping.map(this.gapTo, 1); 3930 if (from2.deletedAcross && to.deletedAcross || gapFrom < from2.pos || gapTo > to.pos) 3931 return null; 3932 return new ReplaceAroundStep(from2.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure); 3933 } 3934 toJSON() { 3935 let json = { 3936 stepType: "replaceAround", 3937 from: this.from, 3938 to: this.to, 3939 gapFrom: this.gapFrom, 3940 gapTo: this.gapTo, 3941 insert: this.insert 3942 }; 3943 if (this.slice.size) 3944 json.slice = this.slice.toJSON(); 3945 if (this.structure) 3946 json.structure = true; 3947 return json; 3948 } 3949 /** 3950 @internal 3951 */ 3952 static fromJSON(schema, json) { 3953 if (typeof json.from != "number" || typeof json.to != "number" || typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") 3954 throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON"); 3955 return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, Slice.fromJSON(schema, json.slice), json.insert, !!json.structure); 3956 } 3957} 3958Step.jsonID("replaceAround", ReplaceAroundStep); 3959function contentBetween(doc2, from2, to) { 3960 let $from = doc2.resolve(from2), dist = to - from2, depth = $from.depth; 3961 while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { 3962 depth--; 3963 dist--; 3964 } 3965 if (dist > 0) { 3966 let next = $from.node(depth).maybeChild($from.indexAfter(depth)); 3967 while (dist > 0) { 3968 if (!next || next.isLeaf) 3969 return true; 3970 next = next.firstChild; 3971 dist--; 3972 } 3973 } 3974 return false; 3975} 3976function addMark(tr2, from2, to, mark) { 3977 let removed = [], added = []; 3978 let removing, adding; 3979 tr2.doc.nodesBetween(from2, to, (node, pos, parent) => { 3980 if (!node.isInline) 3981 return; 3982 let marks = node.marks; 3983 if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) { 3984 let start2 = Math.max(pos, from2), end2 = Math.min(pos + node.nodeSize, to); 3985 let newSet = mark.addToSet(marks); 3986 for (let i = 0; i < marks.length; i++) { 3987 if (!marks[i].isInSet(newSet)) { 3988 if (removing && removing.to == start2 && removing.mark.eq(marks[i])) 3989 removing.to = end2; 3990 else 3991 removed.push(removing = new RemoveMarkStep(start2, end2, marks[i])); 3992 } 3993 } 3994 if (adding && adding.to == start2) 3995 adding.to = end2; 3996 else 3997 added.push(adding = new AddMarkStep(start2, end2, mark)); 3998 } 3999 }); 4000 removed.forEach((s) => tr2.step(s)); 4001 added.forEach((s) => tr2.step(s)); 4002} 4003function removeMark(tr2, from2, to, mark) { 4004 let matched = [], step = 0; 4005 tr2.doc.nodesBetween(from2, to, (node, pos) => { 4006 if (!node.isInline) 4007 return; 4008 step++; 4009 let toRemove = null; 4010 if (mark instanceof MarkType) { 4011 let set = node.marks, found2; 4012 while (found2 = mark.isInSet(set)) { 4013 (toRemove || (toRemove = [])).push(found2); 4014 set = found2.removeFromSet(set); 4015 } 4016 } else if (mark) { 4017 if (mark.isInSet(node.marks)) 4018 toRemove = [mark]; 4019 } else { 4020 toRemove = node.marks; 4021 } 4022 if (toRemove && toRemove.length) { 4023 let end2 = Math.min(pos + node.nodeSize, to); 4024 for (let i = 0; i < toRemove.length; i++) { 4025 let style2 = toRemove[i], found2; 4026 for (let j = 0; j < matched.length; j++) { 4027 let m = matched[j]; 4028 if (m.step == step - 1 && style2.eq(matched[j].style)) 4029 found2 = m; 4030 } 4031 if (found2) { 4032 found2.to = end2; 4033 found2.step = step; 4034 } else { 4035 matched.push({ style: style2, from: Math.max(pos, from2), to: end2, step }); 4036 } 4037 } 4038 } 4039 }); 4040 matched.forEach((m) => tr2.step(new RemoveMarkStep(m.from, m.to, m.style))); 4041} 4042function clearIncompatible(tr2, pos, parentType, match = parentType.contentMatch, clearNewlines = true) { 4043 let node = tr2.doc.nodeAt(pos); 4044 let replSteps = [], cur = pos + 1; 4045 for (let i = 0; i < node.childCount; i++) { 4046 let child = node.child(i), end2 = cur + child.nodeSize; 4047 let allowed = match.matchType(child.type); 4048 if (!allowed) { 4049 replSteps.push(new ReplaceStep(cur, end2, Slice.empty)); 4050 } else { 4051 match = allowed; 4052 for (let j = 0; j < child.marks.length; j++) 4053 if (!parentType.allowsMarkType(child.marks[j].type)) 4054 tr2.step(new RemoveMarkStep(cur, end2, child.marks[j])); 4055 if (clearNewlines && child.isText && parentType.whitespace != "pre") { 4056 let m, newline = /\r?\n|\r/g, slice2; 4057 while (m = newline.exec(child.text)) { 4058 if (!slice2) 4059 slice2 = new Slice(Fragment.from(parentType.schema.text(" ", parentType.allowedMarks(child.marks))), 0, 0); 4060 replSteps.push(new ReplaceStep(cur + m.index, cur + m.index + m[0].length, slice2)); 4061 } 4062 } 4063 } 4064 cur = end2; 4065 } 4066 if (!match.validEnd) { 4067 let fill = match.fillBefore(Fragment.empty, true); 4068 tr2.replace(cur, cur, new Slice(fill, 0, 0)); 4069 } 4070 for (let i = replSteps.length - 1; i >= 0; i--) 4071 tr2.step(replSteps[i]); 4072} 4073function canCut(node, start2, end2) { 4074 return (start2 == 0 || node.canReplace(start2, node.childCount)) && (end2 == node.childCount || node.canReplace(0, end2)); 4075} 4076function liftTarget(range) { 4077 let parent = range.parent; 4078 let content = parent.content.cutByIndex(range.startIndex, range.endIndex); 4079 for (let depth = range.depth; ; --depth) { 4080 let node = range.$from.node(depth); 4081 let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth); 4082 if (depth < range.depth && node.canReplace(index, endIndex, content)) 4083 return depth; 4084 if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) 4085 break; 4086 } 4087 return null; 4088} 4089function lift$2(tr2, range, target) { 4090 let { $from, $to, depth } = range; 4091 let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1); 4092 let start2 = gapStart, end2 = gapEnd; 4093 let before = Fragment.empty, openStart = 0; 4094 for (let d = depth, splitting = false; d > target; d--) 4095 if (splitting || $from.index(d) > 0) { 4096 splitting = true; 4097 before = Fragment.from($from.node(d).copy(before)); 4098 openStart++; 4099 } else { 4100 start2--; 4101 } 4102 let after = Fragment.empty, openEnd = 0; 4103 for (let d = depth, splitting = false; d > target; d--) 4104 if (splitting || $to.after(d + 1) < $to.end(d)) { 4105 splitting = true; 4106 after = Fragment.from($to.node(d).copy(after)); 4107 openEnd++; 4108 } else { 4109 end2++; 4110 } 4111 tr2.step(new ReplaceAroundStep(start2, end2, gapStart, gapEnd, new Slice(before.append(after), openStart, openEnd), before.size - openStart, true)); 4112} 4113function findWrapping(range, nodeType, attrs = null, innerRange = range) { 4114 let around = findWrappingOutside(range, nodeType); 4115 let inner = around && findWrappingInside(innerRange, nodeType); 4116 if (!inner) 4117 return null; 4118 return around.map(withAttrs).concat({ type: nodeType, attrs }).concat(inner.map(withAttrs)); 4119} 4120function withAttrs(type) { 4121 return { type, attrs: null }; 4122} 4123function findWrappingOutside(range, type) { 4124 let { parent, startIndex, endIndex } = range; 4125 let around = parent.contentMatchAt(startIndex).findWrapping(type); 4126 if (!around) 4127 return null; 4128 let outer = around.length ? around[0] : type; 4129 return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null; 4130}
vendor: 4,390 bytes, lines 4131-4224
4131function findWrappingInside(range, type) { 4132 let { parent, startIndex, endIndex } = range; 4133 let inner = parent.child(startIndex); 4134 let inside = type.contentMatch.findWrapping(inner.type); 4135 if (!inside) 4136 return null; 4137 let lastType = inside.length ? inside[inside.length - 1] : type; 4138 let innerMatch = lastType.contentMatch; 4139 for (let i = startIndex; innerMatch && i < endIndex; i++) 4140 innerMatch = innerMatch.matchType(parent.child(i).type); 4141 if (!innerMatch || !innerMatch.validEnd) 4142 return null; 4143 return inside; 4144} 4145function wrap(tr2, range, wrappers) { 4146 let content = Fragment.empty; 4147 for (let i = wrappers.length - 1; i >= 0; i--) { 4148 if (content.size) { 4149 let match = wrappers[i].type.contentMatch.matchFragment(content); 4150 if (!match || !match.validEnd) 4151 throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper"); 4152 } 4153 content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content)); 4154 } 4155 let start2 = range.start, end2 = range.end; 4156 tr2.step(new ReplaceAroundStep(start2, end2, start2, end2, new Slice(content, 0, 0), wrappers.length, true)); 4157} 4158function setBlockType$1(tr2, from2, to, type, attrs) { 4159 if (!type.isTextblock) 4160 throw new RangeError("Type given to setBlockType should be a textblock"); 4161 let mapFrom = tr2.steps.length; 4162 tr2.doc.nodesBetween(from2, to, (node, pos) => { 4163 if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(tr2.doc, tr2.mapping.slice(mapFrom).map(pos), type)) { 4164 let convertNewlines = null; 4165 if (type.schema.linebreakReplacement) { 4166 let pre = type.whitespace == "pre", supportLinebreak = !!type.contentMatch.matchType(type.schema.linebreakReplacement); 4167 if (pre && !supportLinebreak) 4168 convertNewlines = false; 4169 else if (!pre && supportLinebreak) 4170 convertNewlines = true; 4171 } 4172 if (convertNewlines === false) 4173 replaceLinebreaks(tr2, node, pos, mapFrom); 4174 clearIncompatible(tr2, tr2.mapping.slice(mapFrom).map(pos, 1), type, void 0, convertNewlines === null); 4175 let mapping = tr2.mapping.slice(mapFrom); 4176 let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1); 4177 tr2.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true)); 4178 if (convertNewlines === true) 4179 replaceNewlines(tr2, node, pos, mapFrom); 4180 return false; 4181 } 4182 }); 4183} 4184function replaceNewlines(tr2, node, pos, mapFrom) { 4185 node.forEach((child, offset2) => { 4186 if (child.isText) { 4187 let m, newline = /\r?\n|\r/g; 4188 while (m = newline.exec(child.text)) { 4189 let start2 = tr2.mapping.slice(mapFrom).map(pos + 1 + offset2 + m.index); 4190 tr2.replaceWith(start2, start2 + 1, node.type.schema.linebreakReplacement.create()); 4191 } 4192 } 4193 }); 4194} 4195function replaceLinebreaks(tr2, node, pos, mapFrom) { 4196 node.forEach((child, offset2) => { 4197 if (child.type == child.type.schema.linebreakReplacement) { 4198 let start2 = tr2.mapping.slice(mapFrom).map(pos + 1 + offset2); 4199 tr2.replaceWith(start2, start2 + 1, node.type.schema.text("\n")); 4200 } 4201 }); 4202} 4203function canChangeType(doc2, pos, type) { 4204 let $pos = doc2.resolve(pos), index = $pos.index(); 4205 return $pos.parent.canReplaceWith(index, index + 1, type); 4206} 4207function setNodeMarkup(tr2, pos, type, attrs, marks) { 4208 let node = tr2.doc.nodeAt(pos); 4209 if (!node) 4210 throw new RangeError("No node at given position"); 4211 if (!type) 4212 type = node.type; 4213 let newNode = type.create(attrs, null, marks || node.marks); 4214 if (node.isLeaf) 4215 return tr2.replaceWith(pos, pos + node.nodeSize, newNode); 4216 if (!type.validContent(node.content)) 4217 throw new RangeError("Invalid content for node type " + type.name); 4218 tr2.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, new Slice(Fragment.from(newNode), 0, 0), 1, true)); 4219} 4220function canSplit(doc2, pos, depth = 1, typesAfter) { 4221 let $pos = doc2.resolve(pos), base2 = $pos.depth - depth; 4222 let innerType = typesAfter && typesAfter[typesAfter.length - 1] || $pos.parent; 4223 if (base2 < 0 || $pos.parent.type.spec.isolating || !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) 4224 return false;
vendor: 4,644 bytes, lines 4225-4340
4225 for (let d = $pos.depth - 1, i = depth - 2; d > base2; d--, i--) { 4226 let node = $pos.node(d), index2 = $pos.index(d); 4227 if (node.type.spec.isolating) 4228 return false; 4229 let rest = node.content.cutByIndex(index2, node.childCount); 4230 let overrideChild = typesAfter && typesAfter[i + 1]; 4231 if (overrideChild) 4232 rest = rest.replaceChild(0, overrideChild.type.create(overrideChild.attrs)); 4233 let after = typesAfter && typesAfter[i] || node; 4234 if (!node.canReplace(index2 + 1, node.childCount) || !after.type.validContent(rest)) 4235 return false; 4236 } 4237 let index = $pos.indexAfter(base2); 4238 let baseType = typesAfter && typesAfter[0]; 4239 return $pos.node(base2).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base2 + 1).type); 4240} 4241function split(tr2, pos, depth = 1, typesAfter) { 4242 let $pos = tr2.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty; 4243 for (let d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) { 4244 before = Fragment.from($pos.node(d).copy(before)); 4245 let typeAfter = typesAfter && typesAfter[i]; 4246 after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after)); 4247 } 4248 tr2.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true)); 4249} 4250function canJoin(doc2, pos) { 4251 let $pos = doc2.resolve(pos), index = $pos.index(); 4252 return joinable($pos.nodeBefore, $pos.nodeAfter) && $pos.parent.canReplace(index, index + 1); 4253} 4254function joinable(a, b) { 4255 return !!(a && b && !a.isLeaf && a.canAppend(b)); 4256} 4257function joinPoint(doc2, pos, dir = -1) { 4258 let $pos = doc2.resolve(pos); 4259 for (let d = $pos.depth; ; d--) { 4260 let before, after, index = $pos.index(d); 4261 if (d == $pos.depth) { 4262 before = $pos.nodeBefore; 4263 after = $pos.nodeAfter; 4264 } else if (dir > 0) { 4265 before = $pos.node(d + 1); 4266 index++; 4267 after = $pos.node(d).maybeChild(index); 4268 } else { 4269 before = $pos.node(d).maybeChild(index - 1); 4270 after = $pos.node(d + 1); 4271 } 4272 if (before && !before.isTextblock && joinable(before, after) && $pos.node(d).canReplace(index, index + 1)) 4273 return pos; 4274 if (d == 0) 4275 break; 4276 pos = dir < 0 ? $pos.before(d) : $pos.after(d); 4277 } 4278} 4279function join(tr2, pos, depth) { 4280 let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true); 4281 tr2.step(step); 4282} 4283function insertPoint(doc2, pos, nodeType) { 4284 let $pos = doc2.resolve(pos); 4285 if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) 4286 return pos; 4287 if ($pos.parentOffset == 0) 4288 for (let d = $pos.depth - 1; d >= 0; d--) { 4289 let index = $pos.index(d); 4290 if ($pos.node(d).canReplaceWith(index, index, nodeType)) 4291 return $pos.before(d + 1); 4292 if (index > 0) 4293 return null; 4294 } 4295 if ($pos.parentOffset == $pos.parent.content.size) 4296 for (let d = $pos.depth - 1; d >= 0; d--) { 4297 let index = $pos.indexAfter(d); 4298 if ($pos.node(d).canReplaceWith(index, index, nodeType)) 4299 return $pos.after(d + 1); 4300 if (index < $pos.node(d).childCount) 4301 return null; 4302 } 4303 return null; 4304} 4305function dropPoint(doc2, pos, slice2) { 4306 let $pos = doc2.resolve(pos); 4307 if (!slice2.content.size) 4308 return pos; 4309 let content = slice2.content; 4310 for (let i = 0; i < slice2.openStart; i++) 4311 content = content.firstChild.content; 4312 for (let pass = 1; pass <= (slice2.openStart == 0 && slice2.size ? 2 : 1); pass++) { 4313 for (let d = $pos.depth; d >= 0; d--) { 4314 let bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1; 4315 let insertPos = $pos.index(d) + (bias > 0 ? 1 : 0); 4316 let parent = $pos.node(d), fits = false; 4317 if (pass == 1) { 4318 fits = parent.canReplace(insertPos, insertPos, content); 4319 } else { 4320 let wrapping = parent.contentMatchAt(insertPos).findWrapping(content.firstChild.type); 4321 fits = wrapping && parent.canReplaceWith(insertPos, insertPos, wrapping[0]); 4322 } 4323 if (fits) 4324 return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1); 4325 } 4326 } 4327 return null; 4328} 4329function replaceStep(doc2, from2, to = from2, slice2 = Slice.empty) { 4330 if (from2 == to && !slice2.size) 4331 return null; 4332 let $from = doc2.resolve(from2), $to = doc2.resolve(to); 4333 if (fitsTrivially($from, $to, slice2)) 4334 return new ReplaceStep(from2, to, slice2); 4335 return new Fitter($from, $to, slice2).fit(); 4336} 4337function fitsTrivially($from, $to, slice2) { 4338 return !slice2.openStart && !slice2.openEnd && $from.start() == $to.start() && $from.parent.canReplace($from.index(), $to.index(), slice2.content); 4339} 4340class Fitter {
vendor: 4,650 bytes, lines 4341-4452
4341 constructor($from, $to, unplaced) { 4342 this.$from = $from; 4343 this.$to = $to; 4344 this.unplaced = unplaced; 4345 this.frontier = []; 4346 this.placed = Fragment.empty; 4347 for (let i = 0; i <= $from.depth; i++) { 4348 let node = $from.node(i); 4349 this.frontier.push({ 4350 type: node.type, 4351 match: node.contentMatchAt($from.indexAfter(i)) 4352 }); 4353 } 4354 for (let i = $from.depth; i > 0; i--) 4355 this.placed = Fragment.from($from.node(i).copy(this.placed)); 4356 } 4357 get depth() { 4358 return this.frontier.length - 1; 4359 } 4360 fit() { 4361 while (this.unplaced.size) { 4362 let fit = this.findFittable(); 4363 if (fit) 4364 this.placeNodes(fit); 4365 else 4366 this.openMore() || this.dropNode(); 4367 } 4368 let moveInline = this.mustMoveInline(), placedSize = this.placed.size - this.depth - this.$from.depth; 4369 let $from = this.$from, $to = this.close(moveInline < 0 ? this.$to : $from.doc.resolve(moveInline)); 4370 if (!$to) 4371 return null; 4372 let content = this.placed, openStart = $from.depth, openEnd = $to.depth; 4373 while (openStart && openEnd && content.childCount == 1) { 4374 content = content.firstChild.content; 4375 openStart--; 4376 openEnd--; 4377 } 4378 let slice2 = new Slice(content, openStart, openEnd); 4379 if (moveInline > -1) 4380 return new ReplaceAroundStep($from.pos, moveInline, this.$to.pos, this.$to.end(), slice2, placedSize); 4381 if (slice2.size || $from.pos != this.$to.pos) 4382 return new ReplaceStep($from.pos, $to.pos, slice2); 4383 return null; 4384 } 4385 // Find a position on the start spine of `this.unplaced` that has 4386 // content that can be moved somewhere on the frontier. Returns two 4387 // depths, one for the slice and one for the frontier. 4388 findFittable() { 4389 let startDepth = this.unplaced.openStart; 4390 for (let cur = this.unplaced.content, d = 0, openEnd = this.unplaced.openEnd; d < startDepth; d++) { 4391 let node = cur.firstChild; 4392 if (cur.childCount > 1) 4393 openEnd = 0; 4394 if (node.type.spec.isolating && openEnd <= d) { 4395 startDepth = d; 4396 break; 4397 } 4398 cur = node.content; 4399 } 4400 for (let pass = 1; pass <= 2; pass++) { 4401 for (let sliceDepth = pass == 1 ? startDepth : this.unplaced.openStart; sliceDepth >= 0; sliceDepth--) { 4402 let fragment, parent = null; 4403 if (sliceDepth) { 4404 parent = contentAt(this.unplaced.content, sliceDepth - 1).firstChild; 4405 fragment = parent.content; 4406 } else { 4407 fragment = this.unplaced.content; 4408 } 4409 let first2 = fragment.firstChild; 4410 for (let frontierDepth = this.depth; frontierDepth >= 0; frontierDepth--) { 4411 let { type, match } = this.frontier[frontierDepth], wrap2, inject = null; 4412 if (pass == 1 && (first2 ? match.matchType(first2.type) || (inject = match.fillBefore(Fragment.from(first2), false)) : parent && type.compatibleContent(parent.type))) 4413 return { sliceDepth, frontierDepth, parent, inject }; 4414 else if (pass == 2 && first2 && (wrap2 = match.findWrapping(first2.type))) 4415 return { sliceDepth, frontierDepth, parent, wrap: wrap2 }; 4416 if (parent && match.matchType(parent.type)) 4417 break; 4418 } 4419 } 4420 } 4421 } 4422 openMore() { 4423 let { content, openStart, openEnd } = this.unplaced; 4424 let inner = contentAt(content, openStart); 4425 if (!inner.childCount || inner.firstChild.isLeaf) 4426 return false; 4427 this.unplaced = new Slice(content, openStart + 1, Math.max(openEnd, inner.size + openStart >= content.size - openEnd ? openStart + 1 : 0)); 4428 return true; 4429 } 4430 dropNode() { 4431 let { content, openStart, openEnd } = this.unplaced; 4432 let inner = contentAt(content, openStart); 4433 if (inner.childCount <= 1 && openStart > 0) { 4434 let openAtEnd = content.size - openStart <= openStart + inner.size; 4435 this.unplaced = new Slice(dropFromFragment(content, openStart - 1, 1), openStart - 1, openAtEnd ? openStart - 1 : openEnd); 4436 } else { 4437 this.unplaced = new Slice(dropFromFragment(content, openStart, 1), openStart, openEnd); 4438 } 4439 } 4440 // Move content from the unplaced slice at `sliceDepth` to the 4441 // frontier node at `frontierDepth`. Close that frontier node when 4442 // applicable. 4443 placeNodes({ sliceDepth, frontierDepth, parent, inject, wrap: wrap2 }) { 4444 while (this.depth > frontierDepth) 4445 this.closeFrontierNode(); 4446 if (wrap2) 4447 for (let i = 0; i < wrap2.length; i++) 4448 this.openFrontierNode(wrap2[i]); 4449 let slice2 = this.unplaced, fragment = parent ? parent.content : slice2.content; 4450 let openStart = slice2.openStart - sliceDepth; 4451 let taken = 0, add = []; 4452 let { match, type }
vendor: 5,395 bytes, lines 4452-4573
4452 = this.frontier[frontierDepth]; 4453 if (inject) { 4454 for (let i = 0; i < inject.childCount; i++) 4455 add.push(inject.child(i)); 4456 match = match.matchFragment(inject); 4457 } 4458 let openEndCount = fragment.size + sliceDepth - (slice2.content.size - slice2.openEnd); 4459 while (taken < fragment.childCount) { 4460 let next = fragment.child(taken), matches2 = match.matchType(next.type); 4461 if (!matches2) 4462 break; 4463 taken++; 4464 if (taken > 1 || openStart == 0 || next.content.size) { 4465 match = matches2; 4466 add.push(closeNodeStart(next.mark(type.allowedMarks(next.marks)), taken == 1 ? openStart : 0, taken == fragment.childCount ? openEndCount : -1)); 4467 } 4468 } 4469 let toEnd = taken == fragment.childCount; 4470 if (!toEnd) 4471 openEndCount = -1; 4472 this.placed = addToFragment(this.placed, frontierDepth, Fragment.from(add)); 4473 this.frontier[frontierDepth].match = match; 4474 if (toEnd && openEndCount < 0 && parent && parent.type == this.frontier[this.depth].type && this.frontier.length > 1) 4475 this.closeFrontierNode(); 4476 for (let i = 0, cur = fragment; i < openEndCount; i++) { 4477 let node = cur.lastChild; 4478 this.frontier.push({ type: node.type, match: node.contentMatchAt(node.childCount) }); 4479 cur = node.content; 4480 } 4481 this.unplaced = !toEnd ? new Slice(dropFromFragment(slice2.content, sliceDepth, taken), slice2.openStart, slice2.openEnd) : sliceDepth == 0 ? Slice.empty : new Slice(dropFromFragment(slice2.content, sliceDepth - 1, 1), sliceDepth - 1, openEndCount < 0 ? slice2.openEnd : sliceDepth - 1); 4482 } 4483 mustMoveInline() { 4484 if (!this.$to.parent.isTextblock) 4485 return -1; 4486 let top2 = this.frontier[this.depth], level; 4487 if (!top2.type.isTextblock || !contentAfterFits(this.$to, this.$to.depth, top2.type, top2.match, false) || this.$to.depth == this.depth && (level = this.findCloseLevel(this.$to)) && level.depth == this.depth) 4488 return -1; 4489 let { depth } = this.$to, after = this.$to.after(depth); 4490 while (depth > 1 && after == this.$to.end(--depth)) 4491 ++after; 4492 return after; 4493 } 4494 findCloseLevel($to) { 4495 scan: 4496 for (let i = Math.min(this.depth, $to.depth); i >= 0; i--) { 4497 let { match, type } = this.frontier[i]; 4498 let dropInner = i < $to.depth && $to.end(i + 1) == $to.pos + ($to.depth - (i + 1)); 4499 let fit = contentAfterFits($to, i, type, match, dropInner); 4500 if (!fit) 4501 continue; 4502 for (let d = i - 1; d >= 0; d--) { 4503 let { match: match2, type: type2 } = this.frontier[d]; 4504 let matches2 = contentAfterFits($to, d, type2, match2, true); 4505 if (!matches2 || matches2.childCount) 4506 continue scan; 4507 } 4508 return { depth: i, fit, move: dropInner ? $to.doc.resolve($to.after(i + 1)) : $to }; 4509 } 4510 } 4511 close($to) { 4512 let close2 = this.findCloseLevel($to); 4513 if (!close2) 4514 return null; 4515 while (this.depth > close2.depth) 4516 this.closeFrontierNode(); 4517 if (close2.fit.childCount) 4518 this.placed = addToFragment(this.placed, close2.depth, close2.fit); 4519 $to = close2.move; 4520 for (let d = close2.depth + 1; d <= $to.depth; d++) { 4521 let node = $to.node(d), add = node.type.contentMatch.fillBefore(node.content, true, $to.index(d)); 4522 this.openFrontierNode(node.type, node.attrs, add); 4523 } 4524 return $to; 4525 } 4526 openFrontierNode(type, attrs = null, content) { 4527 let top2 = this.frontier[this.depth]; 4528 top2.match = top2.match.matchType(type); 4529 this.placed = addToFragment(this.placed, this.depth, Fragment.from(type.create(attrs, content))); 4530 this.frontier.push({ type, match: type.contentMatch }); 4531 } 4532 closeFrontierNode() { 4533 let open = this.frontier.pop(); 4534 let add = open.match.fillBefore(Fragment.empty, true); 4535 if (add.childCount) 4536 this.placed = addToFragment(this.placed, this.frontier.length, add); 4537 } 4538} 4539function dropFromFragment(fragment, depth, count) { 4540 if (depth == 0) 4541 return fragment.cutByIndex(count, fragment.childCount); 4542 return fragment.replaceChild(0, fragment.firstChild.copy(dropFromFragment(fragment.firstChild.content, depth - 1, count))); 4543} 4544function addToFragment(fragment, depth, content) { 4545 if (depth == 0) 4546 return fragment.append(content); 4547 return fragment.replaceChild(fragment.childCount - 1, fragment.lastChild.copy(addToFragment(fragment.lastChild.content, depth - 1, content))); 4548} 4549function contentAt(fragment, depth) { 4550 for (let i = 0; i < depth; i++) 4551 fragment = fragment.firstChild.content; 4552 return fragment; 4553} 4554function closeNodeStart(node, openStart, openEnd) { 4555 if (openStart <= 0) 4556 return node; 4557 let frag = node.content; 4558 if (openStart > 1) 4559 frag = frag.replaceChild(0, closeNodeStart(frag.firstChild, openStart - 1, frag.childCount == 1 ? openEnd - 1 : 0)); 4560 if (openStart > 0) { 4561 frag = node.type.contentMatch.fillBefore(frag).append(frag); 4562 if (openEnd <= 0) 4563 frag = frag.append(node.type.contentMatch.matchFragment(frag).fillBefore(Fragment.empty, true)); 4564 } 4565 return node.copy(frag); 4566} 4567function contentAfterFits($to, depth, type, match, open) { 4568 let node = $to.node(depth), index = open ? $to.indexAfter(depth) : $to.index(depth); 4569 if (index == node.childCount && !type.compatibleContent(node.type)) 4570 return null; 4571 let fit = match.fillBefore(node.content, true, index); 4572 return fit && !invalidMarks(type, node.content, index) ? fit : null; 4573}
vendor: 4,790 bytes, lines 4574-4687
4574function invalidMarks(type, fragment, start2) { 4575 for (let i = start2; i < fragment.childCount; i++) 4576 if (!type.allowsMarks(fragment.child(i).marks)) 4577 return true; 4578 return false; 4579} 4580function definesContent(type) { 4581 return type.spec.defining || type.spec.definingForContent; 4582} 4583function replaceRange(tr2, from2, to, slice2) { 4584 if (!slice2.size) 4585 return tr2.deleteRange(from2, to); 4586 let $from = tr2.doc.resolve(from2), $to = tr2.doc.resolve(to); 4587 if (fitsTrivially($from, $to, slice2)) 4588 return tr2.step(new ReplaceStep(from2, to, slice2)); 4589 let targetDepths = coveredDepths($from, tr2.doc.resolve(to)); 4590 if (targetDepths[targetDepths.length - 1] == 0) 4591 targetDepths.pop(); 4592 let preferredTarget = -($from.depth + 1); 4593 targetDepths.unshift(preferredTarget); 4594 for (let d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) { 4595 let spec = $from.node(d).type.spec; 4596 if (spec.defining || spec.definingAsContext || spec.isolating) 4597 break; 4598 if (targetDepths.indexOf(d) > -1) 4599 preferredTarget = d; 4600 else if ($from.before(d) == pos) 4601 targetDepths.splice(1, 0, -d); 4602 } 4603 let preferredTargetIndex = targetDepths.indexOf(preferredTarget); 4604 let leftNodes = [], preferredDepth = slice2.openStart; 4605 for (let content = slice2.content, i = 0; ; i++) { 4606 let node = content.firstChild; 4607 leftNodes.push(node); 4608 if (i == slice2.openStart) 4609 break; 4610 content = node.content; 4611 } 4612 for (let d = preferredDepth - 1; d >= 0; d--) { 4613 let leftNode = leftNodes[d], def = definesContent(leftNode.type); 4614 if (def && !leftNode.sameMarkup($from.node(Math.abs(preferredTarget) - 1))) 4615 preferredDepth = d; 4616 else if (def || !leftNode.type.isTextblock) 4617 break; 4618 } 4619 for (let j = slice2.openStart; j >= 0; j--) { 4620 let openDepth = (j + preferredDepth + 1) % (slice2.openStart + 1); 4621 let insert = leftNodes[openDepth]; 4622 if (!insert) 4623 continue; 4624 for (let i = 0; i < targetDepths.length; i++) { 4625 let targetDepth = targetDepths[(i + preferredTargetIndex) % targetDepths.length], expand = true; 4626 if (targetDepth < 0) { 4627 expand = false; 4628 targetDepth = -targetDepth; 4629 } 4630 let parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1); 4631 if (parent.canReplaceWith(index, index, insert.type, insert.marks)) 4632 return tr2.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, new Slice(closeFragment(slice2.content, 0, slice2.openStart, openDepth), openDepth, slice2.openEnd)); 4633 } 4634 } 4635 let startSteps = tr2.steps.length; 4636 for (let i = targetDepths.length - 1; i >= 0; i--) { 4637 tr2.replace(from2, to, slice2); 4638 if (tr2.steps.length > startSteps) 4639 break; 4640 let depth = targetDepths[i]; 4641 if (depth < 0) 4642 continue; 4643 from2 = $from.before(depth); 4644 to = $to.after(depth); 4645 } 4646} 4647function closeFragment(fragment, depth, oldOpen, newOpen, parent) { 4648 if (depth < oldOpen) { 4649 let first2 = fragment.firstChild; 4650 fragment = fragment.replaceChild(0, first2.copy(closeFragment(first2.content, depth + 1, oldOpen, newOpen, first2))); 4651 } 4652 if (depth > newOpen) { 4653 let match = parent.contentMatchAt(0); 4654 let start2 = match.fillBefore(fragment).append(fragment); 4655 fragment = start2.append(match.matchFragment(start2).fillBefore(Fragment.empty, true)); 4656 } 4657 return fragment; 4658} 4659function replaceRangeWith(tr2, from2, to, node) { 4660 if (!node.isInline && from2 == to && tr2.doc.resolve(from2).parent.content.size) { 4661 let point = insertPoint(tr2.doc, from2, node.type); 4662 if (point != null) 4663 from2 = to = point; 4664 } 4665 tr2.replaceRange(from2, to, new Slice(Fragment.from(node), 0, 0)); 4666} 4667function deleteRange$1(tr2, from2, to) { 4668 let $from = tr2.doc.resolve(from2), $to = tr2.doc.resolve(to); 4669 let covered = coveredDepths($from, $to); 4670 for (let i = 0; i < covered.length; i++) { 4671 let depth = covered[i], last = i == covered.length - 1; 4672 if (last && depth == 0 || $from.node(depth).type.contentMatch.validEnd) 4673 return tr2.delete($from.start(depth), $to.end(depth)); 4674 if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) 4675 return tr2.delete($from.before(depth), $to.after(depth)); 4676 } 4677 for (let d = 1; d <= $from.depth && d <= $to.depth; d++) { 4678 if (from2 - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d) 4679 return tr2.delete($from.before(d), to); 4680 } 4681 tr2.delete(from2, to); 4682} 4683function coveredDepths($from, $to) { 4684 let result = [], minDepth = Math.min($from.depth, $to.depth); 4685 for (let d = minDepth; d >= 0; d--) { 4686 let start2 = $from.start(d); 4687 if (start2 < $from.pos - ($from.depth - d) || $to.end(d) > $to.pos + ($to.depth - d) || $from.node(d).type.spec.isolating || $to.node(d
vendor: 7,604 bytes, lines 4687-4928
4687).type.spec.isolating) 4688 break; 4689 if (start2 == $to.start(d) || d == $from.depth && d == $to.depth && $from.parent.inlineContent && $to.parent.inlineContent && d && $to.start(d - 1) == start2 - 1) 4690 result.push(d); 4691 } 4692 return result; 4693} 4694class AttrStep extends Step { 4695 /** 4696 Construct an attribute step. 4697 */ 4698 constructor(pos, attr, value) { 4699 super(); 4700 this.pos = pos; 4701 this.attr = attr; 4702 this.value = value; 4703 } 4704 apply(doc2) { 4705 let node = doc2.nodeAt(this.pos); 4706 if (!node) 4707 return StepResult.fail("No node at attribute step's position"); 4708 let attrs = /* @__PURE__ */ Object.create(null); 4709 for (let name in node.attrs) 4710 attrs[name] = node.attrs[name]; 4711 attrs[this.attr] = this.value; 4712 let updated = node.type.create(attrs, null, node.marks); 4713 return StepResult.fromReplace(doc2, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1)); 4714 } 4715 getMap() { 4716 return StepMap.empty; 4717 } 4718 invert(doc2) { 4719 return new AttrStep(this.pos, this.attr, doc2.nodeAt(this.pos).attrs[this.attr]); 4720 } 4721 map(mapping) { 4722 let pos = mapping.mapResult(this.pos, 1); 4723 return pos.deletedAfter ? null : new AttrStep(pos.pos, this.attr, this.value); 4724 } 4725 toJSON() { 4726 return { stepType: "attr", pos: this.pos, attr: this.attr, value: this.value }; 4727 } 4728 static fromJSON(schema, json) { 4729 if (typeof json.pos != "number" || typeof json.attr != "string") 4730 throw new RangeError("Invalid input for AttrStep.fromJSON"); 4731 return new AttrStep(json.pos, json.attr, json.value); 4732 } 4733} 4734Step.jsonID("attr", AttrStep); 4735class DocAttrStep extends Step { 4736 /** 4737 Construct an attribute step. 4738 */ 4739 constructor(attr, value) { 4740 super(); 4741 this.attr = attr; 4742 this.value = value; 4743 } 4744 apply(doc2) { 4745 let attrs = /* @__PURE__ */ Object.create(null); 4746 for (let name in doc2.attrs) 4747 attrs[name] = doc2.attrs[name]; 4748 attrs[this.attr] = this.value; 4749 let updated = doc2.type.create(attrs, doc2.content, doc2.marks); 4750 return StepResult.ok(updated); 4751 } 4752 getMap() { 4753 return StepMap.empty; 4754 } 4755 invert(doc2) { 4756 return new DocAttrStep(this.attr, doc2.attrs[this.attr]); 4757 } 4758 map(mapping) { 4759 return this; 4760 } 4761 toJSON() { 4762 return { stepType: "docAttr", attr: this.attr, value: this.value }; 4763 } 4764 static fromJSON(schema, json) { 4765 if (typeof json.attr != "string") 4766 throw new RangeError("Invalid input for DocAttrStep.fromJSON"); 4767 return new DocAttrStep(json.attr, json.value); 4768 } 4769} 4770Step.jsonID("docAttr", DocAttrStep); 4771let TransformError = class extends Error { 4772}; 4773TransformError = function TransformError2(message) { 4774 let err = Error.call(this, message); 4775 err.__proto__ = TransformError2.prototype; 4776 return err; 4777}; 4778TransformError.prototype = Object.create(Error.prototype); 4779TransformError.prototype.constructor = TransformError; 4780TransformError.prototype.name = "TransformError"; 4781class Transform { 4782 /** 4783 Create a transform that starts with the given document. 4784 */ 4785 constructor(doc2) { 4786 this.doc = doc2; 4787 this.steps = []; 4788 this.docs = []; 4789 this.mapping = new Mapping(); 4790 } 4791 /** 4792 The starting document. 4793 */ 4794 get before() { 4795 return this.docs.length ? this.docs[0] : this.doc; 4796 } 4797 /** 4798 Apply a new step in this transform, saving the result. Throws an 4799 error when the step fails. 4800 */ 4801 step(step) { 4802 let result = this.maybeStep(step); 4803 if (result.failed) 4804 throw new TransformError(result.failed); 4805 return this; 4806 } 4807 /** 4808 Try to apply a step in this transformation, ignoring it if it 4809 fails. Returns the step result. 4810 */ 4811 maybeStep(step) { 4812 let result = step.apply(this.doc); 4813 if (!result.failed) 4814 this.addStep(step, result.doc); 4815 return result; 4816 } 4817 /** 4818 True when the document has been changed (when there are any 4819 steps). 4820 */ 4821 get docChanged() { 4822 return this.steps.length > 0; 4823 } 4824 /** 4825 @internal 4826 */ 4827 addStep(step, doc2) { 4828 this.docs.push(this.doc); 4829 this.steps.push(step); 4830 this.mapping.appendMap(step.getMap()); 4831 this.doc = doc2; 4832 } 4833 /** 4834 Replace the part of the document between `from` and `to` with the 4835 given `slice`. 4836 */ 4837 replace(from2, to = from2, slice2 = Slice.empty) { 4838 let step = replaceStep(this.doc, from2, to, slice2); 4839 if (step) 4840 this.step(step); 4841 return this; 4842 } 4843 /** 4844 Replace the given range with the given content, which may be a 4845 fragment, node, or array of nodes. 4846 */ 4847 replaceWith(from2, to, content) { 4848 return this.replace(from2, to, new Slice(Fragment.from(content), 0, 0)); 4849 } 4850 /** 4851 Delete the content between the given positions. 4852 */ 4853 delete(from2, to) { 4854 return this.replace(from2, to, Slice.empty); 4855 } 4856 /** 4857 Insert the given content at the given position. 4858 */ 4859 insert(pos, content) { 4860 return this.replaceWith(pos, pos, content); 4861 } 4862 /** 4863 Replace a range of the document with a given slice, using 4864 `from`, `to`, and the slice's 4865 [`openStart`](https://prosemirror.net/docs/ref/#model.Slice.openStart) property as hints, rather 4866 than fixed start and end points. This method may grow the 4867 replaced area or close open nodes in the slice in order to get a 4868 fit that is more in line with WYSIWYG expectations, by dropping 4869 fully covered parent nodes of the replaced region when they are 4870 marked [non-defining as 4871 context](https://prosemirror.net/docs/ref/#model.NodeSpec.definingAsContext), or including an 4872 open parent node from the slice that _is_ marked as [defining 4873 its content](https://prosemirror.net/docs/ref/#model.NodeSpec.definingForContent). 4874 4875 This is the method, for example, to handle paste. The similar 4876 [`replace`](https://prosemirror.net/docs/ref/#transform.Transform.replace) method is a more 4877 primitive tool which will _not_ move the start and end of its given 4878 range, and is useful in situations where you need more precise 4879 control over what happens. 4880 */ 4881 replaceRange(from2, to, slice2) { 4882 replaceRange(this, from2, to, slice2); 4883 return this; 4884 } 4885 /** 4886 Replace the given range with a node, but use `from` and `to` as 4887 hints, rather than precise positions. When from and to are the same 4888 and are at the start or end of a parent node in which the given 4889 node doesn't fit, this method may _move_ them out towards a parent 4890 that does allow the given node to be placed. When the given range 4891 completely covers a parent node, this method may completely replace 4892 that parent node. 4893 */ 4894 replaceRangeWith(from2, to, node) { 4895 replaceRangeWith(this, from2, to, node); 4896 return this; 4897 } 4898 /** 4899 Delete the given range, expanding it to cover fully covered 4900 parent nodes until a valid replace is found. 4901 */ 4902 deleteRange(from2, to) { 4903 deleteRange$1(this, from2, to); 4904 return this; 4905 } 4906 /** 4907 Split the content in the given range off from its parent, if there 4908 is sibling content before or after it, and move it up the tree to 4909 the depth specified by `target`. You'll probably want to use 4910 [`liftTarget`](https://prosemirror.net/docs/ref/#transform.liftTarget) to compute `target`, to make 4911 sure the lift is valid. 4912 */ 4913 lift(range, target) { 4914 lift$2(this, range, target); 4915 return this; 4916 } 4917 /** 4918 Join the blocks around the given position. If depth is 2, their 4919 last and first siblings are also joined, and so on. 4920 */ 4921 join(pos, depth = 1) { 4922 join(this, pos, depth); 4923 return this; 4924 } 4925 /** 4926 Wrap the given [range](https://prosemirror.net/docs/ref/#model.NodeRange) in the given set of wrappers. 4927 The wrappers are assumed to be valid in this position, and should 4928 probably be computed with [`findWrapping`](https://prosemirror.net/docs/ref/#transform.findWra
4928pping). 4929 */ 4930 wrap(range, wrappers) { 4931 wrap(this, range, wrappers); 4932 return this; 4933 } 4934 /** 4935 Set the type of all textblocks (partly) between `from` and `to` to 4936 the given node type with the given attributes. 4937 */ 4938 setBlockType(from2, to = from2, type, attrs = null) { 4939 setBlockType$1(this, from2, to, type, attrs); 4940 return this; 4941 } 4942 /** 4943 Change the type, attributes, and/or marks of the node at `pos`. 4944 When `type` isn't given, the existing node type is preserved, 4945 */ 4946 setNodeMarkup(pos, type, attrs = null, marks) { 4947 setNodeMarkup(this, pos, type, attrs, marks); 4948 return this; 4949 } 4950 /** 4951 Set a single attribute on a given node to a new value. 4952 The `pos` addresses the document content. Use `setDocAttribute` 4953 to set attributes on the document itself. 4954 */ 4955 setNodeAttribute(pos, attr, value) { 4956 this.step(new AttrStep(pos, attr, value)); 4957 return this; 4958 } 4959 /** 4960 Set a single attribute on the document to a new value. 4961 */ 4962 setDocAttribute(attr, value) { 4963 this.step(new DocAttrStep(attr, value)); 4964 return this; 4965 } 4966 /** 4967 Add a mark to the node at position `pos`. 4968 */ 4969 addNodeMark(pos, mark) { 4970 this.step(new AddNodeMarkStep(pos, mark)); 4971 return this; 4972 } 4973 /** 4974 Remove a mark (or a mark of the given type) from the node at 4975 position `pos`. 4976 */ 4977 removeNodeMark(pos, mark) { 4978 if (!(mark instanceof Mark$1)) { 4979 let node = this.doc.nodeAt(pos); 4980 if (!node) 4981 throw new RangeError("No node at position " + pos); 4982 mark = mark.isInSet(node.marks); 4983 if (!mark) 4984 return this; 4985 } 4986 this.step(new RemoveNodeMarkStep(pos, mark)); 4987 return this; 4988 } 4989 /** 4990 Split the node at the given position, and optionally, if `depth` is 4991 greater than one, any number of nodes above that. By default, the 4992 parts split off will inherit the node type of the original node. 4993 This can be changed by passing an array of types and attributes to 4994 use after the split. 4995 */ 4996 split(pos, depth = 1, typesAfter) { 4997 split(this, pos, depth, typesAfter); 4998 return this; 4999 } 5000 /** 5001 Add the given mark to the inline content between `from` and `to`. 5002 */ 5003 addMark(from2, to, mark) { 5004 addMark(this, from2, to, mark); 5005 return this; 5006 } 5007 /** 5008 Remove marks from inline nodes between `from` and `to`. When 5009 `mark` is a single mark, remove precisely that mark. When it is 5010 a mark type, remove all marks of that type. When it is null, 5011 remove all marks of any type. 5012 */ 5013 removeMark(from2, to, mark) { 5014 removeMark(this, from2, to, mark); 5015 return this; 5016 } 5017 /** 5018 Removes all marks and nodes from the content of the node at 5019 `pos` that don't match the given new parent node type. Accepts 5020 an optional starting [content match](https://prosemirror.net/docs/ref/#model.ContentMatch) as 5021 third argument. 5022 */ 5023 clearIncompatible(pos, parentType, match) { 5024 clearIncompatible(this, pos, parentType, match); 5025 return this; 5026 } 5027} 5028const classesById = /* @__PURE__ */ Object.create(null); 5029class Selection { 5030 /** 5031 Initialize a selection with the head and anchor and ranges. If no 5032 ranges are given, constructs a single range across `$anchor` and 5033 `$head`. 5034 */ 5035 constructor($anchor, $head, ranges) { 5036 this.$anchor = $anchor; 5037 this.$head = $head; 5038 this.ranges = ranges || [new SelectionRange($anchor.min($head), $anchor.max($head))]; 5039 } 5040 /** 5041 The selection's anchor, as an unresolved position. 5042 */ 5043 get anchor() { 5044 return this.$anchor.pos; 5045 } 5046 /** 5047 The selection's head. 5048 */ 5049 get head() { 5050 return this.$head.pos; 5051 } 5052 /** 5053 The lower bound of the selection's main range. 5054 */ 5055 get from() { 5056 return this.$from.pos; 5057 } 5058 /** 5059 The upper bound of the selection's main range. 5060 */ 5061 get to() { 5062 return this.$to.pos; 5063 } 5064 /** 5065 The resolved lower bound of the selection's main range. 5066 */ 5067 get $from() { 5068 return this.ranges[0].$from; 5069 } 5070 /** 5071 The resolved upper bound of the selection's main range. 5072 */ 5073 get $to() { 5074 return this.ranges[0].$to; 5075 } 5076 /** 5077 Indicates whether the selection contains any content. 5078 */ 5079 get empty() { 5080 let ranges = this.ranges; 5081 for (let i = 0; i < ranges.length; i++) 5082 if (ranges[i].$from.pos != ranges[i].$to.pos) 5083 return false;
vendor: 16,479 bytes, lines 5084-5602
5084 return true; 5085 } 5086 /** 5087 Get the content of this selection as a slice. 5088 */ 5089 content() { 5090 return this.$from.doc.slice(this.from, this.to, true); 5091 } 5092 /** 5093 Replace the selection with a slice or, if no slice is given, 5094 delete the selection. Will append to the given transaction. 5095 */ 5096 replace(tr2, content = Slice.empty) { 5097 let lastNode = content.content.lastChild, lastParent = null; 5098 for (let i = 0; i < content.openEnd; i++) { 5099 lastParent = lastNode; 5100 lastNode = lastNode.lastChild; 5101 } 5102 let mapFrom = tr2.steps.length, ranges = this.ranges; 5103 for (let i = 0; i < ranges.length; i++) { 5104 let { $from, $to } = ranges[i], mapping = tr2.mapping.slice(mapFrom); 5105 tr2.replaceRange(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content); 5106 if (i == 0) 5107 selectionToInsertionEnd$1(tr2, mapFrom, (lastNode ? lastNode.isInline : lastParent && lastParent.isTextblock) ? -1 : 1); 5108 } 5109 } 5110 /** 5111 Replace the selection with the given node, appending the changes 5112 to the given transaction. 5113 */ 5114 replaceWith(tr2, node) { 5115 let mapFrom = tr2.steps.length, ranges = this.ranges; 5116 for (let i = 0; i < ranges.length; i++) { 5117 let { $from, $to } = ranges[i], mapping = tr2.mapping.slice(mapFrom); 5118 let from2 = mapping.map($from.pos), to = mapping.map($to.pos); 5119 if (i) { 5120 tr2.deleteRange(from2, to); 5121 } else { 5122 tr2.replaceRangeWith(from2, to, node); 5123 selectionToInsertionEnd$1(tr2, mapFrom, node.isInline ? -1 : 1); 5124 } 5125 } 5126 } 5127 /** 5128 Find a valid cursor or leaf node selection starting at the given 5129 position and searching back if `dir` is negative, and forward if 5130 positive. When `textOnly` is true, only consider cursor 5131 selections. Will return null when no valid selection position is 5132 found. 5133 */ 5134 static findFrom($pos, dir, textOnly = false) { 5135 let inner = $pos.parent.inlineContent ? new TextSelection($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly); 5136 if (inner) 5137 return inner; 5138 for (let depth = $pos.depth - 1; depth >= 0; depth--) { 5139 let found2 = dir < 0 ? findSelectionIn($pos.node(0), $pos.node(depth), $pos.before(depth + 1), $pos.index(depth), dir, textOnly) : findSelectionIn($pos.node(0), $pos.node(depth), $pos.after(depth + 1), $pos.index(depth) + 1, dir, textOnly); 5140 if (found2) 5141 return found2; 5142 } 5143 return null; 5144 } 5145 /** 5146 Find a valid cursor or leaf node selection near the given 5147 position. Searches forward first by default, but if `bias` is 5148 negative, it will search backwards first. 5149 */ 5150 static near($pos, bias = 1) { 5151 return this.findFrom($pos, bias) || this.findFrom($pos, -bias) || new AllSelection($pos.node(0)); 5152 } 5153 /** 5154 Find the cursor or leaf node selection closest to the start of 5155 the given document. Will return an 5156 [`AllSelection`](https://prosemirror.net/docs/ref/#state.AllSelection) if no valid position 5157 exists. 5158 */ 5159 static atStart(doc2) { 5160 return findSelectionIn(doc2, doc2, 0, 0, 1) || new AllSelection(doc2); 5161 } 5162 /** 5163 Find the cursor or leaf node selection closest to the end of the 5164 given document. 5165 */ 5166 static atEnd(doc2) { 5167 return findSelectionIn(doc2, doc2, doc2.content.size, doc2.childCount, -1) || new AllSelection(doc2); 5168 } 5169 /** 5170 Deserialize the JSON representation of a selection. Must be 5171 implemented for custom classes (as a static class method). 5172 */ 5173 static fromJSON(doc2, json) { 5174 if (!json || !json.type) 5175 throw new RangeError("Invalid input for Selection.fromJSON"); 5176 let cls = classesById[json.type]; 5177 if (!cls) 5178 throw new RangeError(`No selection type ${json.type} defined`); 5179 return cls.fromJSON(doc2, json); 5180 } 5181 /** 5182 To be able to deserialize selections from JSON, custom selection 5183 classes must register themselves with an ID string, so that they 5184 can be disambiguated. Try to pick something that's unlikely to 5185 clash with classes from other modules. 5186 */ 5187 static jsonID(id, selectionClass) { 5188 if (id in classesById) 5189 throw new RangeError("Duplicate use of selection JSON ID " + id); 5190 classesById[id] = selectionClass; 5191 selectionClass.prototype.jsonID = id; 5192 return selectionClass; 5193 } 5194 /** 5195 Get a [bookmark](https://prosemirror.net/docs/ref/#state.SelectionBookmark) for this selection, 5196 which is a value that can be mapped without having access to a 5197 current document, and later resolved to a real selection for a 5198 given document again. (This is used mostly by the history to 5199 track and restore old selections.) The default implementation of 5200 this method just converts the selection to a text selection and 5201 returns the bookmark for that. 5202 */ 5203 getBookmark() { 5204 return TextSelection.between(this.$anchor, this.$head).getBookmark(); 5205 } 5206} 5207Selection.prototype.visible = true; 5208class SelectionRange { 5209 /** 5210 Create a range. 5211 */ 5212 constructor($from, $to) { 5213 this.$from = $from; 5214 this.$to = $to; 5215 } 5216} 5217let warnedAboutTextSelection = false; 5218function checkTextSelection($pos) { 5219 if (!warnedAboutTextSelection && !$pos.parent.inlineContent) { 5220 warnedAboutTextSelection = true; 5221 console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")"); 5222 } 5223} 5224class TextSelection extends Selection { 5225 /** 5226 Construct a text selection between the given points. 5227 */ 5228 constructor($anchor, $head = $anchor) { 5229 checkTextSelection($anchor); 5230 checkTextSelection($head); 5231 super($anchor, $head); 5232 } 5233 /** 5234 Returns a resolved position if this is a cursor selection (an 5235 empty text selection), and null otherwise. 5236 */ 5237 get $cursor() { 5238 return this.$anchor.pos == this.$head.pos ? this.$head : null; 5239 } 5240 map(doc2, mapping) { 5241 let $head = doc2.resolve(mapping.map(this.head)); 5242 if (!$head.parent.inlineContent) 5243 return Selection.near($head); 5244 let $anchor = doc2.resolve(mapping.map(this.anchor)); 5245 return new TextSelection($anchor.parent.inlineContent ? $anchor : $head, $head); 5246 } 5247 replace(tr2, content = Slice.empty) { 5248 super.replace(tr2, content); 5249 if (content == Slice.empty) { 5250 let marks = this.$from.marksAcross(this.$to); 5251 if (marks) 5252 tr2.ensureMarks(marks); 5253 } 5254 } 5255 eq(other) { 5256 return other instanceof TextSelection && other.anchor == this.anchor && other.head == this.head; 5257 } 5258 getBookmark() { 5259 return new TextBookmark(this.anchor, this.head); 5260 } 5261 toJSON() { 5262 return { type: "text", anchor: this.anchor, head: this.head }; 5263 } 5264 /** 5265 @internal 5266 */ 5267 static fromJSON(doc2, json) { 5268 if (typeof json.anchor != "number" || typeof json.head != "number") 5269 throw new RangeError("Invalid input for TextSelection.fromJSON"); 5270 return new TextSelection(doc2.resolve(json.anchor), doc2.resolve(json.head)); 5271 } 5272 /** 5273 Create a text selection from non-resolved positions. 5274 */ 5275 static create(doc2, anchor, head = anchor) { 5276 let $anchor = doc2.resolve(anchor); 5277 return new this($anchor, head == anchor ? $anchor : doc2.resolve(head)); 5278 } 5279 /** 5280 Return a text selection that spans the given positions or, if 5281 they aren't text positions, find a text selection near them. 5282 `bias` determines whether the method searches forward (default) 5283 or backwards (negative number) first. Will fall back to calling 5284 [`Selection.near`](https://prosemirror.net/docs/ref/#state.Selection^near) when the document 5285 doesn't contain a valid text position. 5286 */ 5287 static between($anchor, $head, bias) { 5288 let dPos = $anchor.pos - $head.pos; 5289 if (!bias || dPos) 5290 bias = dPos >= 0 ? 1 : -1; 5291 if (!$head.parent.inlineContent) { 5292 let found2 = Selection.findFrom($head, bias, true) || Selection.findFrom($head, -bias, true); 5293 if (found2) 5294 $head = found2.$head; 5295 else 5296 return Selection.near($head, bias); 5297 } 5298 if (!$anchor.parent.inlineContent) { 5299 if (dPos == 0) { 5300 $anchor = $head; 5301 } else { 5302 $anchor = (Selection.findFrom($anchor, -bias, true) || Selection.findFrom($anchor, bias, true)).$anchor; 5303 if ($anchor.pos < $head.pos != dPos < 0) 5304 $anchor = $head; 5305 } 5306 } 5307 return new TextSelection($anchor, $head); 5308 } 5309} 5310Selection.jsonID("text", TextSelection); 5311class TextBookmark { 5312 constructor(anchor, head) { 5313 this.anchor = anchor; 5314 this.head = head; 5315 } 5316 map(mapping) { 5317 return new TextBookmark(mapping.map(this.anchor), mapping.map(this.head)); 5318 } 5319 resolve(doc2) { 5320 return TextSelection.between(doc2.resolve(this.anchor), doc2.resolve(this.head)); 5321 } 5322} 5323class NodeSelection extends Selection { 5324 /** 5325 Create a node selection. Does not verify the validity of its 5326 argument. 5327 */ 5328 constructor($pos) { 5329 let node = $pos.nodeAfter; 5330 let $end = $pos.node(0).resolve($pos.pos + node.nodeSize); 5331 super($pos, $end); 5332 this.node = node; 5333 } 5334 map(doc2, mapping) { 5335 let { deleted, pos } = mapping.mapResult(this.anchor); 5336 let $pos = doc2.resolve(pos); 5337 if (deleted) 5338 return Selection.near($pos); 5339 return new NodeSelection($pos); 5340 } 5341 content() { 5342 return new Slice(Fragment.from(this.node), 0, 0); 5343 } 5344 eq(other) { 5345 return other instanceof NodeSelection && other.anchor == this.anchor; 5346 } 5347 toJSON() { 5348 return { type: "node", anchor: this.anchor }; 5349 } 5350 getBookmark() { 5351 return new NodeBookmark(this.anchor); 5352 } 5353 /** 5354 @internal 5355 */ 5356 static fromJSON(doc2, json) { 5357 if (typeof json.anchor != "number") 5358 throw new RangeError("Invalid input for NodeSelection.fromJSON"); 5359 return new NodeSelection(doc2.resolve(json.anchor)); 5360 } 5361 /** 5362 Create a node selection from non-resolved positions. 5363 */ 5364 static create(doc2, from2) { 5365 return new NodeSelection(doc2.resolve(from2)); 5366 } 5367 /** 5368 Determines whether the given node may be selected as a node 5369 selection. 5370 */ 5371 static isSelectable(node) { 5372 return !node.isText && node.type.spec.selectable !== false; 5373 } 5374} 5375NodeSelection.prototype.visible = false; 5376Selection.jsonID("node", NodeSelection); 5377class NodeBookmark { 5378 constructor(anchor) { 5379 this.anchor = anchor; 5380 } 5381 map(mapping) { 5382 let { deleted, pos } = mapping.mapResult(this.anchor); 5383 return deleted ? new TextBookmark(pos, pos) : new NodeBookmark(pos); 5384 } 5385 resolve(doc2) { 5386 let $pos = doc2.resolve(this.anchor), node = $pos.nodeAfter; 5387 if (node && NodeSelection.isSelectable(node)) 5388 return new NodeSelection($pos); 5389 return Selection.near($pos); 5390 } 5391} 5392class AllSelection extends Selection { 5393 /** 5394 Create an all-selection over the given document. 5395 */ 5396 constructor(doc2) { 5397 super(doc2.resolve(0), doc2.resolve(doc2.content.size)); 5398 } 5399 replace(tr2, content = Slice.empty) { 5400 if (content == Slice.empty) { 5401 tr2.delete(0, tr2.doc.content.size); 5402 let sel = Selection.atStart(tr2.doc); 5403 if (!sel.eq(tr2.selection)) 5404 tr2.setSelection(sel); 5405 } else { 5406 super.replace(tr2, content); 5407 } 5408 } 5409 toJSON() { 5410 return { type: "all" }; 5411 } 5412 /** 5413 @internal 5414 */ 5415 static fromJSON(doc2) { 5416 return new AllSelection(doc2); 5417 } 5418 map(doc2) { 5419 return new AllSelection(doc2); 5420 } 5421 eq(other) { 5422 return other instanceof AllSelection; 5423 } 5424 getBookmark() { 5425 return AllBookmark; 5426 } 5427} 5428Selection.jsonID("all", AllSelection); 5429const AllBookmark = { 5430 map() { 5431 return this; 5432 }, 5433 resolve(doc2) { 5434 return new AllSelection(doc2); 5435 } 5436}; 5437function findSelectionIn(doc2, node, pos, index, dir, text = false) { 5438 if (node.inlineContent) 5439 return TextSelection.create(doc2, pos); 5440 for (let i = index - (dir > 0 ? 0 : 1); dir > 0 ? i < node.childCount : i >= 0; i += dir) { 5441 let child = node.child(i); 5442 if (!child.isAtom) { 5443 let inner = findSelectionIn(doc2, child, pos + dir, dir < 0 ? child.childCount : 0, dir, text); 5444 if (inner) 5445 return inner; 5446 } else if (!text && NodeSelection.isSelectable(child)) { 5447 return NodeSelection.create(doc2, pos - (dir < 0 ? child.nodeSize : 0)); 5448 } 5449 pos += child.nodeSize * dir; 5450 } 5451 return null; 5452} 5453function selectionToInsertionEnd$1(tr2, startLen, bias) { 5454 let last = tr2.steps.length - 1; 5455 if (last < startLen) 5456 return; 5457 let step = tr2.steps[last]; 5458 if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) 5459 return; 5460 let map2 = tr2.mapping.maps[last], end2; 5461 map2.forEach((_from, _to, _newFrom, newTo) => { 5462 if (end2 == null) 5463 end2 = newTo; 5464 }); 5465 tr2.setSelection(Selection.near(tr2.doc.resolve(end2), bias)); 5466} 5467const UPDATED_SEL = 1, UPDATED_MARKS = 2, UPDATED_SCROLL = 4; 5468class Transaction extends Transform { 5469 /** 5470 @internal 5471 */ 5472 constructor(state) { 5473 super(state.doc); 5474 this.curSelectionFor = 0; 5475 this.updated = 0; 5476 this.meta = /* @__PURE__ */ Object.create(null); 5477 this.time = Date.now(); 5478 this.curSelection = state.selection; 5479 this.storedMarks = state.storedMarks; 5480 } 5481 /** 5482 The transaction's current selection. This defaults to the editor 5483 selection [mapped](https://prosemirror.net/docs/ref/#state.Selection.map) through the steps in the 5484 transaction, but can be overwritten with 5485 [`setSelection`](https://prosemirror.net/docs/ref/#state.Transaction.setSelection). 5486 */ 5487 get selection() { 5488 if (this.curSelectionFor < this.steps.length) { 5489 this.curSelection = this.curSelection.map(this.doc, this.mapping.slice(this.curSelectionFor)); 5490 this.curSelectionFor = this.steps.length; 5491 } 5492 return this.curSelection; 5493 } 5494 /** 5495 Update the transaction's current selection. Will determine the 5496 selection that the editor gets when the transaction is applied. 5497 */ 5498 setSelection(selection) { 5499 if (selection.$from.doc != this.doc) 5500 throw new RangeError("Selection passed to setSelection must point at the current document"); 5501 this.curSelection = selection; 5502 this.curSelectionFor = this.steps.length; 5503 this.updated = (this.updated | UPDATED_SEL) & ~UPDATED_MARKS; 5504 this.storedMarks = null; 5505 return this; 5506 } 5507 /** 5508 Whether the selection was explicitly updated by this transaction. 5509 */ 5510 get selectionSet() { 5511 return (this.updated & UPDATED_SEL) > 0; 5512 } 5513 /** 5514 Set the current stored marks. 5515 */ 5516 setStoredMarks(marks) { 5517 this.storedMarks = marks; 5518 this.updated |= UPDATED_MARKS; 5519 return this; 5520 } 5521 /** 5522 Make sure the current stored marks or, if that is null, the marks 5523 at the selection, match the given set of marks. Does nothing if 5524 this is already the case. 5525 */ 5526 ensureMarks(marks) { 5527 if (!Mark$1.sameSet(this.storedMarks || this.selection.$from.marks(), marks)) 5528 this.setStoredMarks(marks); 5529 return this; 5530 } 5531 /** 5532 Add a mark to the set of stored marks. 5533 */ 5534 addStoredMark(mark) { 5535 return this.ensureMarks(mark.addToSet(this.storedMarks || this.selection.$head.marks())); 5536 } 5537 /** 5538 Remove a mark or mark type from the set of stored marks. 5539 */ 5540 removeStoredMark(mark) { 5541 return this.ensureMarks(mark.removeFromSet(this.storedMarks || this.selection.$head.marks())); 5542 } 5543 /** 5544 Whether the stored marks were explicitly set for this transaction. 5545 */ 5546 get storedMarksSet() { 5547 return (this.updated & UPDATED_MARKS) > 0; 5548 } 5549 /** 5550 @internal 5551 */ 5552 addStep(step, doc2) { 5553 super.addStep(step, doc2); 5554 this.updated = this.updated & ~UPDATED_MARKS; 5555 this.storedMarks = null; 5556 } 5557 /** 5558 Update the timestamp for the transaction. 5559 */ 5560 setTime(time) { 5561 this.time = time; 5562 return this; 5563 } 5564 /** 5565 Replace the current selection with the given slice. 5566 */ 5567 replaceSelection(slice2) { 5568 this.selection.replace(this, slice2); 5569 return this; 5570 } 5571 /** 5572 Replace the selection with the given node. When `inheritMarks` is 5573 true and the content is inline, it inherits the marks from the 5574 place where it is inserted. 5575 */ 5576 replaceSelectionWith(node, inheritMarks = true) { 5577 let selection = this.selection; 5578 if (inheritMarks) 5579 node = node.mark(this.storedMarks || (selection.empty ? selection.$from.marks() : selection.$from.marksAcross(selection.$to) || Mark$1.none)); 5580 selection.replaceWith(this, node); 5581 return this; 5582 } 5583 /** 5584 Delete the selection. 5585 */ 5586 deleteSelection() { 5587 this.selection.replace(this); 5588 return this; 5589 } 5590 /** 5591 Replace the given range, or the selection if no range is given, 5592 with a text node containing the given string. 5593 */ 5594 insertText(text, from2, to) { 5595 let schema = this.doc.type.schema; 5596 if (from2 == null) { 5597 if (!text) 5598 return this.deleteSelection(); 5599 return this.replaceSelectionWith(schema.text(text), true); 5600 } else { 5601 if (to == null) 5602 to = from2;
vendor: 4,359 bytes, lines 5603-5765
5603 to = to == null ? from2 : to; 5604 if (!text) 5605 return this.deleteRange(from2, to); 5606 let marks = this.storedMarks; 5607 if (!marks) { 5608 let $from = this.doc.resolve(from2); 5609 marks = to == from2 ? $from.marks() : $from.marksAcross(this.doc.resolve(to)); 5610 } 5611 this.replaceRangeWith(from2, to, schema.text(text, marks)); 5612 if (!this.selection.empty) 5613 this.setSelection(Selection.near(this.selection.$to)); 5614 return this; 5615 } 5616 } 5617 /** 5618 Store a metadata property in this transaction, keyed either by 5619 name or by plugin. 5620 */ 5621 setMeta(key, value) { 5622 this.meta[typeof key == "string" ? key : key.key] = value; 5623 return this; 5624 } 5625 /** 5626 Retrieve a metadata property for a given name or plugin. 5627 */ 5628 getMeta(key) { 5629 return this.meta[typeof key == "string" ? key : key.key]; 5630 } 5631 /** 5632 Returns true if this transaction doesn't contain any metadata, 5633 and can thus safely be extended. 5634 */ 5635 get isGeneric() { 5636 for (let _ in this.meta) 5637 return false; 5638 return true; 5639 } 5640 /** 5641 Indicate that the editor should scroll the selection into view 5642 when updated to the state produced by this transaction. 5643 */ 5644 scrollIntoView() { 5645 this.updated |= UPDATED_SCROLL; 5646 return this; 5647 } 5648 /** 5649 True when this transaction has had `scrollIntoView` called on it. 5650 */ 5651 get scrolledIntoView() { 5652 return (this.updated & UPDATED_SCROLL) > 0; 5653 } 5654} 5655function bind(f, self) { 5656 return !self || !f ? f : f.bind(self); 5657} 5658class FieldDesc { 5659 constructor(name, desc, self) { 5660 this.name = name; 5661 this.init = bind(desc.init, self); 5662 this.apply = bind(desc.apply, self); 5663 } 5664} 5665const baseFields = [ 5666 new FieldDesc("doc", { 5667 init(config) { 5668 return config.doc || config.schema.topNodeType.createAndFill(); 5669 }, 5670 apply(tr2) { 5671 return tr2.doc; 5672 } 5673 }), 5674 new FieldDesc("selection", { 5675 init(config, instance) { 5676 return config.selection || Selection.atStart(instance.doc); 5677 }, 5678 apply(tr2) { 5679 return tr2.selection; 5680 } 5681 }), 5682 new FieldDesc("storedMarks", { 5683 init(config) { 5684 return config.storedMarks || null; 5685 }, 5686 apply(tr2, _marks, _old, state) { 5687 return state.selection.$cursor ? tr2.storedMarks : null; 5688 } 5689 }), 5690 new FieldDesc("scrollToSelection", { 5691 init() { 5692 return 0; 5693 }, 5694 apply(tr2, prev) { 5695 return tr2.scrolledIntoView ? prev + 1 : prev; 5696 } 5697 }) 5698]; 5699class Configuration { 5700 constructor(schema, plugins) { 5701 this.schema = schema; 5702 this.plugins = []; 5703 this.pluginsByKey = /* @__PURE__ */ Object.create(null); 5704 this.fields = baseFields.slice(); 5705 if (plugins) 5706 plugins.forEach((plugin) => { 5707 if (this.pluginsByKey[plugin.key]) 5708 throw new RangeError("Adding different instances of a keyed plugin (" + plugin.key + ")"); 5709 this.plugins.push(plugin); 5710 this.pluginsByKey[plugin.key] = plugin; 5711 if (plugin.spec.state) 5712 this.fields.push(new FieldDesc(plugin.key, plugin.spec.state, plugin)); 5713 }); 5714 } 5715} 5716class EditorState { 5717 /** 5718 @internal 5719 */ 5720 constructor(config) { 5721 this.config = config; 5722 } 5723 /** 5724 The schema of the state's document. 5725 */ 5726 get schema() { 5727 return this.config.schema; 5728 } 5729 /** 5730 The plugins that are active in this state. 5731 */ 5732 get plugins() { 5733 return this.config.plugins; 5734 } 5735 /** 5736 Apply the given transaction to produce a new state. 5737 */ 5738 apply(tr2) { 5739 return this.applyTransaction(tr2).state; 5740 } 5741 /** 5742 @internal 5743 */ 5744 filterTransaction(tr2, ignore = -1) { 5745 for (let i = 0; i < this.config.plugins.length; i++) 5746 if (i != ignore) { 5747 let plugin = this.config.plugins[i]; 5748 if (plugin.spec.filterTransaction && !plugin.spec.filterTransaction.call(plugin, tr2, this)) 5749 return false; 5750 } 5751 return true; 5752 } 5753 /** 5754 Verbose variant of [`apply`](https://prosemirror.net/docs/ref/#state.EditorState.apply) that 5755 returns the precise transactions that were applied (which might 5756 be influenced by the [transaction 5757 hooks](https://prosemirror.net/docs/ref/#state.PluginSpec.filterTransaction) of 5758 plugins) along with the new state. 5759 */ 5760 applyTransaction(rootTr) { 5761 if (!this.filterTransaction(rootTr)) 5762 return { state: this, transactions: [] }; 5763 let trs = [rootTr], newState = this.applyInner(rootTr), seen = null; 5764 for (; ; ) { 5765 let haveNew = false;
vendor: 4,394 bytes, lines 5766-5872
5766 for (let i = 0; i < this.config.plugins.length; i++) { 5767 let plugin = this.config.plugins[i]; 5768 if (plugin.spec.appendTransaction) { 5769 let n = seen ? seen[i].n : 0, oldState = seen ? seen[i].state : this; 5770 let tr2 = n < trs.length && plugin.spec.appendTransaction.call(plugin, n ? trs.slice(n) : trs, oldState, newState); 5771 if (tr2 && newState.filterTransaction(tr2, i)) { 5772 tr2.setMeta("appendedTransaction", rootTr); 5773 if (!seen) { 5774 seen = []; 5775 for (let j = 0; j < this.config.plugins.length; j++) 5776 seen.push(j < i ? { state: newState, n: trs.length } : { state: this, n: 0 }); 5777 } 5778 trs.push(tr2); 5779 newState = newState.applyInner(tr2); 5780 haveNew = true; 5781 } 5782 if (seen) 5783 seen[i] = { state: newState, n: trs.length }; 5784 } 5785 } 5786 if (!haveNew) 5787 return { state: newState, transactions: trs }; 5788 } 5789 } 5790 /** 5791 @internal 5792 */ 5793 applyInner(tr2) { 5794 if (!tr2.before.eq(this.doc)) 5795 throw new RangeError("Applying a mismatched transaction"); 5796 let newInstance = new EditorState(this.config), fields = this.config.fields; 5797 for (let i = 0; i < fields.length; i++) { 5798 let field = fields[i]; 5799 newInstance[field.name] = field.apply(tr2, this[field.name], this, newInstance); 5800 } 5801 return newInstance; 5802 } 5803 /** 5804 Start a [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state. 5805 */ 5806 get tr() { 5807 return new Transaction(this); 5808 } 5809 /** 5810 Create a new state. 5811 */ 5812 static create(config) { 5813 let $config = new Configuration(config.doc ? config.doc.type.schema : config.schema, config.plugins); 5814 let instance = new EditorState($config); 5815 for (let i = 0; i < $config.fields.length; i++) 5816 instance[$config.fields[i].name] = $config.fields[i].init(config, instance); 5817 return instance; 5818 } 5819 /** 5820 Create a new state based on this one, but with an adjusted set 5821 of active plugins. State fields that exist in both sets of 5822 plugins are kept unchanged. Those that no longer exist are 5823 dropped, and those that are new are initialized using their 5824 [`init`](https://prosemirror.net/docs/ref/#state.StateField.init) method, passing in the new 5825 configuration object.. 5826 */ 5827 reconfigure(config) { 5828 let $config = new Configuration(this.schema, config.plugins); 5829 let fields = $config.fields, instance = new EditorState($config); 5830 for (let i = 0; i < fields.length; i++) { 5831 let name = fields[i].name; 5832 instance[name] = this.hasOwnProperty(name) ? this[name] : fields[i].init(config, instance); 5833 } 5834 return instance; 5835 } 5836 /** 5837 Serialize this state to JSON. If you want to serialize the state 5838 of plugins, pass an object mapping property names to use in the 5839 resulting JSON object to plugin objects. The argument may also be 5840 a string or number, in which case it is ignored, to support the 5841 way `JSON.stringify` calls `toString` methods. 5842 */ 5843 toJSON(pluginFields) { 5844 let result = { doc: this.doc.toJSON(), selection: this.selection.toJSON() }; 5845 if (this.storedMarks) 5846 result.storedMarks = this.storedMarks.map((m) => m.toJSON()); 5847 if (pluginFields && typeof pluginFields == "object") 5848 for (let prop in pluginFields) { 5849 if (prop == "doc" || prop == "selection") 5850 throw new RangeError("The JSON fields `doc` and `selection` are reserved"); 5851 let plugin = pluginFields[prop], state = plugin.spec.state; 5852 if (state && state.toJSON) 5853 result[prop] = state.toJSON.call(plugin, this[plugin.key]); 5854 } 5855 return result; 5856 } 5857 /** 5858 Deserialize a JSON representation of a state. `config` should 5859 have at least a `schema` field, and should contain array of 5860 plugins to initialize the state with. `pluginFields` can be used 5861 to deserialize the state of plugins, by associating plugin 5862 instances with the property names they use in the JSON object. 5863 */ 5864 static fromJSON(config, json, pluginFields) { 5865 if (!json) 5866 throw new RangeError("Invalid input for EditorState.fromJSON"); 5867 if (!config.schema) 5868 throw new RangeError("Required config field 'schema' missing"); 5869 let $config = new Configuration(config.schema, config.plugins); 5870 let instance = new EditorState($config); 5871 $config.fields.forEach((field) => { 5872 if (field.name == "doc") {
vendor: 4,980 bytes, lines 5873-6040
5873 instance.doc = Node$1.fromJSON(config.schema, json.doc); 5874 } else if (field.name == "selection") { 5875 instance.selection = Selection.fromJSON(instance.doc, json.selection); 5876 } else if (field.name == "storedMarks") { 5877 if (json.storedMarks) 5878 instance.storedMarks = json.storedMarks.map(config.schema.markFromJSON); 5879 } else { 5880 if (pluginFields) 5881 for (let prop in pluginFields) { 5882 let plugin = pluginFields[prop], state = plugin.spec.state; 5883 if (plugin.key == field.name && state && state.fromJSON && Object.prototype.hasOwnProperty.call(json, prop)) { 5884 instance[field.name] = state.fromJSON.call(plugin, config, json[prop], instance); 5885 return; 5886 } 5887 } 5888 instance[field.name] = field.init(config, instance); 5889 } 5890 }); 5891 return instance; 5892 } 5893} 5894function bindProps(obj, self, target) { 5895 for (let prop in obj) { 5896 let val = obj[prop]; 5897 if (val instanceof Function) 5898 val = val.bind(self); 5899 else if (prop == "handleDOMEvents") 5900 val = bindProps(val, self, {}); 5901 target[prop] = val; 5902 } 5903 return target; 5904} 5905class Plugin { 5906 /** 5907 Create a plugin. 5908 */ 5909 constructor(spec) { 5910 this.spec = spec; 5911 this.props = {}; 5912 if (spec.props) 5913 bindProps(spec.props, this, this.props); 5914 this.key = spec.key ? spec.key.key : createKey("plugin"); 5915 } 5916 /** 5917 Extract the plugin's state field from an editor state. 5918 */ 5919 getState(state) { 5920 return state[this.key]; 5921 } 5922} 5923const keys = /* @__PURE__ */ Object.create(null); 5924function createKey(name) { 5925 if (name in keys) 5926 return name + "$" + ++keys[name]; 5927 keys[name] = 0; 5928 return name + "$"; 5929} 5930class PluginKey { 5931 /** 5932 Create a plugin key. 5933 */ 5934 constructor(name = "key") { 5935 this.key = createKey(name); 5936 } 5937 /** 5938 Get the active plugin with this key, if any, from an editor 5939 state. 5940 */ 5941 get(state) { 5942 return state.config.pluginsByKey[this.key]; 5943 } 5944 /** 5945 Get the plugin's state from an editor state. 5946 */ 5947 getState(state) { 5948 return state[this.key]; 5949 } 5950} 5951const domIndex = function(node) { 5952 for (var index = 0; ; index++) { 5953 node = node.previousSibling; 5954 if (!node) 5955 return index; 5956 } 5957}; 5958const parentNode = function(node) { 5959 let parent = node.assignedSlot || node.parentNode; 5960 return parent && parent.nodeType == 11 ? parent.host : parent; 5961}; 5962let reusedRange = null; 5963const textRange = function(node, from2, to) { 5964 let range = reusedRange || (reusedRange = document.createRange()); 5965 range.setEnd(node, to == null ? node.nodeValue.length : to); 5966 range.setStart(node, from2 || 0); 5967 return range; 5968}; 5969const clearReusedRange = function() { 5970 reusedRange = null; 5971}; 5972const isEquivalentPosition = function(node, off, targetNode, targetOff) { 5973 return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || scanFor(node, off, targetNode, targetOff, 1)); 5974}; 5975const atomElements = /^(img|br|input|textarea|hr)$/i; 5976function scanFor(node, off, targetNode, targetOff, dir) { 5977 for (; ; ) { 5978 if (node == targetNode && off == targetOff) 5979 return true; 5980 if (off == (dir < 0 ? 0 : nodeSize(node))) { 5981 let parent = node.parentNode; 5982 if (!parent || parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") 5983 return false; 5984 off = domIndex(node) + (dir < 0 ? 0 : 1); 5985 node = parent; 5986 } else if (node.nodeType == 1) { 5987 node = node.childNodes[off + (dir < 0 ? -1 : 0)]; 5988 if (node.contentEditable == "false") 5989 return false; 5990 off = dir < 0 ? nodeSize(node) : 0; 5991 } else { 5992 return false; 5993 } 5994 } 5995} 5996function nodeSize(node) { 5997 return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; 5998} 5999function textNodeBefore$1(node, offset2) { 6000 for (; ; ) { 6001 if (node.nodeType == 3 && offset2) 6002 return node; 6003 if (node.nodeType == 1 && offset2 > 0) { 6004 if (node.contentEditable == "false") 6005 return null; 6006 node = node.childNodes[offset2 - 1]; 6007 offset2 = nodeSize(node); 6008 } else if (node.parentNode && !hasBlockDesc(node)) { 6009 offset2 = domIndex(node); 6010 node = node.parentNode; 6011 } else { 6012 return null; 6013 } 6014 } 6015} 6016function textNodeAfter$1(node, offset2) { 6017 for (; ; ) { 6018 if (node.nodeType == 3 && offset2 < node.nodeValue.length) 6019 return node; 6020 if (node.nodeType == 1 && offset2 < node.childNodes.length) { 6021 if (node.contentEditable == "false") 6022 return null; 6023 node = node.childNodes[offset2]; 6024 offset2 = 0; 6025 } else if (node.parentNode && !hasBlockDesc(node)) { 6026 offset2 = domIndex(node) + 1; 6027 node = node.parentNode; 6028 } else { 6029 return null; 6030 } 6031 } 6032} 6033function isOnEdge(node, offset2, parent) { 6034 for (let atStart = offset2 == 0, atEnd = offset2 == nodeSize(node); atStart || atEnd; ) { 6035 if (node == parent) 6036 return true; 6037 let index = domIndex(node); 6038 node = node.parentNode; 6039 if (!node) 6040 return false;
6041 atStart = atStart && index == 0; 6042 atEnd = atEnd && index == nodeSize(node); 6043 } 6044} 6045function hasBlockDesc(dom) { 6046 let desc; 6047 for (let cur = dom; cur; cur = cur.parentNode) 6048 if (desc = cur.pmViewDesc) 6049 break; 6050 return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom); 6051} 6052const selectionCollapsed = function(domSel) { 6053 return domSel.focusNode && isEquivalentPosition(domSel.focusNode, domSel.focusOffset, domSel.anchorNode, domSel.anchorOffset); 6054}; 6055function keyEvent(keyCode, key) { 6056 let event = document.createEvent("Event"); 6057 event.initEvent("keydown", true, true); 6058 event.keyCode = keyCode; 6059 event.key = event.code = key; 6060 return event; 6061} 6062function deepActiveElement(doc2) { 6063 let elt = doc2.activeElement; 6064 while (elt && elt.shadowRoot) 6065 elt = elt.shadowRoot.activeElement; 6066 return elt; 6067} 6068function caretFromPoint(doc2, x, y) { 6069 if (doc2.caretPositionFromPoint) { 6070 try { 6071 let pos = doc2.caretPositionFromPoint(x, y); 6072 if (pos) 6073 return { node: pos.offsetNode, offset: pos.offset }; 6074 } catch (_) { 6075 } 6076 } 6077 if (doc2.caretRangeFromPoint) { 6078 let range = doc2.caretRangeFromPoint(x, y); 6079 if (range) 6080 return { node: range.startContainer, offset: range.startOffset }; 6081 } 6082} 6083const nav = typeof navigator != "undefined" ? navigator : null; 6084const doc = typeof document != "undefined" ? document : null; 6085const agent = nav && nav.userAgent || ""; 6086const ie_edge = /Edge\/(\d+)/.exec(agent); 6087const ie_upto10 = /MSIE \d/.exec(agent); 6088const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent); 6089const ie$1 = !!(ie_upto10 || ie_11up || ie_edge); 6090const ie_version = ie_upto10 ? document.documentMode : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0; 6091const gecko = !ie$1 && /gecko\/(\d+)/i.test(agent); 6092gecko && +(/Firefox\/(\d+)/.exec(agent) || [0, 0])[1]; 6093const _chrome = !ie$1 && /Chrome\/(\d+)/.exec(agent); 6094const chrome = !!_chrome; 6095const chrome_version = _chrome ? +_chrome[1] : 0; 6096const safari = !ie$1 && !!nav && /Apple Computer/.test(nav.vendor); 6097const ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2); 6098const mac$2 = ios || (nav ? /Mac/.test(nav.platform) : false); 6099const windows = nav ? /Win/.test(nav.platform) : false; 6100const android = /Android \d/.test(agent); 6101const webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style; 6102const webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0; 6103function windowRect(doc2) { 6104 let vp = doc2.defaultView && doc2.defaultView.visualViewport; 6105 if (vp) 6106 return { 6107 left: 0, 6108 right: vp.width, 6109 top: 0, 6110 bottom: vp.height 6111 }; 6112 return { 6113 left: 0, 6114 right: doc2.documentElement.clientWidth, 6115 top: 0, 6116 bottom: doc2.documentElement.clientHeight 6117 }; 6118} 6119function getSide(value, side) { 6120 return typeof value == "number" ? value : value[side]; 6121} 6122function clientRect(node) { 6123 let rect = node.getBoundingClientRect(); 6124 let scaleX = rect.width / node.offsetWidth || 1; 6125 let scaleY = rect.height / node.offsetHeight || 1; 6126 return { 6127 left: rect.left, 6128 right: rect.left + node.clientWidth * scaleX, 6129 top: rect.top, 6130 bottom: rect.top + node.clientHeight * scaleY 6131 }; 6132} 6133function scrollRectIntoView(view, rect, startDOM) { 6134 let scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5; 6135 let doc2 = view.dom.ownerDocument; 6136 for (let parent = startDOM || view.dom; ; parent = parentNode(parent)) { 6137 if (!parent) 6138 break; 6139 if (parent.nodeType != 1) 6140 continue; 6141 let elt = parent; 6142 let atTop = elt == doc2.body; 6143 let bounding = atTop ? windowRect(doc2) : clientRect(elt); 6144 let moveX = 0, moveY = 0; 6145 if (rect.top < bounding.top + getSide(scrollThreshold, "top")) 6146 moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top")); 6147 else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) 6148 moveY = rect.bottom - rect.top > bounding.bottom - bounding.top ? rect.top + getSide(scrollMargin, "top") - bounding.top : rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom"); 6149 if (rect.left < bounding.left + getSide(scrollThreshold, "left")) 6150 moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left")); 6151 else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) 6152 moveX = rect.right - bounding.right + getSide(scrollMargin, "right"); 6153 if (moveX || moveY) { 6154 if (atTop) { 6155 doc2.defaultView.scrollBy(moveX, moveY); 6156 } else { 6157 let startX = elt.scrollLeft, startY = elt.scrollTop; 6158 if (moveY) 6159 elt.scrollTop += moveY; 6160 if (moveX) 6161 elt.scrollLeft += moveX; 6162 let dX = elt.scrollLeft - startX, dY = elt.scrollTop - startY; 6163 rect = { left: rect.left - dX, top: rect.top - dY, right: rect.right - dX, bottom: rect.bottom - dY }; 6164 } 6165 } 6166 if (atTop || /^(fixed|sticky)$/.test(getComputedStyle(parent).position)) 6167 break; 6168 } 6169} 6170function storeScrollPos(view) { 6171 let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top); 6172 let refDOM, refTop; 6173 for (let x = (rect.left + rect.right) / 2, y = startY + 1; y < Math.min(innerHeight, rect.bottom); y += 5) { 6174 let dom = view.root.elementFromPoint(x, y); 6175 if (!dom || dom == view.dom || !view.dom.contains(dom)) 6176 continue; 6177 let localRect = dom.getBoundingClientRect(); 6178 if (localRect.top >= startY - 20) { 6179 refDOM = dom; 6180 refTop = localRect.top; 6181 break; 6182 } 6183 } 6184 return { refDOM, refTop, stack: scrollStack(view.dom) }; 6185} 6186function scrollStack(dom) { 6187 let stack = [], doc2 = dom.ownerDocument; 6188 for (let cur = dom; cur; cur = parentNode(cur)) { 6189 stack.push({ dom: cur, top: cur.scrollTop, left: cur.scrollLeft }); 6190 if (dom == doc2) 6191 break; 6192 } 6193 return stack; 6194} 6195function resetScrollPos({ refDOM, refTop, stack }) { 6196 let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0; 6197 restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop); 6198} 6199function restoreScrollStack(stack, dTop) { 6200 for (let i = 0; i < stack.length; i++) { 6201 let { dom, top: top2, left: left2 } = stack[i]; 6202 if (dom.scrollTop != top2 + dTop) 6203 dom.scrollTop = top2 + dTop; 6204 if (dom.scrollLeft != left2) 6205 dom.scrollLeft = left2; 6206 } 6207} 6208let preventScrollSupported = null; 6209function focusPreventScroll(dom) { 6210 if (dom.setActive) 6211 return dom.setActive(); 6212 if (preventScrollSupported) 6213 return dom.focus(preventScrollSupported); 6214 let stored = scrollStack(dom); 6215 dom.focus(preventScrollSupported == null ? { 6216 get preventScroll() { 6217 preventScrollSupported = { preventScroll: true }; 6218 return true; 6219 } 6220 } : void 0); 6221 if (!preventScrollSupported) { 6222 preventScrollSupported = false;
6223 restoreScrollStack(stored, 0); 6224 } 6225} 6226function findOffsetInNode(node, coords) { 6227 let closest, dxClosest = 2e8, coordsClosest, offset2 = 0; 6228 let rowBot = coords.top, rowTop = coords.top; 6229 let firstBelow, coordsBelow; 6230 for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) { 6231 let rects; 6232 if (child.nodeType == 1) 6233 rects = child.getClientRects(); 6234 else if (child.nodeType == 3) 6235 rects = textRange(child).getClientRects(); 6236 else 6237 continue; 6238 for (let i = 0; i < rects.length; i++) { 6239 let rect = rects[i]; 6240 if (rect.top <= rowBot && rect.bottom >= rowTop) { 6241 rowBot = Math.max(rect.bottom, rowBot); 6242 rowTop = Math.min(rect.top, rowTop); 6243 let dx = rect.left > coords.left ? rect.left - coords.left : rect.right < coords.left ? coords.left - rect.right : 0; 6244 if (dx < dxClosest) { 6245 closest = child; 6246 dxClosest = dx; 6247 coordsClosest = dx && closest.nodeType == 3 ? { 6248 left: rect.right < coords.left ? rect.right : rect.left, 6249 top: coords.top 6250 } : coords; 6251 if (child.nodeType == 1 && dx) 6252 offset2 = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0); 6253 continue; 6254 } 6255 } else if (rect.top > coords.top && !firstBelow && rect.left <= coords.left && rect.right >= coords.left) { 6256 firstBelow = child; 6257 coordsBelow = { left: Math.max(rect.left, Math.min(rect.right, coords.left)), top: rect.top }; 6258 } 6259 if (!closest && (coords.left >= rect.right && coords.top >= rect.top || coords.left >= rect.left && coords.top >= rect.bottom)) 6260 offset2 = childIndex + 1; 6261 } 6262 } 6263 if (!closest && firstBelow) { 6264 closest = firstBelow; 6265 coordsClosest = coordsBelow; 6266 dxClosest = 0; 6267 } 6268 if (closest && closest.nodeType == 3) 6269 return findOffsetInText(closest, coordsClosest); 6270 if (!closest || dxClosest && closest.nodeType == 1) 6271 return { node, offset: offset2 }; 6272 return findOffsetInNode(closest, coordsClosest); 6273} 6274function findOffsetInText(node, coords) { 6275 let len = node.nodeValue.length; 6276 let range = document.createRange(); 6277 for (let i = 0; i < len; i++) { 6278 range.setEnd(node, i + 1); 6279 range.setStart(node, i); 6280 let rect = singleRect(range, 1); 6281 if (rect.top == rect.bottom) 6282 continue; 6283 if (inRect(coords, rect)) 6284 return { node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) }; 6285 } 6286 return { node, offset: 0 }; 6287} 6288function inRect(coords, rect) { 6289 return coords.left >= rect.left - 1 && coords.left <= rect.right + 1 && coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1; 6290} 6291function targetKludge(dom, coords) { 6292 let parent = dom.parentNode; 6293 if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) 6294 return parent; 6295 return dom; 6296} 6297function posFromElement(view, elt, coords) { 6298 let { node, offset: offset2 } = findOffsetInNode(elt, coords), bias = -1; 6299 if (node.nodeType == 1 && !node.firstChild) { 6300 let rect = node.getBoundingClientRect(); 6301 bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1; 6302 } 6303 return view.docView.posFromDOM(node, offset2, bias); 6304} 6305function posFromCaret(view, node, offset2, coords) { 6306 let outsideBlock = -1; 6307 for (let cur = node, sawBlock = false; ; ) { 6308 if (cur == view.dom) 6309 break; 6310 let desc = view.docView.nearestDesc(cur, true); 6311 if (!desc) 6312 return null; 6313 if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent && !sawBlock || !desc.contentDOM)) { 6314 let rect = desc.dom.getBoundingClientRect(); 6315 if (desc.node.isBlock && desc.parent && !sawBlock) { 6316 sawBlock = true; 6317 if (rect.left > coords.left || rect.top > coords.top) 6318 outsideBlock = desc.posBefore; 6319 else if (rect.right < coords.left || rect.bottom < coords.top) 6320 outsideBlock = desc.posAfter; 6321 } 6322 if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) { 6323 let before = desc.node.isBlock ? coords.top < (rect.top + rect.bottom) / 2 : coords.left < (rect.left + rect.right) / 2; 6324 return before ? desc.posBefore : desc.posAfter; 6325 } 6326 } 6327 cur = desc.dom.parentNode; 6328 } 6329 return outsideBlock > -1 ? outsideBlock : view.docView.posFromDOM(node, offset2, -1); 6330} 6331function elementFromPoint(element, coords, box) { 6332 let len = element.childNodes.length; 6333 if (len && box.top < box.bottom) { 6334 for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI; ; ) { 6335 let child = element.childNodes[i]; 6336 if (child.nodeType == 1) { 6337 let rects = child.getClientRects(); 6338 for (let j = 0; j < rects.length; j++) { 6339 let rect = rects[j]; 6340 if (inRect(coords, rect))
vendor: 8,519 bytes, lines 6341-6556
6341 return elementFromPoint(child, coords, rect); 6342 } 6343 } 6344 if ((i = (i + 1) % len) == startI) 6345 break; 6346 } 6347 } 6348 return element; 6349} 6350function posAtCoords(view, coords) { 6351 let doc2 = view.dom.ownerDocument, node, offset2 = 0; 6352 let caret = caretFromPoint(doc2, coords.left, coords.top); 6353 if (caret) 6354 ({ node, offset: offset2 } = caret); 6355 let elt = (view.root.elementFromPoint ? view.root : doc2).elementFromPoint(coords.left, coords.top); 6356 let pos; 6357 if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) { 6358 let box = view.dom.getBoundingClientRect(); 6359 if (!inRect(coords, box)) 6360 return null; 6361 elt = elementFromPoint(view.dom, coords, box); 6362 if (!elt) 6363 return null; 6364 } 6365 if (safari) { 6366 for (let p = elt; node && p; p = parentNode(p)) 6367 if (p.draggable) 6368 node = void 0; 6369 } 6370 elt = targetKludge(elt, coords); 6371 if (node) { 6372 if (gecko && node.nodeType == 1) { 6373 offset2 = Math.min(offset2, node.childNodes.length); 6374 if (offset2 < node.childNodes.length) { 6375 let next = node.childNodes[offset2], box; 6376 if (next.nodeName == "IMG" && (box = next.getBoundingClientRect()).right <= coords.left && box.bottom > coords.top) 6377 offset2++; 6378 } 6379 } 6380 let prev; 6381 if (webkit && offset2 && node.nodeType == 1 && (prev = node.childNodes[offset2 - 1]).nodeType == 1 && prev.contentEditable == "false" && prev.getBoundingClientRect().top >= coords.top) 6382 offset2--; 6383 if (node == view.dom && offset2 == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && coords.top > node.lastChild.getBoundingClientRect().bottom) 6384 pos = view.state.doc.content.size; 6385 else if (offset2 == 0 || node.nodeType != 1 || node.childNodes[offset2 - 1].nodeName != "BR") 6386 pos = posFromCaret(view, node, offset2, coords); 6387 } 6388 if (pos == null) 6389 pos = posFromElement(view, elt, coords); 6390 let desc = view.docView.nearestDesc(elt, true); 6391 return { pos, inside: desc ? desc.posAtStart - desc.border : -1 }; 6392} 6393function nonZero(rect) { 6394 return rect.top < rect.bottom || rect.left < rect.right; 6395} 6396function singleRect(target, bias) { 6397 let rects = target.getClientRects(); 6398 if (rects.length) { 6399 let first2 = rects[bias < 0 ? 0 : rects.length - 1]; 6400 if (nonZero(first2)) 6401 return first2; 6402 } 6403 return Array.prototype.find.call(rects, nonZero) || target.getBoundingClientRect(); 6404} 6405const BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; 6406function coordsAtPos(view, pos, side) { 6407 let { node, offset: offset2, atom } = view.docView.domFromPos(pos, side < 0 ? -1 : 1); 6408 let supportEmptyRange = webkit || gecko; 6409 if (node.nodeType == 3) { 6410 if (supportEmptyRange && (BIDI.test(node.nodeValue) || (side < 0 ? !offset2 : offset2 == node.nodeValue.length))) { 6411 let rect = singleRect(textRange(node, offset2, offset2), side); 6412 if (gecko && offset2 && /\s/.test(node.nodeValue[offset2 - 1]) && offset2 < node.nodeValue.length) { 6413 let rectBefore = singleRect(textRange(node, offset2 - 1, offset2 - 1), -1); 6414 if (rectBefore.top == rect.top) { 6415 let rectAfter = singleRect(textRange(node, offset2, offset2 + 1), -1); 6416 if (rectAfter.top != rect.top) 6417 return flattenV(rectAfter, rectAfter.left < rectBefore.left); 6418 } 6419 } 6420 return rect; 6421 } else { 6422 let from2 = offset2, to = offset2, takeSide = side < 0 ? 1 : -1; 6423 if (side < 0 && !offset2) { 6424 to++; 6425 takeSide = -1; 6426 } else if (side >= 0 && offset2 == node.nodeValue.length) { 6427 from2--; 6428 takeSide = 1; 6429 } else if (side < 0) { 6430 from2--; 6431 } else { 6432 to++; 6433 } 6434 return flattenV(singleRect(textRange(node, from2, to), takeSide), takeSide < 0); 6435 } 6436 } 6437 let $dom = view.state.doc.resolve(pos - (atom || 0)); 6438 if (!$dom.parent.inlineContent) { 6439 if (atom == null && offset2 && (side < 0 || offset2 == nodeSize(node))) { 6440 let before = node.childNodes[offset2 - 1]; 6441 if (before.nodeType == 1) 6442 return flattenH(before.getBoundingClientRect(), false); 6443 } 6444 if (atom == null && offset2 < nodeSize(node)) { 6445 let after = node.childNodes[offset2]; 6446 if (after.nodeType == 1) 6447 return flattenH(after.getBoundingClientRect(), true); 6448 } 6449 return flattenH(node.getBoundingClientRect(), side >= 0); 6450 } 6451 if (atom == null && offset2 && (side < 0 || offset2 == nodeSize(node))) { 6452 let before = node.childNodes[offset2 - 1]; 6453 let target = before.nodeType == 3 ? textRange(before, nodeSize(before) - (supportEmptyRange ? 0 : 1)) : before.nodeType == 1 && (before.nodeName != "BR" || !before.nextSibling) ? before : null; 6454 if (target) 6455 return flattenV(singleRect(target, 1), false); 6456 } 6457 if (atom == null && offset2 < nodeSize(node)) { 6458 let after = node.childNodes[offset2]; 6459 while (after.pmViewDesc && after.pmViewDesc.ignoreForCoords) 6460 after = after.nextSibling; 6461 let target = !after ? null : after.nodeType == 3 ? textRange(after, 0, supportEmptyRange ? 0 : 1) : after.nodeType == 1 ? after : null; 6462 if (target) 6463 return flattenV(singleRect(target, -1), true); 6464 } 6465 return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, -side), side >= 0); 6466} 6467function flattenV(rect, left2) { 6468 if (rect.width == 0) 6469 return rect; 6470 let x = left2 ? rect.left : rect.right; 6471 return { top: rect.top, bottom: rect.bottom, left: x, right: x }; 6472} 6473function flattenH(rect, top2) { 6474 if (rect.height == 0) 6475 return rect; 6476 let y = top2 ? rect.top : rect.bottom; 6477 return { top: y, bottom: y, left: rect.left, right: rect.right }; 6478} 6479function withFlushedState(view, state, f) { 6480 let viewState = view.state, active = view.root.activeElement; 6481 if (viewState != state) 6482 view.updateState(state); 6483 if (active != view.dom) 6484 view.focus(); 6485 try { 6486 return f(); 6487 } finally { 6488 if (viewState != state) 6489 view.updateState(viewState); 6490 if (active != view.dom && active) 6491 active.focus(); 6492 } 6493} 6494function endOfTextblockVertical(view, state, dir) { 6495 let sel = state.selection; 6496 let $pos = dir == "up" ? sel.$from : sel.$to; 6497 return withFlushedState(view, state, () => { 6498 let { node: dom } = view.docView.domFromPos($pos.pos, dir == "up" ? -1 : 1); 6499 for (; ; ) { 6500 let nearest = view.docView.nearestDesc(dom, true); 6501 if (!nearest) 6502 break; 6503 if (nearest.node.isBlock) { 6504 dom = nearest.contentDOM || nearest.dom; 6505 break; 6506 } 6507 dom = nearest.dom.parentNode; 6508 } 6509 let coords = coordsAtPos(view, $pos.pos, 1); 6510 for (let child = dom.firstChild; child; child = child.nextSibling) { 6511 let boxes; 6512 if (child.nodeType == 1) 6513 boxes = child.getClientRects(); 6514 else if (child.nodeType == 3) 6515 boxes = textRange(child, 0, child.nodeValue.length).getClientRects(); 6516 else 6517 continue; 6518 for (let i = 0; i < boxes.length; i++) { 6519 let box = boxes[i]; 6520 if (box.bottom > box.top + 1 && (dir == "up" ? coords.top - box.top > (box.bottom - coords.top) * 2 : box.bottom - coords.bottom > (coords.bottom - box.top) * 2)) 6521 return false; 6522 } 6523 } 6524 return true; 6525 }); 6526} 6527const maybeRTL = /[\u0590-\u08ac]/; 6528function endOfTextblockHorizontal(view, state, dir) { 6529 let { $head } = state.selection; 6530 if (!$head.parent.isTextblock) 6531 return false; 6532 let offset2 = $head.parentOffset, atStart = !offset2, atEnd = offset2 == $head.parent.content.size; 6533 let sel = view.domSelection(); 6534 if (!maybeRTL.test($head.parent.textContent) || !sel.modify) 6535 return dir == "left" || dir == "backward" ? atStart : atEnd; 6536 return withFlushedState(view, state, () => { 6537 let { focusNode: oldNode, focusOffset: oldOff, anchorNode, anchorOffset } = view.domSelectionRange(); 6538 let oldBidiLevel = sel.caretBidiLevel; 6539 sel.modify("move", dir, "character"); 6540 let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom; 6541 let { focusNode: newNode, focusOffset: newOff } = view.domSelectionRange(); 6542 let result = newNode && !parentDOM.contains(newNode.nodeType == 1 ? newNode : newNode.parentNode) || oldNode == newNode && oldOff == newOff; 6543 try { 6544 sel.collapse(anchorNode, anchorOffset); 6545 if (oldNode && (oldNode != anchorNode || oldOff != anchorOffset) && sel.extend) 6546 sel.extend(oldNode, oldOff); 6547 } catch (_) { 6548 } 6549 if (oldBidiLevel != null) 6550 sel.caretBidiLevel = oldBidiLevel; 6551 return result; 6552 }); 6553} 6554let cachedState = null; 6555let cachedDir = null; 6556let cachedResult = false;
vendor: 4,709 bytes, lines 6557-6698
6557function endOfTextblock(view, state, dir) { 6558 if (cachedState == state && cachedDir == dir) 6559 return cachedResult; 6560 cachedState = state; 6561 cachedDir = dir; 6562 return cachedResult = dir == "up" || dir == "down" ? endOfTextblockVertical(view, state, dir) : endOfTextblockHorizontal(view, state, dir); 6563} 6564const NOT_DIRTY = 0, CHILD_DIRTY = 1, CONTENT_DIRTY = 2, NODE_DIRTY = 3; 6565class ViewDesc { 6566 constructor(parent, children, dom, contentDOM) { 6567 this.parent = parent; 6568 this.children = children; 6569 this.dom = dom; 6570 this.contentDOM = contentDOM; 6571 this.dirty = NOT_DIRTY; 6572 dom.pmViewDesc = this; 6573 } 6574 // Used to check whether a given description corresponds to a 6575 // widget/mark/node. 6576 matchesWidget(widget) { 6577 return false; 6578 } 6579 matchesMark(mark) { 6580 return false; 6581 } 6582 matchesNode(node, outerDeco, innerDeco) { 6583 return false; 6584 } 6585 matchesHack(nodeName) { 6586 return false; 6587 } 6588 // When parsing in-editor content (in domchange.js), we allow 6589 // descriptions to determine the parse rules that should be used to 6590 // parse them. 6591 parseRule() { 6592 return null; 6593 } 6594 // Used by the editor's event handler to ignore events that come 6595 // from certain descs. 6596 stopEvent(event) { 6597 return false; 6598 } 6599 // The size of the content represented by this desc. 6600 get size() { 6601 let size = 0; 6602 for (let i = 0; i < this.children.length; i++) 6603 size += this.children[i].size; 6604 return size; 6605 } 6606 // For block nodes, this represents the space taken up by their 6607 // start/end tokens. 6608 get border() { 6609 return 0; 6610 } 6611 destroy() { 6612 this.parent = void 0; 6613 if (this.dom.pmViewDesc == this) 6614 this.dom.pmViewDesc = void 0; 6615 for (let i = 0; i < this.children.length; i++) 6616 this.children[i].destroy(); 6617 } 6618 posBeforeChild(child) { 6619 for (let i = 0, pos = this.posAtStart; ; i++) { 6620 let cur = this.children[i]; 6621 if (cur == child) 6622 return pos; 6623 pos += cur.size; 6624 } 6625 } 6626 get posBefore() { 6627 return this.parent.posBeforeChild(this); 6628 } 6629 get posAtStart() { 6630 return this.parent ? this.parent.posBeforeChild(this) + this.border : 0; 6631 } 6632 get posAfter() { 6633 return this.posBefore + this.size; 6634 } 6635 get posAtEnd() { 6636 return this.posAtStart + this.size - 2 * this.border; 6637 } 6638 localPosFromDOM(dom, offset2, bias) { 6639 if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) { 6640 if (bias < 0) { 6641 let domBefore, desc; 6642 if (dom == this.contentDOM) { 6643 domBefore = dom.childNodes[offset2 - 1]; 6644 } else { 6645 while (dom.parentNode != this.contentDOM) 6646 dom = dom.parentNode; 6647 domBefore = dom.previousSibling; 6648 } 6649 while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) 6650 domBefore = domBefore.previousSibling; 6651 return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart; 6652 } else { 6653 let domAfter, desc; 6654 if (dom == this.contentDOM) { 6655 domAfter = dom.childNodes[offset2]; 6656 } else { 6657 while (dom.parentNode != this.contentDOM) 6658 dom = dom.parentNode; 6659 domAfter = dom.nextSibling; 6660 } 6661 while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) 6662 domAfter = domAfter.nextSibling; 6663 return domAfter ? this.posBeforeChild(desc) : this.posAtEnd; 6664 } 6665 } 6666 let atEnd; 6667 if (dom == this.dom && this.contentDOM) { 6668 atEnd = offset2 > domIndex(this.contentDOM); 6669 } else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) { 6670 atEnd = dom.compareDocumentPosition(this.contentDOM) & 2; 6671 } else if (this.dom.firstChild) { 6672 if (offset2 == 0) 6673 for (let search = dom; ; search = search.parentNode) { 6674 if (search == this.dom) { 6675 atEnd = false; 6676 break; 6677 } 6678 if (search.previousSibling) 6679 break; 6680 } 6681 if (atEnd == null && offset2 == dom.childNodes.length) 6682 for (let search = dom; ; search = search.parentNode) { 6683 if (search == this.dom) { 6684 atEnd = true; 6685 break; 6686 } 6687 if (search.nextSibling) 6688 break; 6689 } 6690 } 6691 return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart; 6692 } 6693 nearestDesc(dom, onlyNodes = false) { 6694 for (let first2 = true, cur = dom; cur; cur = cur.parentNode) { 6695 let desc = this.getDesc(cur), nodeDOM; 6696 if (desc && (!onlyNodes || desc.node)) { 6697 if (first2 && (nodeDOM = desc.nodeDOM) && !(nodeDOM.nodeType == 1 ? nodeDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) : nodeDOM == dom)) 6698 first2 = false;
vendor: 4,323 bytes, lines 6699-6815
6699 else 6700 return desc; 6701 } 6702 } 6703 } 6704 getDesc(dom) { 6705 let desc = dom.pmViewDesc; 6706 for (let cur = desc; cur; cur = cur.parent) 6707 if (cur == this) 6708 return desc; 6709 } 6710 posFromDOM(dom, offset2, bias) { 6711 for (let scan = dom; scan; scan = scan.parentNode) { 6712 let desc = this.getDesc(scan); 6713 if (desc) 6714 return desc.localPosFromDOM(dom, offset2, bias); 6715 } 6716 return -1; 6717 } 6718 // Find the desc for the node after the given pos, if any. (When a 6719 // parent node overrode rendering, there might not be one.) 6720 descAt(pos) { 6721 for (let i = 0, offset2 = 0; i < this.children.length; i++) { 6722 let child = this.children[i], end2 = offset2 + child.size; 6723 if (offset2 == pos && end2 != offset2) { 6724 while (!child.border && child.children.length) 6725 child = child.children[0]; 6726 return child; 6727 } 6728 if (pos < end2) 6729 return child.descAt(pos - offset2 - child.border); 6730 offset2 = end2; 6731 } 6732 } 6733 domFromPos(pos, side) { 6734 if (!this.contentDOM) 6735 return { node: this.dom, offset: 0, atom: pos + 1 }; 6736 let i = 0, offset2 = 0; 6737 for (let curPos = 0; i < this.children.length; i++) { 6738 let child = this.children[i], end2 = curPos + child.size; 6739 if (end2 > pos || child instanceof TrailingHackViewDesc) { 6740 offset2 = pos - curPos; 6741 break; 6742 } 6743 curPos = end2; 6744 } 6745 if (offset2) 6746 return this.children[i].domFromPos(offset2 - this.children[i].border, side); 6747 for (let prev; i && !(prev = this.children[i - 1]).size && prev instanceof WidgetViewDesc && prev.side >= 0; i--) { 6748 } 6749 if (side <= 0) { 6750 let prev, enter2 = true; 6751 for (; ; i--, enter2 = false) { 6752 prev = i ? this.children[i - 1] : null; 6753 if (!prev || prev.dom.parentNode == this.contentDOM) 6754 break; 6755 } 6756 if (prev && side && enter2 && !prev.border && !prev.domAtom) 6757 return prev.domFromPos(prev.size, side); 6758 return { node: this.contentDOM, offset: prev ? domIndex(prev.dom) + 1 : 0 }; 6759 } else { 6760 let next, enter2 = true; 6761 for (; ; i++, enter2 = false) { 6762 next = i < this.children.length ? this.children[i] : null; 6763 if (!next || next.dom.parentNode == this.contentDOM) 6764 break; 6765 } 6766 if (next && enter2 && !next.border && !next.domAtom) 6767 return next.domFromPos(0, side); 6768 return { node: this.contentDOM, offset: next ? domIndex(next.dom) : this.contentDOM.childNodes.length }; 6769 } 6770 } 6771 // Used to find a DOM range in a single parent for a given changed 6772 // range. 6773 parseRange(from2, to, base2 = 0) { 6774 if (this.children.length == 0) 6775 return { node: this.contentDOM, from: from2, to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length }; 6776 let fromOffset = -1, toOffset = -1; 6777 for (let offset2 = base2, i = 0; ; i++) { 6778 let child = this.children[i], end2 = offset2 + child.size; 6779 if (fromOffset == -1 && from2 <= end2) { 6780 let childBase = offset2 + child.border; 6781 if (from2 >= childBase && to <= end2 - child.border && child.node && child.contentDOM && this.contentDOM.contains(child.contentDOM)) 6782 return child.parseRange(from2, to, childBase); 6783 from2 = offset2; 6784 for (let j = i; j > 0; j--) { 6785 let prev = this.children[j - 1]; 6786 if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { 6787 fromOffset = domIndex(prev.dom) + 1; 6788 break; 6789 } 6790 from2 -= prev.size; 6791 } 6792 if (fromOffset == -1) 6793 fromOffset = 0; 6794 } 6795 if (fromOffset > -1 && (end2 > to || i == this.children.length - 1)) { 6796 to = end2; 6797 for (let j = i + 1; j < this.children.length; j++) { 6798 let next = this.children[j]; 6799 if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { 6800 toOffset = domIndex(next.dom); 6801 break; 6802 } 6803 to += next.size; 6804 } 6805 if (toOffset == -1) 6806 toOffset = this.contentDOM.childNodes.length; 6807 break; 6808 } 6809 offset2 = end2; 6810 } 6811 return { node: this.contentDOM, from: from2, to, fromOffset, toOffset }; 6812 } 6813 emptyChildAt(side) { 6814 if (this.border || !this.contentDOM || !this.children.length) 6815 return false;
vendor: 7,077 bytes, lines 6816-7013
6816 let child = this.children[side < 0 ? 0 : this.children.length - 1]; 6817 return child.size == 0 || child.emptyChildAt(side); 6818 } 6819 domAfterPos(pos) { 6820 let { node, offset: offset2 } = this.domFromPos(pos, 0); 6821 if (node.nodeType != 1 || offset2 == node.childNodes.length) 6822 throw new RangeError("No node after pos " + pos); 6823 return node.childNodes[offset2]; 6824 } 6825 // View descs are responsible for setting any selection that falls 6826 // entirely inside of them, so that custom implementations can do 6827 // custom things with the selection. Note that this falls apart when 6828 // a selection starts in such a node and ends in another, in which 6829 // case we just use whatever domFromPos produces as a best effort. 6830 setSelection(anchor, head, root, force = false) { 6831 let from2 = Math.min(anchor, head), to = Math.max(anchor, head); 6832 for (let i = 0, offset2 = 0; i < this.children.length; i++) { 6833 let child = this.children[i], end2 = offset2 + child.size; 6834 if (from2 > offset2 && to < end2) 6835 return child.setSelection(anchor - offset2 - child.border, head - offset2 - child.border, root, force); 6836 offset2 = end2; 6837 } 6838 let anchorDOM = this.domFromPos(anchor, anchor ? -1 : 1); 6839 let headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1); 6840 let domSel = root.getSelection(); 6841 let brKludge = false; 6842 if ((gecko || safari) && anchor == head) { 6843 let { node, offset: offset2 } = anchorDOM; 6844 if (node.nodeType == 3) { 6845 brKludge = !!(offset2 && node.nodeValue[offset2 - 1] == "\n"); 6846 if (brKludge && offset2 == node.nodeValue.length) { 6847 for (let scan = node, after; scan; scan = scan.parentNode) { 6848 if (after = scan.nextSibling) { 6849 if (after.nodeName == "BR") 6850 anchorDOM = headDOM = { node: after.parentNode, offset: domIndex(after) + 1 }; 6851 break; 6852 } 6853 let desc = scan.pmViewDesc; 6854 if (desc && desc.node && desc.node.isBlock) 6855 break; 6856 } 6857 } 6858 } else { 6859 let prev = node.childNodes[offset2 - 1]; 6860 brKludge = prev && (prev.nodeName == "BR" || prev.contentEditable == "false"); 6861 } 6862 } 6863 if (gecko && domSel.focusNode && domSel.focusNode != headDOM.node && domSel.focusNode.nodeType == 1) { 6864 let after = domSel.focusNode.childNodes[domSel.focusOffset]; 6865 if (after && after.contentEditable == "false") 6866 force = true; 6867 } 6868 if (!(force || brKludge && safari) && isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) && isEquivalentPosition(headDOM.node, headDOM.offset, domSel.focusNode, domSel.focusOffset)) 6869 return; 6870 let domSelExtended = false; 6871 if ((domSel.extend || anchor == head) && !brKludge) { 6872 domSel.collapse(anchorDOM.node, anchorDOM.offset); 6873 try { 6874 if (anchor != head) 6875 domSel.extend(headDOM.node, headDOM.offset); 6876 domSelExtended = true; 6877 } catch (_) { 6878 } 6879 } 6880 if (!domSelExtended) { 6881 if (anchor > head) { 6882 let tmp = anchorDOM; 6883 anchorDOM = headDOM; 6884 headDOM = tmp; 6885 } 6886 let range = document.createRange(); 6887 range.setEnd(headDOM.node, headDOM.offset); 6888 range.setStart(anchorDOM.node, anchorDOM.offset); 6889 domSel.removeAllRanges(); 6890 domSel.addRange(range); 6891 } 6892 } 6893 ignoreMutation(mutation) { 6894 return !this.contentDOM && mutation.type != "selection"; 6895 } 6896 get contentLost() { 6897 return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM); 6898 } 6899 // Remove a subtree of the element tree that has been touched 6900 // by a DOM change, so that the next update will redraw it. 6901 markDirty(from2, to) { 6902 for (let offset2 = 0, i = 0; i < this.children.length; i++) { 6903 let child = this.children[i], end2 = offset2 + child.size; 6904 if (offset2 == end2 ? from2 <= end2 && to >= offset2 : from2 < end2 && to > offset2) { 6905 let startInside = offset2 + child.border, endInside = end2 - child.border; 6906 if (from2 >= startInside && to <= endInside) { 6907 this.dirty = from2 == offset2 || to == end2 ? CONTENT_DIRTY : CHILD_DIRTY; 6908 if (from2 == startInside && to == endInside && (child.contentLost || child.dom.parentNode != this.contentDOM)) 6909 child.dirty = NODE_DIRTY; 6910 else 6911 child.markDirty(from2 - startInside, to - startInside); 6912 return; 6913 } else { 6914 child.dirty = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM && !child.children.length ? CONTENT_DIRTY : NODE_DIRTY; 6915 } 6916 } 6917 offset2 = end2; 6918 } 6919 this.dirty = CONTENT_DIRTY; 6920 } 6921 markParentsDirty() { 6922 let level = 1; 6923 for (let node = this.parent; node; node = node.parent, level++) { 6924 let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY; 6925 if (node.dirty < dirty) 6926 node.dirty = dirty; 6927 } 6928 } 6929 get domAtom() { 6930 return false; 6931 } 6932 get ignoreForCoords() { 6933 return false; 6934 } 6935 isText(text) { 6936 return false; 6937 } 6938} 6939class WidgetViewDesc extends ViewDesc { 6940 constructor(parent, widget, view, pos) { 6941 let self, dom = widget.type.toDOM; 6942 if (typeof dom == "function") 6943 dom = dom(view, () => { 6944 if (!self) 6945 return pos; 6946 if (self.parent) 6947 return self.parent.posBeforeChild(self); 6948 }); 6949 if (!widget.type.spec.raw) { 6950 if (dom.nodeType != 1) { 6951 let wrap2 = document.createElement("span"); 6952 wrap2.appendChild(dom); 6953 dom = wrap2; 6954 } 6955 dom.contentEditable = "false"; 6956 dom.classList.add("ProseMirror-widget"); 6957 } 6958 super(parent, [], dom, null); 6959 this.widget = widget; 6960 this.widget = widget; 6961 self = this; 6962 } 6963 matchesWidget(widget) { 6964 return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type); 6965 } 6966 parseRule() { 6967 return { ignore: true }; 6968 } 6969 stopEvent(event) { 6970 let stop = this.widget.spec.stopEvent; 6971 return stop ? stop(event) : false; 6972 } 6973 ignoreMutation(mutation) { 6974 return mutation.type != "selection" || this.widget.spec.ignoreSelection; 6975 } 6976 destroy() { 6977 this.widget.type.destroy(this.dom); 6978 super.destroy(); 6979 } 6980 get domAtom() { 6981 return true; 6982 } 6983 get side() { 6984 return this.widget.type.side; 6985 } 6986} 6987class CompositionViewDesc extends ViewDesc { 6988 constructor(parent, dom, textDOM, text) { 6989 super(parent, [], dom, null); 6990 this.textDOM = textDOM; 6991 this.text = text; 6992 } 6993 get size() { 6994 return this.text.length; 6995 } 6996 localPosFromDOM(dom, offset2) { 6997 if (dom != this.textDOM) 6998 return this.posAtStart + (offset2 ? this.size : 0); 6999 return this.posAtStart + offset2; 7000 } 7001 domFromPos(pos) { 7002 return { node: this.textDOM, offset: pos }; 7003 } 7004 ignoreMutation(mut) { 7005 return mut.type === "characterData" && mut.target.nodeValue == mut.oldValue; 7006 } 7007} 7008class MarkViewDesc extends ViewDesc { 7009 constructor(parent, mark, dom, contentDOM) { 7010 super(parent, [], dom, contentDOM); 7011 this.mark = mark; 7012 } 7013 static create(parent, mark, inline, view) {
7014 let custom = view.nodeViews[mark.type.name]; 7015 let spec = custom && custom(mark, view, inline); 7016 if (!spec || !spec.dom) 7017 spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline)); 7018 return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom); 7019 } 7020 parseRule() { 7021 if (this.dirty & NODE_DIRTY || this.mark.type.spec.reparseInView) 7022 return null; 7023 return { mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM }; 7024 } 7025 matchesMark(mark) { 7026 return this.dirty != NODE_DIRTY && this.mark.eq(mark); 7027 } 7028 markDirty(from2, to) { 7029 super.markDirty(from2, to); 7030 if (this.dirty != NOT_DIRTY) { 7031 let parent = this.parent; 7032 while (!parent.node) 7033 parent = parent.parent; 7034 if (parent.dirty < this.dirty) 7035 parent.dirty = this.dirty; 7036 this.dirty = NOT_DIRTY; 7037 } 7038 } 7039 slice(from2, to, view) { 7040 let copy2 = MarkViewDesc.create(this.parent, this.mark, true, view); 7041 let nodes = this.children, size = this.size; 7042 if (to < size) 7043 nodes = replaceNodes(nodes, to, size, view); 7044 if (from2 > 0) 7045 nodes = replaceNodes(nodes, 0, from2, view); 7046 for (let i = 0; i < nodes.length; i++) 7047 nodes[i].parent = copy2; 7048 copy2.children = nodes; 7049 return copy2; 7050 } 7051} 7052class NodeViewDesc extends ViewDesc { 7053 constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) { 7054 super(parent, [], dom, contentDOM); 7055 this.node = node; 7056 this.outerDeco = outerDeco; 7057 this.innerDeco = innerDeco; 7058 this.nodeDOM = nodeDOM; 7059 } 7060 // By default, a node is rendered using the `toDOM` method from the 7061 // node type spec. But client code can use the `nodeViews` spec to 7062 // supply a custom node view, which can influence various aspects of 7063 // the way the node works. 7064 // 7065 // (Using subclassing for this was intentionally decided against, 7066 // since it'd require exposing a whole slew of finicky 7067 // implementation details to the user code that they probably will 7068 // never need.) 7069 static create(parent, node, outerDeco, innerDeco, view, pos) {
vendor: 5,880 bytes, lines 7070-7208
7070 let custom = view.nodeViews[node.type.name], descObj; 7071 let spec = custom && custom(node, view, () => { 7072 if (!descObj) 7073 return pos; 7074 if (descObj.parent) 7075 return descObj.parent.posBeforeChild(descObj); 7076 }, outerDeco, innerDeco); 7077 let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM; 7078 if (node.isText) { 7079 if (!dom) 7080 dom = document.createTextNode(node.text); 7081 else if (dom.nodeType != 3) 7082 throw new RangeError("Text must be rendered as a DOM text node"); 7083 } else if (!dom) { 7084 ({ dom, contentDOM } = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node))); 7085 } 7086 if (!contentDOM && !node.isText && dom.nodeName != "BR") { 7087 if (!dom.hasAttribute("contenteditable")) 7088 dom.contentEditable = "false"; 7089 if (node.type.spec.draggable) 7090 dom.draggable = true; 7091 } 7092 let nodeDOM = dom; 7093 dom = applyOuterDeco(dom, outerDeco, node); 7094 if (spec) 7095 return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec, view, pos + 1); 7096 else if (node.isText) 7097 return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view); 7098 else 7099 return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, view, pos + 1); 7100 } 7101 parseRule() { 7102 if (this.node.type.spec.reparseInView) 7103 return null; 7104 let rule = { node: this.node.type.name, attrs: this.node.attrs }; 7105 if (this.node.type.whitespace == "pre") 7106 rule.preserveWhitespace = "full"; 7107 if (!this.contentDOM) { 7108 rule.getContent = () => this.node.content; 7109 } else if (!this.contentLost) { 7110 rule.contentElement = this.contentDOM; 7111 } else { 7112 for (let i = this.children.length - 1; i >= 0; i--) { 7113 let child = this.children[i]; 7114 if (this.dom.contains(child.dom.parentNode)) { 7115 rule.contentElement = child.dom.parentNode; 7116 break; 7117 } 7118 } 7119 if (!rule.contentElement) 7120 rule.getContent = () => Fragment.empty; 7121 } 7122 return rule; 7123 } 7124 matchesNode(node, outerDeco, innerDeco) { 7125 return this.dirty == NOT_DIRTY && node.eq(this.node) && sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco); 7126 } 7127 get size() { 7128 return this.node.nodeSize; 7129 } 7130 get border() { 7131 return this.node.isLeaf ? 0 : 1; 7132 } 7133 // Syncs `this.children` to match `this.node.content` and the local 7134 // decorations, possibly introducing nesting for marks. Then, in a 7135 // separate step, syncs the DOM inside `this.contentDOM` to 7136 // `this.children`. 7137 updateChildren(view, pos) { 7138 let inline = this.node.inlineContent, off = pos; 7139 let composition = view.composing ? this.localCompositionInfo(view, pos) : null; 7140 let localComposition = composition && composition.pos > -1 ? composition : null; 7141 let compositionInChild = composition && composition.pos < 0; 7142 let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view); 7143 iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => { 7144 if (widget.spec.marks) 7145 updater.syncToMarks(widget.spec.marks, inline, view); 7146 else if (widget.type.side >= 0 && !insideNode) 7147 updater.syncToMarks(i == this.node.childCount ? Mark$1.none : this.node.child(i).marks, inline, view); 7148 updater.placeWidget(widget, view, off); 7149 }, (child, outerDeco, innerDeco, i) => { 7150 updater.syncToMarks(child.marks, inline, view); 7151 let compIndex; 7152 if (updater.findNodeMatch(child, outerDeco, innerDeco, i)) 7153 ; 7154 else if (compositionInChild && view.state.selection.from > off && view.state.selection.to < off + child.nodeSize && (compIndex = updater.findIndexWithChild(composition.node)) > -1 && updater.updateNodeAt(child, outerDeco, innerDeco, compIndex, view)) 7155 ; 7156 else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i, off)) 7157 ; 7158 else { 7159 updater.addNode(child, outerDeco, innerDeco, view, off); 7160 } 7161 off += child.nodeSize; 7162 }); 7163 updater.syncToMarks([], inline, view); 7164 if (this.node.isTextblock) 7165 updater.addTextblockHacks(); 7166 updater.destroyRest(); 7167 if (updater.changed || this.dirty == CONTENT_DIRTY) { 7168 if (localComposition) 7169 this.protectLocalComposition(view, localComposition); 7170 renderDescs(this.contentDOM, this.children, view); 7171 if (ios) 7172 iosHacks(this.dom); 7173 } 7174 } 7175 localCompositionInfo(view, pos) { 7176 let { from: from2, to } = view.state.selection; 7177 if (!(view.state.selection instanceof TextSelection) || from2 < pos || to > pos + this.node.content.size) 7178 return null; 7179 let textNode = view.input.compositionNode; 7180 if (!textNode || !this.dom.contains(textNode.parentNode)) 7181 return null; 7182 if (this.node.inlineContent) { 7183 let text = textNode.nodeValue; 7184 let textPos = findTextInFragment(this.node.content, text, from2 - pos, to - pos); 7185 return textPos < 0 ? null : { node: textNode, pos: textPos, text }; 7186 } else { 7187 return { node: textNode, pos: -1, text: "" }; 7188 } 7189 } 7190 protectLocalComposition(view, { node, pos, text }) { 7191 if (this.getDesc(node)) 7192 return; 7193 let topNode = node; 7194 for (; ; topNode = topNode.parentNode) { 7195 if (topNode.parentNode == this.contentDOM) 7196 break; 7197 while (topNode.previousSibling) 7198 topNode.parentNode.removeChild(topNode.previousSibling); 7199 while (topNode.nextSibling) 7200 topNode.parentNode.removeChild(topNode.nextSibling); 7201 if (topNode.pmViewDesc) 7202 topNode.pmViewDesc = void 0; 7203 } 7204 let desc = new CompositionViewDesc(this, topNode, node, text); 7205 view.input.compositionNodes.push(desc); 7206 this.children = replaceNodes(this.children, pos, pos + text.length, view, desc); 7207 } 7208 // If this desc must be updated to match the given node decoration,
7209 // do so and return true. 7210 update(node, outerDeco, innerDeco, view) { 7211 if (this.dirty == NODE_DIRTY || !node.sameMarkup(this.node)) 7212 return false; 7213 this.updateInner(node, outerDeco, innerDeco, view); 7214 return true; 7215 } 7216 updateInner(node, outerDeco, innerDeco, view) { 7217 this.updateOuterDeco(outerDeco); 7218 this.node = node; 7219 this.innerDeco = innerDeco; 7220 if (this.contentDOM) 7221 this.updateChildren(view, this.posAtStart); 7222 this.dirty = NOT_DIRTY; 7223 } 7224 updateOuterDeco(outerDeco) { 7225 if (sameOuterDeco(outerDeco, this.outerDeco)) 7226 return; 7227 let needsWrap = this.nodeDOM.nodeType != 1; 7228 let oldDOM = this.dom; 7229 this.dom = patchOuterDeco(this.dom, this.nodeDOM, computeOuterDeco(this.outerDeco, this.node, needsWrap), computeOuterDeco(outerDeco, this.node, needsWrap)); 7230 if (this.dom != oldDOM) { 7231 oldDOM.pmViewDesc = void 0; 7232 this.dom.pmViewDesc = this; 7233 } 7234 this.outerDeco = outerDeco; 7235 } 7236 // Mark this node as being the selected node. 7237 selectNode() { 7238 if (this.nodeDOM.nodeType == 1) 7239 this.nodeDOM.classList.add("ProseMirror-selectednode"); 7240 if (this.contentDOM || !this.node.type.spec.draggable) 7241 this.dom.draggable = true; 7242 } 7243 // Remove selected node marking from this node. 7244 deselectNode() { 7245 if (this.nodeDOM.nodeType == 1) 7246 this.nodeDOM.classList.remove("ProseMirror-selectednode"); 7247 if (this.contentDOM || !this.node.type.spec.draggable) 7248 this.dom.removeAttribute("draggable"); 7249 } 7250 get domAtom() { 7251 return this.node.isAtom; 7252 } 7253} 7254function docViewDesc(doc2, outerDeco, innerDeco, dom, view) { 7255 applyOuterDeco(dom, outerDeco, doc2); 7256 let docView = new NodeViewDesc(void 0, doc2, outerDeco, innerDeco, dom, dom, dom, view, 0); 7257 if (docView.contentDOM) 7258 docView.updateChildren(view, 0); 7259 return docView; 7260} 7261class TextViewDesc extends NodeViewDesc { 7262 constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) { 7263 super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view, 0); 7264 } 7265 parseRule() { 7266 let skip = this.nodeDOM.parentNode; 7267 while (skip && skip != this.dom && !skip.pmIsDeco) 7268 skip = skip.parentNode; 7269 return { skip: skip || true }; 7270 } 7271 update(node, outerDeco, innerDeco, view) { 7272 if (this.dirty == NODE_DIRTY || this.dirty != NOT_DIRTY && !this.inParent() || !node.sameMarkup(this.node)) 7273 return false; 7274 this.updateOuterDeco(outerDeco); 7275 if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue) { 7276 this.nodeDOM.nodeValue = node.text; 7277 if (view.trackWrites == this.nodeDOM) 7278 view.trackWrites = null; 7279 } 7280 this.node = node; 7281 this.dirty = NOT_DIRTY; 7282 return true; 7283 } 7284 inParent() { 7285 let parentDOM = this.parent.contentDOM; 7286 for (let n = this.nodeDOM; n; n = n.parentNode) 7287 if (n == parentDOM) 7288 return true; 7289 return false; 7290 } 7291 domFromPos(pos) { 7292 return { node: this.nodeDOM, offset: pos }; 7293 } 7294 localPosFromDOM(dom, offset2, bias) { 7295 if (dom == this.nodeDOM) 7296 return this.posAtStart + Math.min(offset2, this.node.text.length); 7297 return super.localPosFromDOM(dom, offset2, bias); 7298 } 7299 ignoreMutation(mutation) { 7300 return mutation.type != "characterData" && mutation.type != "selection"; 7301 } 7302 slice(from2, to, view) { 7303 let node = this.node.cut(from2, to), dom = document.createTextNode(node.text); 7304 return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view); 7305 } 7306 markDirty(from2, to) { 7307 super.markDirty(from2, to); 7308 if (this.dom != this.nodeDOM && (from2 == 0 || to == this.nodeDOM.nodeValue.length)) 7309 this.dirty = NODE_DIRTY; 7310 } 7311 get domAtom() { 7312 return false; 7313 } 7314 isText(text) { 7315 return this.node.text == text; 7316 } 7317} 7318class TrailingHackViewDesc extends ViewDesc { 7319 parseRule() { 7320 return { ignore: true }; 7321 } 7322 matchesHack(nodeName) { 7323 return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName; 7324 } 7325 get domAtom() { 7326 return true; 7327 } 7328 get ignoreForCoords() { 7329 return this.dom.nodeName == "IMG"; 7330 } 7331} 7332class CustomNodeViewDesc extends NodeViewDesc { 7333 constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) { 7334 super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos); 7335 this.spec = spec; 7336 } 7337 // A custom `update` method gets to decide whether the update goes 7338 // through. If it does, and there's a `contentDOM` node, our logic 7339 // updates the children. 7340 update(node, outerDeco, innerDeco, view) { 7341 if (this.dirty == NODE_DIRTY) 7342 return false;
vendor: 4,068 bytes, lines 7343-7463
7343 if (this.spec.update) { 7344 let result = this.spec.update(node, outerDeco, innerDeco); 7345 if (result) 7346 this.updateInner(node, outerDeco, innerDeco, view); 7347 return result; 7348 } else if (!this.contentDOM && !node.isLeaf) { 7349 return false; 7350 } else { 7351 return super.update(node, outerDeco, innerDeco, view); 7352 } 7353 } 7354 selectNode() { 7355 this.spec.selectNode ? this.spec.selectNode() : super.selectNode(); 7356 } 7357 deselectNode() { 7358 this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode(); 7359 } 7360 setSelection(anchor, head, root, force) { 7361 this.spec.setSelection ? this.spec.setSelection(anchor, head, root) : super.setSelection(anchor, head, root, force); 7362 } 7363 destroy() { 7364 if (this.spec.destroy) 7365 this.spec.destroy(); 7366 super.destroy(); 7367 } 7368 stopEvent(event) { 7369 return this.spec.stopEvent ? this.spec.stopEvent(event) : false; 7370 } 7371 ignoreMutation(mutation) { 7372 return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation); 7373 } 7374} 7375function renderDescs(parentDOM, descs, view) { 7376 let dom = parentDOM.firstChild, written = false; 7377 for (let i = 0; i < descs.length; i++) { 7378 let desc = descs[i], childDOM = desc.dom; 7379 if (childDOM.parentNode == parentDOM) { 7380 while (childDOM != dom) { 7381 dom = rm(dom); 7382 written = true; 7383 } 7384 dom = dom.nextSibling; 7385 } else { 7386 written = true; 7387 parentDOM.insertBefore(childDOM, dom); 7388 } 7389 if (desc instanceof MarkViewDesc) { 7390 let pos = dom ? dom.previousSibling : parentDOM.lastChild; 7391 renderDescs(desc.contentDOM, desc.children, view); 7392 dom = pos ? pos.nextSibling : parentDOM.firstChild; 7393 } 7394 } 7395 while (dom) { 7396 dom = rm(dom); 7397 written = true; 7398 } 7399 if (written && view.trackWrites == parentDOM) 7400 view.trackWrites = null; 7401} 7402const OuterDecoLevel = function(nodeName) { 7403 if (nodeName) 7404 this.nodeName = nodeName; 7405}; 7406OuterDecoLevel.prototype = /* @__PURE__ */ Object.create(null); 7407const noDeco = [new OuterDecoLevel()]; 7408function computeOuterDeco(outerDeco, node, needsWrap) { 7409 if (outerDeco.length == 0) 7410 return noDeco; 7411 let top2 = needsWrap ? noDeco[0] : new OuterDecoLevel(), result = [top2]; 7412 for (let i = 0; i < outerDeco.length; i++) { 7413 let attrs = outerDeco[i].type.attrs; 7414 if (!attrs) 7415 continue; 7416 if (attrs.nodeName) 7417 result.push(top2 = new OuterDecoLevel(attrs.nodeName)); 7418 for (let name in attrs) { 7419 let val = attrs[name]; 7420 if (val == null) 7421 continue; 7422 if (needsWrap && result.length == 1) 7423 result.push(top2 = new OuterDecoLevel(node.isInline ? "span" : "div")); 7424 if (name == "class") 7425 top2.class = (top2.class ? top2.class + " " : "") + val; 7426 else if (name == "style") 7427 top2.style = (top2.style ? top2.style + ";" : "") + val; 7428 else if (name != "nodeName") 7429 top2[name] = val; 7430 } 7431 } 7432 return result; 7433} 7434function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) { 7435 if (prevComputed == noDeco && curComputed == noDeco) 7436 return nodeDOM; 7437 let curDOM = nodeDOM; 7438 for (let i = 0; i < curComputed.length; i++) { 7439 let deco = curComputed[i], prev = prevComputed[i]; 7440 if (i) { 7441 let parent; 7442 if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && (parent = curDOM.parentNode) && parent.nodeName.toLowerCase() == deco.nodeName) { 7443 curDOM = parent; 7444 } else { 7445 parent = document.createElement(deco.nodeName); 7446 parent.pmIsDeco = true; 7447 parent.appendChild(curDOM); 7448 prev = noDeco[0]; 7449 curDOM = parent; 7450 } 7451 } 7452 patchAttributes(curDOM, prev || noDeco[0], deco); 7453 } 7454 return curDOM; 7455} 7456function patchAttributes(dom, prev, cur) { 7457 for (let name in prev) 7458 if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) 7459 dom.removeAttribute(name); 7460 for (let name in cur) 7461 if (name != "class" && name != "style" && name != "nodeName" && cur[name] != prev[name]) 7462 dom.setAttribute(name, cur[name]); 7463 if (prev.class != cur.class) {
vendor: 4,156 bytes, lines 7464-7581
7464 let prevList = prev.class ? prev.class.split(" ").filter(Boolean) : []; 7465 let curList = cur.class ? cur.class.split(" ").filter(Boolean) : []; 7466 for (let i = 0; i < prevList.length; i++) 7467 if (curList.indexOf(prevList[i]) == -1) 7468 dom.classList.remove(prevList[i]); 7469 for (let i = 0; i < curList.length; i++) 7470 if (prevList.indexOf(curList[i]) == -1) 7471 dom.classList.add(curList[i]); 7472 if (dom.classList.length == 0) 7473 dom.removeAttribute("class"); 7474 } 7475 if (prev.style != cur.style) { 7476 if (prev.style) { 7477 let prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m; 7478 while (m = prop.exec(prev.style)) 7479 dom.style.removeProperty(m[1]); 7480 } 7481 if (cur.style) 7482 dom.style.cssText += cur.style; 7483 } 7484} 7485function applyOuterDeco(dom, deco, node) { 7486 return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1)); 7487} 7488function sameOuterDeco(a, b) { 7489 if (a.length != b.length) 7490 return false; 7491 for (let i = 0; i < a.length; i++) 7492 if (!a[i].type.eq(b[i].type)) 7493 return false; 7494 return true; 7495} 7496function rm(dom) { 7497 let next = dom.nextSibling; 7498 dom.parentNode.removeChild(dom); 7499 return next; 7500} 7501class ViewTreeUpdater { 7502 constructor(top2, lock, view) { 7503 this.lock = lock; 7504 this.view = view; 7505 this.index = 0; 7506 this.stack = []; 7507 this.changed = false; 7508 this.top = top2; 7509 this.preMatch = preMatch(top2.node.content, top2); 7510 } 7511 // Destroy and remove the children between the given indices in 7512 // `this.top`. 7513 destroyBetween(start2, end2) { 7514 if (start2 == end2) 7515 return; 7516 for (let i = start2; i < end2; i++) 7517 this.top.children[i].destroy(); 7518 this.top.children.splice(start2, end2 - start2); 7519 this.changed = true; 7520 } 7521 // Destroy all remaining children in `this.top`. 7522 destroyRest() { 7523 this.destroyBetween(this.index, this.top.children.length); 7524 } 7525 // Sync the current stack of mark descs with the given array of 7526 // marks, reusing existing mark descs when possible. 7527 syncToMarks(marks, inline, view) { 7528 let keep = 0, depth = this.stack.length >> 1; 7529 let maxKeep = Math.min(depth, marks.length); 7530 while (keep < maxKeep && (keep == depth - 1 ? this.top : this.stack[keep + 1 << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) 7531 keep++; 7532 while (keep < depth) { 7533 this.destroyRest(); 7534 this.top.dirty = NOT_DIRTY; 7535 this.index = this.stack.pop(); 7536 this.top = this.stack.pop(); 7537 depth--; 7538 } 7539 while (depth < marks.length) { 7540 this.stack.push(this.top, this.index + 1); 7541 let found2 = -1; 7542 for (let i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) { 7543 let next = this.top.children[i]; 7544 if (next.matchesMark(marks[depth]) && !this.isLocked(next.dom)) { 7545 found2 = i; 7546 break; 7547 } 7548 } 7549 if (found2 > -1) { 7550 if (found2 > this.index) { 7551 this.changed = true; 7552 this.destroyBetween(this.index, found2); 7553 } 7554 this.top = this.top.children[this.index]; 7555 } else { 7556 let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view); 7557 this.top.children.splice(this.index, 0, markDesc); 7558 this.top = markDesc; 7559 this.changed = true; 7560 } 7561 this.index = 0; 7562 depth++; 7563 } 7564 } 7565 // Try to find a node desc matching the given data. Skip over it and 7566 // return true when successful. 7567 findNodeMatch(node, outerDeco, innerDeco, index) { 7568 let found2 = -1, targetDesc; 7569 if (index >= this.preMatch.index && (targetDesc = this.preMatch.matches[index - this.preMatch.index]).parent == this.top && targetDesc.matchesNode(node, outerDeco, innerDeco)) { 7570 found2 = this.top.children.indexOf(targetDesc, this.index); 7571 } else { 7572 for (let i = this.index, e = Math.min(this.top.children.length, i + 5); i < e; i++) { 7573 let child = this.top.children[i]; 7574 if (child.matchesNode(node, outerDeco, innerDeco) && !this.preMatch.matched.has(child)) { 7575 found2 = i; 7576 break; 7577 } 7578 } 7579 } 7580 if (found2 < 0) 7581 return false;
vendor: 5,226 bytes, lines 7582-7717
7582 this.destroyBetween(this.index, found2); 7583 this.index++; 7584 return true; 7585 } 7586 updateNodeAt(node, outerDeco, innerDeco, index, view) { 7587 let child = this.top.children[index]; 7588 if (child.dirty == NODE_DIRTY && child.dom == child.contentDOM) 7589 child.dirty = CONTENT_DIRTY; 7590 if (!child.update(node, outerDeco, innerDeco, view)) 7591 return false; 7592 this.destroyBetween(this.index, index); 7593 this.index++; 7594 return true; 7595 } 7596 findIndexWithChild(domNode) { 7597 for (; ; ) { 7598 let parent = domNode.parentNode; 7599 if (!parent) 7600 return -1; 7601 if (parent == this.top.contentDOM) { 7602 let desc = domNode.pmViewDesc; 7603 if (desc) 7604 for (let i = this.index; i < this.top.children.length; i++) { 7605 if (this.top.children[i] == desc) 7606 return i; 7607 } 7608 return -1; 7609 } 7610 domNode = parent; 7611 } 7612 } 7613 // Try to update the next node, if any, to the given data. Checks 7614 // pre-matches to avoid overwriting nodes that could still be used. 7615 updateNextNode(node, outerDeco, innerDeco, view, index, pos) { 7616 for (let i = this.index; i < this.top.children.length; i++) { 7617 let next = this.top.children[i]; 7618 if (next instanceof NodeViewDesc) { 7619 let preMatch2 = this.preMatch.matched.get(next); 7620 if (preMatch2 != null && preMatch2 != index) 7621 return false; 7622 let nextDOM = next.dom, updated; 7623 let locked = this.isLocked(nextDOM) && !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text && next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco)); 7624 if (!locked && next.update(node, outerDeco, innerDeco, view)) { 7625 this.destroyBetween(this.index, i); 7626 if (next.dom != nextDOM) 7627 this.changed = true; 7628 this.index++; 7629 return true; 7630 } else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) { 7631 this.top.children[this.index] = updated; 7632 if (updated.contentDOM) { 7633 updated.dirty = CONTENT_DIRTY; 7634 updated.updateChildren(view, pos + 1); 7635 updated.dirty = NOT_DIRTY; 7636 } 7637 this.changed = true; 7638 this.index++; 7639 return true; 7640 } 7641 break; 7642 } 7643 } 7644 return false; 7645 } 7646 // When a node with content is replaced by a different node with 7647 // identical content, move over its children. 7648 recreateWrapper(next, node, outerDeco, innerDeco, view, pos) { 7649 if (next.dirty || node.isAtom || !next.children.length || !next.node.content.eq(node.content)) 7650 return null; 7651 let wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos); 7652 if (wrapper.contentDOM) { 7653 wrapper.children = next.children; 7654 next.children = []; 7655 for (let ch of wrapper.children) 7656 ch.parent = wrapper; 7657 } 7658 next.destroy(); 7659 return wrapper; 7660 } 7661 // Insert the node as a newly created node desc. 7662 addNode(node, outerDeco, innerDeco, view, pos) { 7663 let desc = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos); 7664 if (desc.contentDOM) 7665 desc.updateChildren(view, pos + 1); 7666 this.top.children.splice(this.index++, 0, desc); 7667 this.changed = true; 7668 } 7669 placeWidget(widget, view, pos) { 7670 let next = this.index < this.top.children.length ? this.top.children[this.index] : null; 7671 if (next && next.matchesWidget(widget) && (widget == next.widget || !next.widget.type.toDOM.parentNode)) { 7672 this.index++; 7673 } else { 7674 let desc = new WidgetViewDesc(this.top, widget, view, pos); 7675 this.top.children.splice(this.index++, 0, desc); 7676 this.changed = true; 7677 } 7678 } 7679 // Make sure a textblock looks and behaves correctly in 7680 // contentEditable. 7681 addTextblockHacks() { 7682 let lastChild = this.top.children[this.index - 1], parent = this.top; 7683 while (lastChild instanceof MarkViewDesc) { 7684 parent = lastChild; 7685 lastChild = parent.children[parent.children.length - 1]; 7686 } 7687 if (!lastChild || // Empty textblock 7688 !(lastChild instanceof TextViewDesc) || /\n$/.test(lastChild.node.text) || this.view.requiresGeckoHackNode && /\s$/.test(lastChild.node.text)) { 7689 if ((safari || chrome) && lastChild && lastChild.dom.contentEditable == "false") 7690 this.addHackNode("IMG", parent); 7691 this.addHackNode("BR", this.top); 7692 } 7693 } 7694 addHackNode(nodeName, parent) { 7695 if (parent == this.top && this.index < parent.children.length && parent.children[this.index].matchesHack(nodeName)) { 7696 this.index++; 7697 } else { 7698 let dom = document.createElement(nodeName); 7699 if (nodeName == "IMG") { 7700 dom.className = "ProseMirror-separator"; 7701 dom.alt = ""; 7702 } 7703 if (nodeName == "BR") 7704 dom.className = "ProseMirror-trailingBreak"; 7705 let hack = new TrailingHackViewDesc(this.top, [], dom, null); 7706 if (parent != this.top) 7707 parent.children.push(hack); 7708 else 7709 parent.children.splice(this.index++, 0, hack); 7710 this.changed = true; 7711 } 7712 } 7713 isLocked(node) { 7714 return this.lock && (node == this.lock || node.nodeType == 1 && node.contains(this.lock.parentNode)); 7715 } 7716} 7717function preMatch(frag, parentDesc) {
vendor: 4,630 bytes, lines 7718-7861
7718 let curDesc = parentDesc, descI = curDesc.children.length; 7719 let fI = frag.childCount, matched = /* @__PURE__ */ new Map(), matches2 = []; 7720 outer: 7721 while (fI > 0) { 7722 let desc; 7723 for (; ; ) { 7724 if (descI) { 7725 let next = curDesc.children[descI - 1]; 7726 if (next instanceof MarkViewDesc) { 7727 curDesc = next; 7728 descI = next.children.length; 7729 } else { 7730 desc = next; 7731 descI--; 7732 break; 7733 } 7734 } else if (curDesc == parentDesc) { 7735 break outer; 7736 } else { 7737 descI = curDesc.parent.children.indexOf(curDesc); 7738 curDesc = curDesc.parent; 7739 } 7740 } 7741 let node = desc.node; 7742 if (!node) 7743 continue; 7744 if (node != frag.child(fI - 1)) 7745 break; 7746 --fI; 7747 matched.set(desc, fI); 7748 matches2.push(desc); 7749 } 7750 return { index: fI, matched, matches: matches2.reverse() }; 7751} 7752function compareSide(a, b) { 7753 return a.type.side - b.type.side; 7754} 7755function iterDeco(parent, deco, onWidget, onNode) { 7756 let locals = deco.locals(parent), offset2 = 0; 7757 if (locals.length == 0) { 7758 for (let i = 0; i < parent.childCount; i++) { 7759 let child = parent.child(i); 7760 onNode(child, locals, deco.forChild(offset2, child), i); 7761 offset2 += child.nodeSize; 7762 } 7763 return; 7764 } 7765 let decoIndex = 0, active = [], restNode = null; 7766 for (let parentIndex = 0; ; ) { 7767 let widget, widgets; 7768 while (decoIndex < locals.length && locals[decoIndex].to == offset2) { 7769 let next = locals[decoIndex++]; 7770 if (next.widget) { 7771 if (!widget) 7772 widget = next; 7773 else 7774 (widgets || (widgets = [widget])).push(next); 7775 } 7776 } 7777 if (widget) { 7778 if (widgets) { 7779 widgets.sort(compareSide); 7780 for (let i = 0; i < widgets.length; i++) 7781 onWidget(widgets[i], parentIndex, !!restNode); 7782 } else { 7783 onWidget(widget, parentIndex, !!restNode); 7784 } 7785 } 7786 let child, index; 7787 if (restNode) { 7788 index = -1; 7789 child = restNode; 7790 restNode = null; 7791 } else if (parentIndex < parent.childCount) { 7792 index = parentIndex; 7793 child = parent.child(parentIndex++); 7794 } else { 7795 break; 7796 } 7797 for (let i = 0; i < active.length; i++) 7798 if (active[i].to <= offset2) 7799 active.splice(i--, 1); 7800 while (decoIndex < locals.length && locals[decoIndex].from <= offset2 && locals[decoIndex].to > offset2) 7801 active.push(locals[decoIndex++]); 7802 let end2 = offset2 + child.nodeSize; 7803 if (child.isText) { 7804 let cutAt = end2; 7805 if (decoIndex < locals.length && locals[decoIndex].from < cutAt) 7806 cutAt = locals[decoIndex].from; 7807 for (let i = 0; i < active.length; i++) 7808 if (active[i].to < cutAt) 7809 cutAt = active[i].to; 7810 if (cutAt < end2) { 7811 restNode = child.cut(cutAt - offset2); 7812 child = child.cut(0, cutAt - offset2); 7813 end2 = cutAt; 7814 index = -1; 7815 } 7816 } else { 7817 while (decoIndex < locals.length && locals[decoIndex].to < end2) 7818 decoIndex++; 7819 } 7820 let outerDeco = child.isInline && !child.isLeaf ? active.filter((d) => !d.inline) : active.slice(); 7821 onNode(child, outerDeco, deco.forChild(offset2, child), index); 7822 offset2 = end2; 7823 } 7824} 7825function iosHacks(dom) { 7826 if (dom.nodeName == "UL" || dom.nodeName == "OL") { 7827 let oldCSS = dom.style.cssText; 7828 dom.style.cssText = oldCSS + "; list-style: square !important"; 7829 window.getComputedStyle(dom).listStyle; 7830 dom.style.cssText = oldCSS; 7831 } 7832} 7833function findTextInFragment(frag, text, from2, to) { 7834 for (let i = 0, pos = 0; i < frag.childCount && pos <= to; ) { 7835 let child = frag.child(i++), childStart = pos; 7836 pos += child.nodeSize; 7837 if (!child.isText) 7838 continue; 7839 let str = child.text; 7840 while (i < frag.childCount) { 7841 let next = frag.child(i++); 7842 pos += next.nodeSize; 7843 if (!next.isText) 7844 break; 7845 str += next.text; 7846 } 7847 if (pos >= from2) { 7848 if (pos >= to && str.slice(to - text.length - childStart, to - childStart) == text) 7849 return to - text.length; 7850 let found2 = childStart < to ? str.lastIndexOf(text, to - childStart - 1) : -1; 7851 if (found2 >= 0 && found2 + text.length + childStart >= from2) 7852 return childStart + found2; 7853 if (from2 == to && str.length >= to + text.length - childStart && str.slice(to - childStart, to - childStart + text.length) == text) 7854 return to; 7855 } 7856 } 7857 return -1; 7858} 7859function replaceNodes(nodes, from2, to, view, replacement) { 7860 let result = []; 7861 for (let i = 0, off = 0; i < nodes.length; i++) {
vendor: 4,418 bytes, lines 7862-7970
7862 let child = nodes[i], start2 = off, end2 = off += child.size; 7863 if (start2 >= to || end2 <= from2) { 7864 result.push(child); 7865 } else { 7866 if (start2 < from2) 7867 result.push(child.slice(0, from2 - start2, view)); 7868 if (replacement) { 7869 result.push(replacement); 7870 replacement = void 0; 7871 } 7872 if (end2 > to) 7873 result.push(child.slice(to - start2, child.size, view)); 7874 } 7875 } 7876 return result; 7877} 7878function selectionFromDOM(view, origin = null) { 7879 let domSel = view.domSelectionRange(), doc2 = view.state.doc; 7880 if (!domSel.focusNode) 7881 return null; 7882 let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0; 7883 let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1); 7884 if (head < 0) 7885 return null; 7886 let $head = doc2.resolve(head), $anchor, selection; 7887 if (selectionCollapsed(domSel)) { 7888 $anchor = $head; 7889 while (nearestDesc && !nearestDesc.node) 7890 nearestDesc = nearestDesc.parent; 7891 let nearestDescNode = nearestDesc.node; 7892 if (nearestDesc && nearestDescNode.isAtom && NodeSelection.isSelectable(nearestDescNode) && nearestDesc.parent && !(nearestDescNode.isInline && isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) { 7893 let pos = nearestDesc.posBefore; 7894 selection = new NodeSelection(head == pos ? $head : doc2.resolve(pos)); 7895 } 7896 } else { 7897 let anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1); 7898 if (anchor < 0) 7899 return null; 7900 $anchor = doc2.resolve(anchor); 7901 } 7902 if (!selection) { 7903 let bias = origin == "pointer" || view.state.selection.head < $head.pos && !inWidget ? 1 : -1; 7904 selection = selectionBetween(view, $anchor, $head, bias); 7905 } 7906 return selection; 7907} 7908function editorOwnsSelection(view) { 7909 return view.editable ? view.hasFocus() : hasSelection(view) && document.activeElement && document.activeElement.contains(view.dom); 7910} 7911function selectionToDOM(view, force = false) { 7912 let sel = view.state.selection; 7913 syncNodeSelection(view, sel); 7914 if (!editorOwnsSelection(view)) 7915 return; 7916 if (!force && view.input.mouseDown && view.input.mouseDown.allowDefault && chrome) { 7917 let domSel = view.domSelectionRange(), curSel = view.domObserver.currentSelection; 7918 if (domSel.anchorNode && curSel.anchorNode && isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset, curSel.anchorNode, curSel.anchorOffset)) { 7919 view.input.mouseDown.delayedSelectionSync = true; 7920 view.domObserver.setCurSelection(); 7921 return; 7922 } 7923 } 7924 view.domObserver.disconnectSelection(); 7925 if (view.cursorWrapper) { 7926 selectCursorWrapper(view); 7927 } else { 7928 let { anchor, head } = sel, resetEditableFrom, resetEditableTo; 7929 if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) { 7930 if (!sel.$from.parent.inlineContent) 7931 resetEditableFrom = temporarilyEditableNear(view, sel.from); 7932 if (!sel.empty && !sel.$from.parent.inlineContent) 7933 resetEditableTo = temporarilyEditableNear(view, sel.to); 7934 } 7935 view.docView.setSelection(anchor, head, view.root, force); 7936 if (brokenSelectBetweenUneditable) { 7937 if (resetEditableFrom) 7938 resetEditable(resetEditableFrom); 7939 if (resetEditableTo) 7940 resetEditable(resetEditableTo); 7941 } 7942 if (sel.visible) { 7943 view.dom.classList.remove("ProseMirror-hideselection"); 7944 } else { 7945 view.dom.classList.add("ProseMirror-hideselection"); 7946 if ("onselectionchange" in document) 7947 removeClassOnSelectionChange(view); 7948 } 7949 } 7950 view.domObserver.setCurSelection(); 7951 view.domObserver.connectSelection(); 7952} 7953const brokenSelectBetweenUneditable = safari || chrome && chrome_version < 63; 7954function temporarilyEditableNear(view, pos) { 7955 let { node, offset: offset2 } = view.docView.domFromPos(pos, 0); 7956 let after = offset2 < node.childNodes.length ? node.childNodes[offset2] : null; 7957 let before = offset2 ? node.childNodes[offset2 - 1] : null; 7958 if (safari && after && after.contentEditable == "false") 7959 return setEditable(after); 7960 if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { 7961 if (after) 7962 return setEditable(after); 7963 else if (before) 7964 return setEditable(before); 7965 } 7966} 7967function setEditable(element) { 7968 element.contentEditable = "true"; 7969 if (safari && element.draggable) { 7970 element.draggable = false;
7971 element.wasDraggable = true; 7972 } 7973 return element; 7974} 7975function resetEditable(element) { 7976 element.contentEditable = "false"; 7977 if (element.wasDraggable) { 7978 element.draggable = true; 7979 element.wasDraggable = null; 7980 } 7981} 7982function removeClassOnSelectionChange(view) { 7983 let doc2 = view.dom.ownerDocument; 7984 doc2.removeEventListener("selectionchange", view.input.hideSelectionGuard); 7985 let domSel = view.domSelectionRange(); 7986 let node = domSel.anchorNode, offset2 = domSel.anchorOffset; 7987 doc2.addEventListener("selectionchange", view.input.hideSelectionGuard = () => { 7988 if (domSel.anchorNode != node || domSel.anchorOffset != offset2) { 7989 doc2.removeEventListener("selectionchange", view.input.hideSelectionGuard); 7990 setTimeout(() => { 7991 if (!editorOwnsSelection(view) || view.state.selection.visible) 7992 view.dom.classList.remove("ProseMirror-hideselection"); 7993 }, 20); 7994 } 7995 }); 7996} 7997function selectCursorWrapper(view) { 7998 let domSel = view.domSelection(), range = document.createRange(); 7999 let node = view.cursorWrapper.dom, img = node.nodeName == "IMG"; 8000 if (img) 8001 range.setEnd(node.parentNode, domIndex(node) + 1); 8002 else 8003 range.setEnd(node, 0); 8004 range.collapse(false); 8005 domSel.removeAllRanges(); 8006 domSel.addRange(range); 8007 if (!img && !view.state.selection.visible && ie$1 && ie_version <= 11) { 8008 node.disabled = true; 8009 node.disabled = false; 8010 } 8011} 8012function syncNodeSelection(view, sel) { 8013 if (sel instanceof NodeSelection) { 8014 let desc = view.docView.descAt(sel.from); 8015 if (desc != view.lastSelectedViewDesc) { 8016 clearNodeSelection(view); 8017 if (desc) 8018 desc.selectNode(); 8019 view.lastSelectedViewDesc = desc; 8020 } 8021 } else { 8022 clearNodeSelection(view); 8023 } 8024} 8025function clearNodeSelection(view) { 8026 if (view.lastSelectedViewDesc) { 8027 if (view.lastSelectedViewDesc.parent) 8028 view.lastSelectedViewDesc.deselectNode(); 8029 view.lastSelectedViewDesc = void 0; 8030 } 8031} 8032function selectionBetween(view, $anchor, $head, bias) { 8033 return view.someProp("createSelectionBetween", (f) => f(view, $anchor, $head)) || TextSelection.between($anchor, $head, bias); 8034} 8035function hasFocusAndSelection(view) { 8036 if (view.editable && !view.hasFocus()) 8037 return false; 8038 return hasSelection(view); 8039} 8040function hasSelection(view) { 8041 let sel = view.domSelectionRange(); 8042 if (!sel.anchorNode) 8043 return false; 8044 try { 8045 return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)); 8046 } catch (_) { 8047 return false; 8048 } 8049} 8050function anchorInRightPlace(view) { 8051 let anchorDOM = view.docView.domFromPos(view.state.selection.anchor, 0); 8052 let domSel = view.domSelectionRange(); 8053 return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset); 8054} 8055function moveSelectionBlock(state, dir) { 8056 let { $anchor, $head } = state.selection; 8057 let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head); 8058 let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null; 8059 return $start && Selection.findFrom($start, dir); 8060} 8061function apply(view, sel) { 8062 view.dispatch(view.state.tr.setSelection(sel).scrollIntoView()); 8063 return true; 8064} 8065function selectHorizontally(view, dir, mods) { 8066 let sel = view.state.selection; 8067 if (sel instanceof TextSelection) { 8068 if (mods.indexOf("s") > -1) { 8069 let { $head } = sel, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter; 8070 if (!node || node.isText || !node.isLeaf) 8071 return false; 8072 let $newHead = view.state.doc.resolve($head.pos + node.nodeSize * (dir < 0 ? -1 : 1)); 8073 return apply(view, new TextSelection(sel.$anchor, $newHead)); 8074 } else if (!sel.empty) { 8075 return false; 8076 } else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) { 8077 let next = moveSelectionBlock(view.state, dir); 8078 if (next && next instanceof NodeSelection) 8079 return apply(view, next); 8080 return false;
vendor: 4,326 bytes, lines 8081-8223
8081 } else if (!(mac$2 && mods.indexOf("m") > -1)) { 8082 let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc; 8083 if (!node || node.isText) 8084 return false; 8085 let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos; 8086 if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) 8087 return false; 8088 if (NodeSelection.isSelectable(node)) { 8089 return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head)); 8090 } else if (webkit) { 8091 return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize))); 8092 } else { 8093 return false; 8094 } 8095 } 8096 } else if (sel instanceof NodeSelection && sel.node.isInline) { 8097 return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from)); 8098 } else { 8099 let next = moveSelectionBlock(view.state, dir); 8100 if (next) 8101 return apply(view, next); 8102 return false; 8103 } 8104} 8105function nodeLen(node) { 8106 return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; 8107} 8108function isIgnorable(dom, dir) { 8109 let desc = dom.pmViewDesc; 8110 return desc && desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR"); 8111} 8112function skipIgnoredNodes(view, dir) { 8113 return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view); 8114} 8115function skipIgnoredNodesBefore(view) { 8116 let sel = view.domSelectionRange(); 8117 let node = sel.focusNode, offset2 = sel.focusOffset; 8118 if (!node) 8119 return; 8120 let moveNode, moveOffset, force = false; 8121 if (gecko && node.nodeType == 1 && offset2 < nodeLen(node) && isIgnorable(node.childNodes[offset2], -1)) 8122 force = true; 8123 for (; ; ) { 8124 if (offset2 > 0) { 8125 if (node.nodeType != 1) { 8126 break; 8127 } else { 8128 let before = node.childNodes[offset2 - 1]; 8129 if (isIgnorable(before, -1)) { 8130 moveNode = node; 8131 moveOffset = --offset2; 8132 } else if (before.nodeType == 3) { 8133 node = before; 8134 offset2 = node.nodeValue.length; 8135 } else 8136 break; 8137 } 8138 } else if (isBlockNode(node)) { 8139 break; 8140 } else { 8141 let prev = node.previousSibling; 8142 while (prev && isIgnorable(prev, -1)) { 8143 moveNode = node.parentNode; 8144 moveOffset = domIndex(prev); 8145 prev = prev.previousSibling; 8146 } 8147 if (!prev) { 8148 node = node.parentNode; 8149 if (node == view.dom) 8150 break; 8151 offset2 = 0; 8152 } else { 8153 node = prev; 8154 offset2 = nodeLen(node); 8155 } 8156 } 8157 } 8158 if (force) 8159 setSelFocus(view, node, offset2); 8160 else if (moveNode) 8161 setSelFocus(view, moveNode, moveOffset); 8162} 8163function skipIgnoredNodesAfter(view) { 8164 let sel = view.domSelectionRange(); 8165 let node = sel.focusNode, offset2 = sel.focusOffset; 8166 if (!node) 8167 return; 8168 let len = nodeLen(node); 8169 let moveNode, moveOffset; 8170 for (; ; ) { 8171 if (offset2 < len) { 8172 if (node.nodeType != 1) 8173 break; 8174 let after = node.childNodes[offset2]; 8175 if (isIgnorable(after, 1)) { 8176 moveNode = node; 8177 moveOffset = ++offset2; 8178 } else 8179 break; 8180 } else if (isBlockNode(node)) { 8181 break; 8182 } else { 8183 let next = node.nextSibling; 8184 while (next && isIgnorable(next, 1)) { 8185 moveNode = next.parentNode; 8186 moveOffset = domIndex(next) + 1; 8187 next = next.nextSibling; 8188 } 8189 if (!next) { 8190 node = node.parentNode; 8191 if (node == view.dom) 8192 break; 8193 offset2 = len = 0; 8194 } else { 8195 node = next; 8196 offset2 = 0; 8197 len = nodeLen(node); 8198 } 8199 } 8200 } 8201 if (moveNode) 8202 setSelFocus(view, moveNode, moveOffset); 8203} 8204function isBlockNode(dom) { 8205 let desc = dom.pmViewDesc; 8206 return desc && desc.node && desc.node.isBlock; 8207} 8208function textNodeAfter(node, offset2) { 8209 while (node && offset2 == node.childNodes.length && !hasBlockDesc(node)) { 8210 offset2 = domIndex(node) + 1; 8211 node = node.parentNode; 8212 } 8213 while (node && offset2 < node.childNodes.length) { 8214 let next = node.childNodes[offset2]; 8215 if (next.nodeType == 3) 8216 return next; 8217 if (next.nodeType == 1 && next.contentEditable == "false") 8218 break; 8219 node = next; 8220 offset2 = 0; 8221 } 8222} 8223function textNodeBefore(node, offset2) {
8224 while (node && !offset2 && !hasBlockDesc(node)) { 8225 offset2 = domIndex(node); 8226 node = node.parentNode; 8227 } 8228 while (node && offset2) { 8229 let next = node.childNodes[offset2 - 1]; 8230 if (next.nodeType == 3) 8231 return next; 8232 if (next.nodeType == 1 && next.contentEditable == "false") 8233 break; 8234 node = next; 8235 offset2 = node.childNodes.length; 8236 } 8237} 8238function setSelFocus(view, node, offset2) { 8239 if (node.nodeType != 3) { 8240 let before, after; 8241 if (after = textNodeAfter(node, offset2)) { 8242 node = after; 8243 offset2 = 0; 8244 } else if (before = textNodeBefore(node, offset2)) { 8245 node = before; 8246 offset2 = before.nodeValue.length; 8247 } 8248 } 8249 let sel = view.domSelection(); 8250 if (selectionCollapsed(sel)) { 8251 let range = document.createRange(); 8252 range.setEnd(node, offset2); 8253 range.setStart(node, offset2); 8254 sel.removeAllRanges(); 8255 sel.addRange(range); 8256 } else if (sel.extend) { 8257 sel.extend(node, offset2); 8258 } 8259 view.domObserver.setCurSelection(); 8260 let { state } = view; 8261 setTimeout(() => { 8262 if (view.state == state) 8263 selectionToDOM(view); 8264 }, 50); 8265} 8266function findDirection(view, pos) { 8267 let $pos = view.state.doc.resolve(pos); 8268 if (!(chrome || windows) && $pos.parent.inlineContent) { 8269 let coords = view.coordsAtPos(pos); 8270 if (pos > $pos.start()) { 8271 let before = view.coordsAtPos(pos - 1); 8272 let mid = (before.top + before.bottom) / 2; 8273 if (mid > coords.top && mid < coords.bottom && Math.abs(before.left - coords.left) > 1) 8274 return before.left < coords.left ? "ltr" : "rtl"; 8275 } 8276 if (pos < $pos.end()) { 8277 let after = view.coordsAtPos(pos + 1); 8278 let mid = (after.top + after.bottom) / 2; 8279 if (mid > coords.top && mid < coords.bottom && Math.abs(after.left - coords.left) > 1) 8280 return after.left > coords.left ? "ltr" : "rtl"; 8281 } 8282 } 8283 let computed = getComputedStyle(view.dom).direction; 8284 return computed == "rtl" ? "rtl" : "ltr"; 8285} 8286function selectVertically(view, dir, mods) { 8287 let sel = view.state.selection; 8288 if (sel instanceof TextSelection && !sel.empty || mods.indexOf("s") > -1) 8289 return false; 8290 if (mac$2 && mods.indexOf("m") > -1) 8291 return false; 8292 let { $from, $to } = sel; 8293 if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) { 8294 let next = moveSelectionBlock(view.state, dir); 8295 if (next && next instanceof NodeSelection) 8296 return apply(view, next); 8297 } 8298 if (!$from.parent.inlineContent) { 8299 let side = dir < 0 ? $from : $to; 8300 let beyond = sel instanceof AllSelection ? Selection.near(side, dir) : Selection.findFrom(side, dir); 8301 return beyond ? apply(view, beyond) : false; 8302 } 8303 return false; 8304} 8305function stopNativeHorizontalDelete(view, dir) { 8306 if (!(view.state.selection instanceof TextSelection)) 8307 return true; 8308 let { $head, $anchor, empty: empty2 } = view.state.selection; 8309 if (!$head.sameParent($anchor)) 8310 return true; 8311 if (!empty2) 8312 return false; 8313 if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) 8314 return true; 8315 let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter); 8316 if (nextNode && !nextNode.isText) { 8317 let tr2 = view.state.tr; 8318 if (dir < 0) 8319 tr2.delete($head.pos - nextNode.nodeSize, $head.pos); 8320 else 8321 tr2.delete($head.pos, $head.pos + nextNode.nodeSize); 8322 view.dispatch(tr2); 8323 return true; 8324 } 8325 return false; 8326} 8327function switchEditable(view, node, state) { 8328 view.domObserver.stop(); 8329 node.contentEditable = state; 8330 view.domObserver.start(); 8331} 8332function safariDownArrowBug(view) { 8333 if (!safari || view.state.selection.$head.parentOffset > 0) 8334 return false; 8335 let { focusNode, focusOffset } = view.domSelectionRange(); 8336 if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && focusNode.firstChild && focusNode.firstChild.contentEditable == "false") { 8337 let child = focusNode.firstChild; 8338 switchEditable(view, child, "true"); 8339 setTimeout(() => switchEditable(view, child, "false"), 20); 8340 } 8341 return false; 8342} 8343function getMods(event) { 8344 let result = ""; 8345 if (event.ctrlKey) 8346 result += "c"; 8347 if (event.metaKey) 8348 result += "m"; 8349 if (event.altKey) 8350 result += "a"; 8351 if (event.shiftKey) 8352 result += "s"; 8353 return result; 8354} 8355function captureKeyDown(view, event) { 8356 let code = event.keyCode, mods = getMods(event); 8357 if (code == 8 || mac$2 && code == 72 && mods == "c") { 8358 return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodes(view, -1); 8359 } else if (code == 46 && !event.shiftKey || mac$2 && code == 68 && mods == "c") { 8360 return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodes(view, 1); 8361 } else if (code == 13 || code == 27) { 8362 return true; 8363 } else if (code == 37 || mac$2 && code == 66 && mods == "c") { 8364 let dir = code == 37 ? findDirection(view, view.state.selection.from) == "ltr" ? -1 : 1 : -1; 8365 return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir); 8366 } else if (code == 39 || mac$2 && code == 70 && mods == "c") { 8367 let dir = code == 39 ? findDirection(view, view.state.selection.from) == "ltr" ? 1 : -1 : 1; 8368 return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir); 8369 } else if (code == 38 || mac$2 && code == 80 && mods == "c") { 8370 return selectVertically(view, -1, mods) || skipIgnoredNodes(view, -1); 8371 } else if (code == 40 || mac$2 && code == 78 && mods == "c") { 8372 return safariDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodes(view, 1); 8373 } else if (mods == (mac$2 ? "m" : "c") && (code == 66 || code == 73 || code == 89 || code == 90)) { 8374 return true; 8375 } 8376 return false;
8377} 8378function serializeForClipboard(view, slice2) { 8379 view.someProp("transformCopied", (f) => { 8380 slice2 = f(slice2, view); 8381 }); 8382 let context = [], { content, openStart, openEnd } = slice2; 8383 while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) { 8384 openStart--; 8385 openEnd--; 8386 let node = content.firstChild; 8387 context.push(node.type.name, node.attrs != node.type.defaultAttrs ? node.attrs : null); 8388 content = node.content; 8389 } 8390 let serializer = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema); 8391 let doc2 = detachedDoc(), wrap2 = doc2.createElement("div"); 8392 wrap2.appendChild(serializer.serializeFragment(content, { document: doc2 })); 8393 let firstChild = wrap2.firstChild, needsWrap, wrappers = 0; 8394 while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) { 8395 for (let i = needsWrap.length - 1; i >= 0; i--) { 8396 let wrapper = doc2.createElement(needsWrap[i]); 8397 while (wrap2.firstChild) 8398 wrapper.appendChild(wrap2.firstChild); 8399 wrap2.appendChild(wrapper); 8400 wrappers++; 8401 } 8402 firstChild = wrap2.firstChild; 8403 } 8404 if (firstChild && firstChild.nodeType == 1) 8405 firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`); 8406 let text = view.someProp("clipboardTextSerializer", (f) => f(slice2, view)) || slice2.content.textBetween(0, slice2.content.size, "\n\n"); 8407 return { dom: wrap2, text, slice: slice2 }; 8408} 8409function parseFromClipboard(view, text, html, plainText, $context) { 8410 let inCode = $context.parent.type.spec.code; 8411 let dom, slice2; 8412 if (!html && !text) 8413 return null; 8414 let asText = text && (plainText || inCode || !html); 8415 if (asText) { 8416 view.someProp("transformPastedText", (f) => { 8417 text = f(text, inCode || plainText, view); 8418 }); 8419 if (inCode) 8420 return text ? new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0) : Slice.empty; 8421 let parsed = view.someProp("clipboardTextParser", (f) => f(text, $context, plainText, view)); 8422 if (parsed) { 8423 slice2 = parsed; 8424 } else { 8425 let marks = $context.marks(); 8426 let { schema } = view.state, serializer = DOMSerializer.fromSchema(schema); 8427 dom = document.createElement("div"); 8428 text.split(/(?:\r\n?|\n)+/).forEach((block) => { 8429 let p = dom.appendChild(document.createElement("p")); 8430 if (block) 8431 p.appendChild(serializer.serializeNode(schema.text(block, marks))); 8432 }); 8433 } 8434 } else { 8435 view.someProp("transformPastedHTML", (f) => { 8436 html = f(html, view); 8437 }); 8438 dom = readHTML(html); 8439 if (webkit) 8440 restoreReplacedSpaces(dom); 8441 } 8442 let contextNode = dom && dom.querySelector("[data-pm-slice]"); 8443 let sliceData = contextNode && /^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(contextNode.getAttribute("data-pm-slice") || ""); 8444 if (sliceData && sliceData[3]) 8445 for (let i = +sliceData[3]; i > 0; i--) { 8446 let child = dom.firstChild; 8447 while (child && child.nodeType != 1) 8448 child = child.nextSibling; 8449 if (!child) 8450 break; 8451 dom = child; 8452 } 8453 if (!slice2) { 8454 let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema); 8455 slice2 = parser.parseSlice(dom, { 8456 preserveWhitespace: !!(asText || sliceData), 8457 context: $context, 8458 ruleFromNode(dom2) { 8459 if (dom2.nodeName == "BR" && !dom2.nextSibling && dom2.parentNode && !inlineParents.test(dom2.parentNode.nodeName)) 8460 return { ignore: true }; 8461 return null; 8462 } 8463 }); 8464 } 8465 if (sliceData) { 8466 slice2 = addContext(closeSlice(slice2, +sliceData[1], +sliceData[2]), sliceData[4]); 8467 } else { 8468 slice2 = Slice.maxOpen(normalizeSiblings(slice2.content, $context), true); 8469 if (slice2.openStart || slice2.openEnd) { 8470 let openStart = 0, openEnd = 0; 8471 for (let node = slice2.content.firstChild; openStart < slice2.openStart && !node.type.spec.isolating; openStart++, node = node.firstChild) { 8472 } 8473 for (let node = slice2.content.lastChild; openEnd < slice2.openEnd && !node.type.spec.isolating; openEnd++, node = node.lastChild) { 8474 } 8475 slice2 = closeSlice(slice2, openStart, openEnd); 8476 } 8477 } 8478 view.someProp("transformPasted", (f) => { 8479 slice2 = f(slice2, view); 8480 }); 8481 return slice2; 8482} 8483const inlineParents = /^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i; 8484function normalizeSiblings(fragment, $context) { 8485 if (fragment.childCount < 2) 8486 return fragment; 8487 for (let d = $context.depth; d >= 0; d--) { 8488 let parent = $context.node(d);
vendor: 4,913 bytes, lines 8489-8614
8489 let match = parent.contentMatchAt($context.index(d)); 8490 let lastWrap, result = []; 8491 fragment.forEach((node) => { 8492 if (!result) 8493 return; 8494 let wrap2 = match.findWrapping(node.type), inLast; 8495 if (!wrap2) 8496 return result = null; 8497 if (inLast = result.length && lastWrap.length && addToSibling(wrap2, lastWrap, node, result[result.length - 1], 0)) { 8498 result[result.length - 1] = inLast; 8499 } else { 8500 if (result.length) 8501 result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length); 8502 let wrapped = withWrappers(node, wrap2); 8503 result.push(wrapped); 8504 match = match.matchType(wrapped.type); 8505 lastWrap = wrap2; 8506 } 8507 }); 8508 if (result) 8509 return Fragment.from(result); 8510 } 8511 return fragment; 8512} 8513function withWrappers(node, wrap2, from2 = 0) { 8514 for (let i = wrap2.length - 1; i >= from2; i--) 8515 node = wrap2[i].create(null, Fragment.from(node)); 8516 return node; 8517} 8518function addToSibling(wrap2, lastWrap, node, sibling, depth) { 8519 if (depth < wrap2.length && depth < lastWrap.length && wrap2[depth] == lastWrap[depth]) { 8520 let inner = addToSibling(wrap2, lastWrap, node, sibling.lastChild, depth + 1); 8521 if (inner) 8522 return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner)); 8523 let match = sibling.contentMatchAt(sibling.childCount); 8524 if (match.matchType(depth == wrap2.length - 1 ? node.type : wrap2[depth + 1])) 8525 return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap2, depth + 1)))); 8526 } 8527} 8528function closeRight(node, depth) { 8529 if (depth == 0) 8530 return node; 8531 let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1)); 8532 let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true); 8533 return node.copy(fragment.append(fill)); 8534} 8535function closeRange(fragment, side, from2, to, depth, openEnd) { 8536 let node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content; 8537 if (fragment.childCount > 1) 8538 openEnd = 0; 8539 if (depth < to - 1) 8540 inner = closeRange(inner, side, from2, to, depth + 1, openEnd); 8541 if (depth >= from2) 8542 inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, openEnd <= depth).append(inner) : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)); 8543 return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner)); 8544} 8545function closeSlice(slice2, openStart, openEnd) { 8546 if (openStart < slice2.openStart) 8547 slice2 = new Slice(closeRange(slice2.content, -1, openStart, slice2.openStart, 0, slice2.openEnd), openStart, slice2.openEnd); 8548 if (openEnd < slice2.openEnd) 8549 slice2 = new Slice(closeRange(slice2.content, 1, openEnd, slice2.openEnd, 0, 0), slice2.openStart, openEnd); 8550 return slice2; 8551} 8552const wrapMap = { 8553 thead: ["table"], 8554 tbody: ["table"], 8555 tfoot: ["table"], 8556 caption: ["table"], 8557 colgroup: ["table"], 8558 col: ["table", "colgroup"], 8559 tr: ["table", "tbody"], 8560 td: ["table", "tbody", "tr"], 8561 th: ["table", "tbody", "tr"] 8562}; 8563let _detachedDoc = null; 8564function detachedDoc() { 8565 return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title")); 8566} 8567function readHTML(html) { 8568 let metas = /^(\s*<meta [^>]*>)*/.exec(html); 8569 if (metas) 8570 html = html.slice(metas[0].length); 8571 let elt = detachedDoc().createElement("div"); 8572 let firstTag = /<([a-z][^>\s]+)/i.exec(html), wrap2; 8573 if (wrap2 = firstTag && wrapMap[firstTag[1].toLowerCase()]) 8574 html = wrap2.map((n) => "<" + n + ">").join("") + html + wrap2.map((n) => "</" + n + ">").reverse().join(""); 8575 elt.innerHTML = html; 8576 if (wrap2) 8577 for (let i = 0; i < wrap2.length; i++) 8578 elt = elt.querySelector(wrap2[i]) || elt; 8579 return elt; 8580} 8581function restoreReplacedSpaces(dom) { 8582 let nodes = dom.querySelectorAll(chrome ? "span:not([class]):not([style])" : "span.Apple-converted-space"); 8583 for (let i = 0; i < nodes.length; i++) { 8584 let node = nodes[i]; 8585 if (node.childNodes.length == 1 && node.textContent == "Â " && node.parentNode) 8586 node.parentNode.replaceChild(dom.ownerDocument.createTextNode(" "), node); 8587 } 8588} 8589function addContext(slice2, context) { 8590 if (!slice2.size) 8591 return slice2; 8592 let schema = slice2.content.firstChild.type.schema, array; 8593 try { 8594 array = JSON.parse(context); 8595 } catch (e) { 8596 return slice2; 8597 } 8598 let { content, openStart, openEnd } = slice2; 8599 for (let i = array.length - 2; i >= 0; i -= 2) { 8600 let type = schema.nodes[array[i]]; 8601 if (!type || type.hasRequiredAttrs()) 8602 break; 8603 content = Fragment.from(type.create(array[i + 1], content)); 8604 openStart++; 8605 openEnd++; 8606 } 8607 return new Slice(content, openStart, openEnd); 8608} 8609const handlers = {}; 8610const editHandlers = {}; 8611const passiveHandlers = { touchstart: true, touchmove: true }; 8612class InputState { 8613 constructor() { 8614 this.shiftKey = false;
8615 this.mouseDown = null; 8616 this.lastKeyCode = null; 8617 this.lastKeyCodeTime = 0; 8618 this.lastClick = { time: 0, x: 0, y: 0, type: "" }; 8619 this.lastSelectionOrigin = null; 8620 this.lastSelectionTime = 0; 8621 this.lastIOSEnter = 0; 8622 this.lastIOSEnterFallbackTimeout = -1; 8623 this.lastFocus = 0; 8624 this.lastTouch = 0; 8625 this.lastAndroidDelete = 0; 8626 this.composing = false; 8627 this.compositionNode = null; 8628 this.composingTimeout = -1; 8629 this.compositionNodes = []; 8630 this.compositionEndedAt = -2e8; 8631 this.compositionID = 1; 8632 this.compositionPendingChanges = 0; 8633 this.domChangeCount = 0; 8634 this.eventHandlers = /* @__PURE__ */ Object.create(null); 8635 this.hideSelectionGuard = null; 8636 } 8637} 8638function initInput(view) { 8639 for (let event in handlers) { 8640 let handler = handlers[event]; 8641 view.dom.addEventListener(event, view.input.eventHandlers[event] = (event2) => { 8642 if (eventBelongsToView(view, event2) && !runCustomHandler(view, event2) && (view.editable || !(event2.type in editHandlers))) 8643 handler(view, event2); 8644 }, passiveHandlers[event] ? { passive: true } : void 0); 8645 } 8646 if (safari) 8647 view.dom.addEventListener("input", () => null); 8648 ensureListeners(view); 8649} 8650function setSelectionOrigin(view, origin) { 8651 view.input.lastSelectionOrigin = origin; 8652 view.input.lastSelectionTime = Date.now(); 8653} 8654function destroyInput(view) { 8655 view.domObserver.stop(); 8656 for (let type in view.input.eventHandlers) 8657 view.dom.removeEventListener(type, view.input.eventHandlers[type]); 8658 clearTimeout(view.input.composingTimeout); 8659 clearTimeout(view.input.lastIOSEnterFallbackTimeout); 8660} 8661function ensureListeners(view) { 8662 view.someProp("handleDOMEvents", (currentHandlers) => { 8663 for (let type in currentHandlers) 8664 if (!view.input.eventHandlers[type]) 8665 view.dom.addEventListener(type, view.input.eventHandlers[type] = (event) => runCustomHandler(view, event)); 8666 }); 8667} 8668function runCustomHandler(view, event) { 8669 return view.someProp("handleDOMEvents", (handlers2) => { 8670 let handler = handlers2[event.type]; 8671 return handler ? handler(view, event) || event.defaultPrevented : false; 8672 }); 8673} 8674function eventBelongsToView(view, event) { 8675 if (!event.bubbles) 8676 return true; 8677 if (event.defaultPrevented) 8678 return false; 8679 for (let node = event.target; node != view.dom; node = node.parentNode) 8680 if (!node || node.nodeType == 11 || node.pmViewDesc && node.pmViewDesc.stopEvent(event)) 8681 return false; 8682 return true; 8683} 8684function dispatchEvent(view, event) { 8685 if (!runCustomHandler(view, event) && handlers[event.type] && (view.editable || !(event.type in editHandlers))) 8686 handlers[event.type](view, event); 8687} 8688editHandlers.keydown = (view, _event) => { 8689 let event = _event; 8690 view.input.shiftKey = event.keyCode == 16 || event.shiftKey; 8691 if (inOrNearComposition(view, event)) 8692 return; 8693 view.input.lastKeyCode = event.keyCode; 8694 view.input.lastKeyCodeTime = Date.now(); 8695 if (android && chrome && event.keyCode == 13) 8696 return; 8697 if (event.keyCode != 229) 8698 view.domObserver.forceFlush(); 8699 if (ios && event.keyCode == 13 && !event.ctrlKey && !event.altKey && !event.metaKey) { 8700 let now = Date.now(); 8701 view.input.lastIOSEnter = now; 8702 view.input.lastIOSEnterFallbackTimeout = setTimeout(() => { 8703 if (view.input.lastIOSEnter == now) { 8704 view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter"))); 8705 view.input.lastIOSEnter = 0; 8706 } 8707 }, 200); 8708 } else if (view.someProp("handleKeyDown", (f) => f(view, event)) || captureKeyDown(view, event)) { 8709 event.preventDefault(); 8710 } else { 8711 setSelectionOrigin(view, "key"); 8712 } 8713}; 8714editHandlers.keyup = (view, event) => { 8715 if (event.keyCode == 16) 8716 view.input.shiftKey = false; 8717}; 8718editHandlers.keypress = (view, _event) => { 8719 let event = _event; 8720 if (inOrNearComposition(view, event) || !event.charCode || event.ctrlKey && !event.altKey || mac$2 && event.metaKey) 8721 return; 8722 if (view.someProp("handleKeyPress", (f) => f(view, event))) { 8723 event.preventDefault(); 8724 return; 8725 } 8726 let sel = view.state.selection; 8727 if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) { 8728 let text = String.fromCharCode(event.charCode); 8729 if (!/[\r\n]/.test(text) && !view.someProp("handleTextInput", (f) => f(view, sel.$from.pos, sel.$to.pos, text))) 8730 view.dispatch(view.state.tr.insertText(text).scrollIntoView()); 8731 event.preventDefault(); 8732 } 8733}; 8734function eventCoords(event) { 8735 return { left: event.clientX, top: event.clientY }; 8736} 8737function isNear(event, click) { 8738 let dx = click.x - event.clientX, dy = click.y - event.clientY; 8739 return dx * dx + dy * dy < 100; 8740} 8741function runHandlerOnContext(view, propName, pos, inside, event) { 8742 if (inside == -1) 8743 return false;
8744 let $pos = view.state.doc.resolve(inside); 8745 for (let i = $pos.depth + 1; i > 0; i--) { 8746 if (view.someProp(propName, (f) => i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true) : f(view, pos, $pos.node(i), $pos.before(i), event, false))) 8747 return true; 8748 } 8749 return false; 8750} 8751function updateSelection(view, selection, origin) { 8752 if (!view.focused) 8753 view.focus(); 8754 let tr2 = view.state.tr.setSelection(selection); 8755 if (origin == "pointer") 8756 tr2.setMeta("pointer", true); 8757 view.dispatch(tr2); 8758} 8759function selectClickedLeaf(view, inside) { 8760 if (inside == -1) 8761 return false; 8762 let $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter; 8763 if (node && node.isAtom && NodeSelection.isSelectable(node)) { 8764 updateSelection(view, new NodeSelection($pos), "pointer"); 8765 return true; 8766 } 8767 return false; 8768} 8769function selectClickedNode(view, inside) { 8770 if (inside == -1) 8771 return false; 8772 let sel = view.state.selection, selectedNode, selectAt; 8773 if (sel instanceof NodeSelection) 8774 selectedNode = sel.no
8774de; 8775 let $pos = view.state.doc.resolve(inside); 8776 for (let i = $pos.depth + 1; i > 0; i--) { 8777 let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); 8778 if (NodeSelection.isSelectable(node)) { 8779 if (selectedNode && sel.$from.depth > 0 && i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) 8780 selectAt = $pos.before(sel.$from.depth); 8781 else 8782 selectAt = $pos.before(i); 8783 break; 8784 } 8785 } 8786 if (selectAt != null) { 8787 updateSelection(view, NodeSelection.create(view.state.doc, selectAt), "pointer"); 8788 return true; 8789 } else { 8790 return false; 8791 } 8792} 8793function handleSingleClick(view, pos, inside, event, selectNode) { 8794 return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || view.someProp("handleClick", (f) => f(view, pos, event)) || (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside)); 8795} 8796function handleDoubleClick(view, pos, inside, event) { 8797 return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || view.someProp("handleDoubleClick", (f) => f(view, pos, event)); 8798} 8799function handleTripleClick$1(view, pos, inside, event) { 8800 return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || view.someProp("handleTripleClick", (f) => f(view, pos, event)) || defaultTripleClick(view, inside, event); 8801} 8802function defaultTripleClick(view, inside, event) { 8803 if (event.button != 0) 8804 return false; 8805 let doc2 = view.state.doc; 8806 if (inside == -1) { 8807 if (doc2.inlineContent) { 8808 updateSelection(view, TextSelection.create(doc2, 0, doc2.content.size), "pointer"); 8809 return true; 8810 } 8811 return false; 8812 } 8813 let $pos = doc2.resolve(inside); 8814 for (let i = $pos.depth + 1; i > 0; i--) { 8815 let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); 8816 let nodePos = $pos.before(i); 8817 if (node.inlineContent) 8818 updateSelection(view, TextSelection.create(doc2, nodePos + 1, nodePos + 1 + node.content.size), "pointer"); 8819 else if (NodeSelection.isSelectable(node)) 8820 updateSelection(view, NodeSelection.create(doc2, nodePos), "pointer"); 8821 else 8822 continue; 8823 return true; 8824 } 8825} 8826function forceDOMFlush(view) { 8827 return endComposition(view); 8828} 8829const selectNodeModifier = mac$2 ? "metaKey" : "ctrlKey"; 8830handlers.mousedown = (view, _event) => { 8831 let event = _event; 8832 view.input.shiftKey = event.shiftKey; 8833 let flushed = forceDOMFlush(view); 8834 let now = Date.now(), type = "singleClick"; 8835 if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier]) { 8836 if (view.input.lastClick.type == "singleClick") 8837 type = "doubleClick"; 8838 else if (view.input.lastClick.type == "doubleClick") 8839 type = "tripleClick"; 8840 } 8841 view.input.lastClick = { time: now, x: event.clientX, y: event.clientY, type }; 8842 let pos = view.posAtCoords(eventCoords(event)); 8843 if (!pos) 8844 return; 8845 if (type == "singleClick") { 8846 if (view.input.mouseDown) 8847 view.input.mouseDown.done(); 8848 view.input.mouseDown = new MouseDown(view, pos, event, !!flushed); 8849 } else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick$1)(view, pos.pos, pos.inside, event)) { 8850 event.preventDefault(); 8851 } else { 8852 setSelectionOrigin(view, "pointer"); 8853 } 8854}; 8855class MouseDown { 8856 constructor(view, pos, event, flushed) { 8857 this.view = view; 8858 this.pos = pos; 8859 this.event = event; 8860 this.flushed = flushed; 8861 this.delayedSelectionSync = false; 8862 this.mightDrag = null; 8863 this.startDoc = view.state.doc; 8864 this.selectNode = !!event[selectNodeModifier]; 8865 this.allowDefault = event.shiftKey; 8866 let targetNode, targetPos; 8867 if (pos.inside > -1) { 8868 targetNode = view.state.doc.nodeAt(pos.inside); 8869 targetPos = pos.inside; 8870 } else { 8871 let $pos = view.state.doc.resolve(pos.pos); 8872 targetNode = $pos.parent; 8873 targetPos = $pos.depth ? $pos.before() : 0; 8874 } 8875 const target = flushed ? null : event.target; 8876 const targetDesc = target ? view.docView.nearestDesc(target, true) : null; 8877 this.target = targetDesc ? targetDesc.dom : null; 8878 let { selection } = view.state; 8879 if (event.button == 0 && targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos) 8880 this.mightDrag = { 8881 node: targetNode, 8882 pos: targetPos, 8883 addAttr: !!(this.target && !this.target.draggable), 8884 setUneditable: !!(this.target && gecko && !this.target.hasAttribute("contentEditable")) 8885 }; 8886 if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) { 8887 this.view.domObserver.stop(); 8888 if (this.mightDrag.addAttr) 8889 this.target.draggable = true; 8890 if (this.mightDrag.setUneditable) 8891 setTimeout(() => { 8892 if (this.view.input.mouseDown == this) 8893 this.target.setAttribute("contentEditable", "false"); 8894 }, 20); 8895 this.view.domObserver.start(); 8896 } 8897 view.root.addEventListener("mouseup", this.up = this.up.bind(this)); 8898 view.root.addEventListener("mousemove", this.move = this.move.bind(this)); 8899 setSelectionOrigin(view, "pointer"); 8900 } 8901 done() { 8902 this.view.root.removeEventListener("mouseup", this.up); 8903 this.view.root.removeEventListener("mousemove", this.move); 8904 if (this.mightDrag && this.target) { 8905 this.view.domObserver.stop(); 8906 if (this.mightDrag.addAttr) 8907 this.target.removeAttribute("draggable"); 8908 if (this.mightDrag.setUneditable) 8909 this.target.removeAttribute("contentEditable"); 8910 this.view.domObserver.start(); 8911 } 8912 if (this.delayedSelectionSync) 8913 setTimeout(() => selectionToDOM(this.view)); 8914 this.view.input.mouseDown = null; 8915 } 8916 up(event) { 8917 this.done(); 8918 if (!this.view.dom.contains(event.target)) 8919 return; 8920 let pos = this.pos; 8921 if (this.view.state.doc != this.startDoc) 8922 pos = this.view.posAtCoords(eventCoords(event)); 8923 this.updateAllowDefault(event); 8924 if (this.allowDefault || !pos) { 8925 setSelectionOrigin(this.view, "pointer"); 8926 } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) { 8927 event.preventDefault(); 8928 } else if (event.button == 0 && (this.flushed || // Safari ignores clicks on draggable elements 8929 safari && this.mightDrag && !this.mightDrag.node.isAtom || // Chrome will sometimes treat a node selection as a 8930 // cursor, but still report that the node is selected 8931 // when asked through getSelection. You'll then get a 8932 // situation where clicking at the point where that 8933 // (hidden) cursor is doesn't change the selection, and 8934 // thus doesn't get a reaction from ProseMirror. This 8935 // works around that. 8936 chrome && !this.view.state.selection.visible && Math.min(Math.abs(pos.pos - this.view.state.selection.from), Math.abs(pos.pos - this.view.state.selection.to)) <= 2)) { 8937 updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer"); 8938 event.preventDefault(); 8939 } else { 8940 setSelectionOrigin(this.view, "pointer"); 8941 } 8942 } 8943 move(event) { 8944 this.updateAllowDefault(event); 8945 setSelectionOrigin(this.view, "pointer"); 8946 if (event.buttons == 0) 8947 this.done(); 8948 } 8949 updateAllowDefault(event) { 8950 if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || Math.abs(this.event.y - event.clientY) > 4)) 8951 this.allowDefault = true; 8952 } 8953} 8954handlers.touchstart = (view) => { 8955 view.input.lastTouch = Date.now(); 8956 forceDOMFlush(view); 8957 setSelectionOrigin(view, "pointer"); 8958}; 8959handlers.touchmove = (view) => { 8960 view.input.lastTouch = Date.now(); 8961 setSelectionOrigin(view, "pointer"); 8962}; 8963handlers.contextmenu = (view) => forceDOMFlush(view); 8964function inOrNearComposition(view, event) { 8965 if (view.composing) 8966 return true; 8967 if (safari && Math.abs(event.timeStamp - view.input.compositionEndedAt) < 500) { 8968 view.input.compositionEndedAt = -2e8; 8969 return true; 8970 } 8971 return false;
8972} 8973const timeoutComposition = android ? 5e3 : -1; 8974editHandlers.compositionstart = editHandlers.compositionupdate = (view) => { 8975 if (!view.composing) { 8976 view.domObserver.flush(); 8977 let { state } = view, $pos = state.selection.$from; 8978 if (state.selection.empty && (state.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some((m) => m.type.spec.inclusive === false))) { 8979 view.markCursor = view.state.storedMarks || $pos.marks(); 8980 endComposition(view, true); 8981 view.markCursor = null; 8982 } else { 8983 endComposition(view); 8984 if (gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) { 8985 let sel = view.domSelectionRange(); 8986 for (let node = sel.focusNode, offset2 = sel.focusOffset; node && node.nodeType == 1 && offset2 != 0; ) { 8987 let before = offset2 < 0 ? node.lastChild : node.childNodes[offset2 - 1]; 8988 if (!before) 8989 break; 8990 if (before.nodeType == 3) { 8991 view.domSelection().collapse(before, before.nodeValue.length); 8992 break; 8993 } else { 8994 node = before; 8995 offset2 = -1; 8996 } 8997 } 8998 } 8999 } 9000 view.input.composing = true; 9001 } 9002 scheduleComposeEnd(view, timeoutComposition); 9003}; 9004editHandlers.compositionend = (view, event) => { 9005 if (view.composing) { 9006 view.input.composing = false; 9007 view.input.compositionEndedAt = event.timeStamp; 9008 view.input.compositionPendingChanges = view.domObserver.pendingRecords().length ? view.input.compositionID : 0; 9009 view.input.compositionNode = null; 9010 if (view.input.compositionPendingChanges) 9011 Promise.resolve().then(() => view.domObserver.flush()); 9012 view.input.compositionID++; 9013 scheduleComposeEnd(view, 20); 9014 } 9015}; 9016function scheduleComposeEnd(view, delay) { 9017 clearTimeout(view.input.composingTimeout); 9018 if (delay > -1) 9019 view.input.composingTimeout = setTimeout(() => endComposition(view), delay); 9020} 9021function clearComposition(view) { 9022 if (view.composing) { 9023 view.input.composing = false; 9024 view.input.compositionEndedAt = timestampFromCustomEvent(); 9025 } 9026 while (view.input.compositionNodes.length > 0) 9027 view.input.compositionNodes.pop().markParentsDirty(); 9028} 9029function findCompositionNode(view) { 9030 let sel = view.domSelectionRange(); 9031 if (!sel.focusNode) 9032 return null; 9033 let textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset); 9034 let textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset); 9035 if (textBefore && textAfter && textBefore != textAfter) { 9036 let descAfter = textAfter.pmViewDesc; 9037 if (!descAfter || !descAfter.isText(textAfter.nodeValue)) { 9038 return textAfter; 9039 } else if (view.input.compositionNode == textAfter) { 9040 let descBefore = textBefore.pmViewDesc; 9041 if (!(!descBefore || !descBefore.isText(textBefore.nodeValue))) 9042 return textAfter; 9043 } 9044 } 9045 return textBefore || textAfter; 9046} 9047function timestampFromCustomEvent() { 9048 let event = document.createEvent("Event"); 9049 event.initEvent("event", true, true); 9050 return event.timeStamp; 9051} 9052function endComposition(view, forceUpdate = false) { 9053 if (android && view.domObserver.flushingSoon >= 0) 9054 return; 9055 view.domObserver.forceFlush(); 9056 clearComposition(view); 9057 if (forceUpdate || view.docView && view.docView.dirty) { 9058 let sel = selectionFromDOM(view); 9059 if (sel && !sel.eq(view.state.selection)) 9060 view.dispatch(view.state.tr.setSelection(sel)); 9061 else 9062 view.updateState(view.state); 9063 return true; 9064 } 9065 return false; 9066} 9067function captureCopy(view, dom) { 9068 if (!view.dom.parentNode) 9069 return; 9070 let wrap2 = view.dom.parentNode.appendChild(document.createElement("div")); 9071 wrap2.appendChild(dom); 9072 wrap2.style.cssText = "position: fixed; left: -10000px; top: 10px"; 9073 let sel = getSelection(), range = document.createRange(); 9074 range.selectNodeContents(dom); 9075 view.dom.blur(); 9076 sel.removeAllRanges(); 9077 sel.addRange(range); 9078 setTimeout(() => { 9079 if (wrap2.parentNode) 9080 wrap2.parentNode.removeChild(wrap2); 9081 view.focus(); 9082 }, 50); 9083} 9084const brokenClipboardAPI = ie$1 && ie_version < 15 || ios && webkit_version < 604; 9085handlers.copy = editHandlers.cut = (view, _event) => { 9086 let event = _event; 9087 let sel = view.state.selection, cut2 = event.type == "cut"; 9088 if (sel.empty) 9089 return; 9090 let data = brokenClipboardAPI ? null : event.clipboardData; 9091 let slice2 = sel.content(), { dom, text } = serializeForClipboard(view, slice2); 9092 if (data) { 9093 event.preventDefault(); 9094 data.clearData(); 9095 data.setData("text/html", dom.innerHTML); 9096 data.setData("text/plain", text); 9097 } else { 9098 captureCopy(view, dom); 9099 } 9100 if (cut2) 9101 view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut")); 9102}; 9103function sliceSingleNode(slice2) { 9104 return slice2.openStart == 0 && slice2.openEnd == 0 && slice2.content.childCount == 1 ? slice2.content.firstChild : null; 9105} 9106function capturePaste(view, event) { 9107 if (!view.dom.parentNode) 9108 return; 9109 let plainText = view.input.shiftKey || view.state.selection.$from.parent.type.spec.code; 9110 let target = view.dom.parentNode.appendChild(document.createElement(plainText ? "textarea" : "div")); 9111 if (!plainText) 9112 target.contentEditable = "true"; 9113 target.style.cssText = "position: fixed; left: -10000px; top: 10px";
9114 target.focus(); 9115 let plain = view.input.shiftKey && view.input.lastKeyCode != 45; 9116 setTimeout(() => { 9117 view.focus(); 9118 if (target.parentNode) 9119 target.parentNode.removeChild(target); 9120 if (plainText) 9121 doPaste(view, target.value, null, plain, event); 9122 else 9123 doPaste(view, target.textContent, target.innerHTML, plain, event); 9124 }, 50); 9125} 9126function doPaste(view, text, html, preferPlain, event) { 9127 let slice2 = parseFromClipboard(view, text, html, preferPlain, view.state.selection.$from); 9128 if (view.someProp("handlePaste", (f) => f(view, event, slice2 || Slice.empty))) 9129 return true; 9130 if (!slice2) 9131 return false; 9132 let singleNode = sliceSingleNode(slice2); 9133 let tr2 = singleNode ? view.state.tr.replaceSelectionWith(singleNode, preferPlain) : view.state.tr.replaceSelection(slice2); 9134 view.dispatch(tr2.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); 9135 return true; 9136} 9137function getText$1(clipboardData) { 9138 let text = clipboardData.getData("text/plain") || clipboardData.getData("Text"); 9139 if (text) 9140 return text; 9141 let uris = clipboardData.getData("text/uri-list"); 9142 return uris ? uris.replace(/\r?\n/g, " ") : ""; 9143} 9144editHandlers.paste = (view, _event) => { 9145 let event = _event; 9146 if (view.composing && !android) 9147 return; 9148 let data = brokenClipboardAPI ? null : event.clipboardData; 9149 let plain = view.input.shiftKey && view.input.lastKeyCode != 45; 9150 if (data && doPaste(view, getText$1(data), data.getData("text/html"), plain, event)) 9151 event.preventDefault(); 9152 else 9153 capturePaste(view, event); 9154}; 9155class Dragging { 9156 constructor(slice2, move, node) { 9157 this.slice = slice2; 9158 this.move = move; 9159 this.node = node; 9160 } 9161} 9162const dragCopyModifier = mac$2 ? "altKey" : "ctrlKey"; 9163handlers.dragstart = (view, _event) => { 9164 let event = _event; 9165 let mouseDown = view.input.mouseDown; 9166 if (mouseDown) 9167 mouseDown.done(); 9168 if (!event.dataTransfer) 9169 return; 9170 let sel = view.state.selection; 9171 let pos = sel.empty ? null : view.posAtCoords(eventCoords(event)); 9172 let node; 9173 if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1 : sel.to)) 9174 ; 9175 else if (mouseDown && mouseDown.mightDrag) { 9176 node = NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos); 9177 } else if (event.target && event.target.nodeType == 1) { 9178 let desc = view.docView.nearestDesc(event.target, true); 9179 if (desc && desc.node.type.spec.draggable && desc != view.docView) 9180 node = NodeSelection.create(view.state.doc, desc.posBefore); 9181 } 9182 let draggedSlice = (node || view.state.selection).content(); 9183 let { dom, text, slice: slice2 } = serializeForClipboard(view, draggedSlice); 9184 event.dataTransfer.clearData(); 9185 event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML); 9186 event.dataTransfer.effectAllowed = "copyMove"; 9187 if (!brokenClipboardAPI) 9188 event.dataTransfer.setData("text/plain", text); 9189 view.dragging = new Dragging(slice2, !event[dragCopyModifier], node); 9190}; 9191handlers.dragend = (view) => { 9192 let dragging = view.dragging; 9193 window.setTimeout(() => { 9194 if (view.dragging == dragging) 9195 view.dragging = null; 9196 }, 50); 9197}; 9198editHandlers.dragover = editHandlers.dragenter = (_, e) => e.preventDefault(); 9199editHandlers.drop = (view, _event) => { 9200 let event = _event; 9201 let dragging = view.dragging; 9202 view.dragging = null; 9203 if (!event.dataTransfer) 9204 return; 9205 let eventPos = view.posAtCoords(eventCoords(event)); 9206 if (!eventPos) 9207 return; 9208 let $mouse = view.state.doc.resolve(eventPos.pos); 9209 let slice2 = dragging && dragging.slice; 9210 if (slice2) { 9211 view.someProp("transformPasted", (f) => { 9212 slice2 = f(slice2, view); 9213 }); 9214 } else { 9215 slice2 = parseFromClipboard(view, getText$1(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse); 9216 } 9217 let move = !!(dragging && !event[dragCopyModifier]); 9218 if (view.someProp("handleDrop", (f) => f(view, event, slice2 || Slice.empty, move))) { 9219 event.preventDefault(); 9220 return; 9221 } 9222 if (!slice2) 9223 return; 9224 event.preventDefault(); 9225 let insertPos = slice2 ? dropPoint(view.state.doc, $mouse.pos, slice2) : $mouse.pos; 9226 if (insertPos == null) 9227 insertPos = $mouse.pos; 9228 let tr2 = view.state.tr; 9229 if (move) { 9230 let { node } = dragging; 9231 if (node) 9232 node.replace(tr2); 9233 else 9234 tr2.deleteSelection(); 9235 } 9236 let pos = tr2.mapping.map(insertPos); 9237 let isNode = slice2.openStart == 0 && slice2.openEnd == 0 && slice2.content.childCount == 1; 9238 let beforeInsert = tr2.doc; 9239 if (isNode) 9240 tr2.replaceRangeWith(pos, pos, slice2.content.firstChild); 9241 else 9242 tr2.replaceRange(pos, pos, slice2); 9243 if (tr2.doc.eq(beforeInsert)) 9244 return; 9245 let $pos = tr2.doc.resolve(pos); 9246 if (isNode && NodeSelection.isSelectable(slice2.content.firstChild) && $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice2.content.firstChild)) { 9247 tr2.setSelection(new NodeSelection($pos)); 9248 } else { 9249 let end2 = tr2.mapping.map(insertPos);
vendor: 5,564 bytes, lines 9250-9427
9250 tr2.mapping.maps[tr2.mapping.maps.length - 1].forEach((_from, _to, _newFrom, newTo) => end2 = newTo); 9251 tr2.setSelection(selectionBetween(view, $pos, tr2.doc.resolve(end2))); 9252 } 9253 view.focus(); 9254 view.dispatch(tr2.setMeta("uiEvent", "drop")); 9255}; 9256handlers.focus = (view) => { 9257 view.input.lastFocus = Date.now(); 9258 if (!view.focused) { 9259 view.domObserver.stop(); 9260 view.dom.classList.add("ProseMirror-focused"); 9261 view.domObserver.start(); 9262 view.focused = true; 9263 setTimeout(() => { 9264 if (view.docView && view.hasFocus() && !view.domObserver.currentSelection.eq(view.domSelectionRange())) 9265 selectionToDOM(view); 9266 }, 20); 9267 } 9268}; 9269handlers.blur = (view, _event) => { 9270 let event = _event; 9271 if (view.focused) { 9272 view.domObserver.stop(); 9273 view.dom.classList.remove("ProseMirror-focused"); 9274 view.domObserver.start(); 9275 if (event.relatedTarget && view.dom.contains(event.relatedTarget)) 9276 view.domObserver.currentSelection.clear(); 9277 view.focused = false; 9278 } 9279}; 9280handlers.beforeinput = (view, _event) => { 9281 let event = _event; 9282 if (chrome && android && event.inputType == "deleteContentBackward") { 9283 view.domObserver.flushSoon(); 9284 let { domChangeCount } = view.input; 9285 setTimeout(() => { 9286 if (view.input.domChangeCount != domChangeCount) 9287 return; 9288 view.dom.blur(); 9289 view.focus(); 9290 if (view.someProp("handleKeyDown", (f) => f(view, keyEvent(8, "Backspace")))) 9291 return; 9292 let { $cursor } = view.state.selection; 9293 if ($cursor && $cursor.pos > 0) 9294 view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView()); 9295 }, 50); 9296 } 9297}; 9298for (let prop in editHandlers) 9299 handlers[prop] = editHandlers[prop]; 9300function compareObjs(a, b) { 9301 if (a == b) 9302 return true; 9303 for (let p in a) 9304 if (a[p] !== b[p]) 9305 return false; 9306 for (let p in b) 9307 if (!(p in a)) 9308 return false; 9309 return true; 9310} 9311class WidgetType { 9312 constructor(toDOM, spec) { 9313 this.toDOM = toDOM; 9314 this.spec = spec || noSpec; 9315 this.side = this.spec.side || 0; 9316 } 9317 map(mapping, span, offset2, oldOffset) { 9318 let { pos, deleted } = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1); 9319 return deleted ? null : new Decoration(pos - offset2, pos - offset2, this); 9320 } 9321 valid() { 9322 return true; 9323 } 9324 eq(other) { 9325 return this == other || other instanceof WidgetType && (this.spec.key && this.spec.key == other.spec.key || this.toDOM == other.toDOM && compareObjs(this.spec, other.spec)); 9326 } 9327 destroy(node) { 9328 if (this.spec.destroy) 9329 this.spec.destroy(node); 9330 } 9331} 9332class InlineType { 9333 constructor(attrs, spec) { 9334 this.attrs = attrs; 9335 this.spec = spec || noSpec; 9336 } 9337 map(mapping, span, offset2, oldOffset) { 9338 let from2 = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset2; 9339 let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset2; 9340 return from2 >= to ? null : new Decoration(from2, to, this); 9341 } 9342 valid(_, span) { 9343 return span.from < span.to; 9344 } 9345 eq(other) { 9346 return this == other || other instanceof InlineType && compareObjs(this.attrs, other.attrs) && compareObjs(this.spec, other.spec); 9347 } 9348 static is(span) { 9349 return span.type instanceof InlineType; 9350 } 9351 destroy() { 9352 } 9353} 9354class NodeType2 { 9355 constructor(attrs, spec) { 9356 this.attrs = attrs; 9357 this.spec = spec || noSpec; 9358 } 9359 map(mapping, span, offset2, oldOffset) { 9360 let from2 = mapping.mapResult(span.from + oldOffset, 1); 9361 if (from2.deleted) 9362 return null; 9363 let to = mapping.mapResult(span.to + oldOffset, -1); 9364 if (to.deleted || to.pos <= from2.pos) 9365 return null; 9366 return new Decoration(from2.pos - offset2, to.pos - offset2, this); 9367 } 9368 valid(node, span) { 9369 let { index, offset: offset2 } = node.content.findIndex(span.from), child; 9370 return offset2 == span.from && !(child = node.child(index)).isText && offset2 + child.nodeSize == span.to; 9371 } 9372 eq(other) { 9373 return this == other || other instanceof NodeType2 && compareObjs(this.attrs, other.attrs) && compareObjs(this.spec, other.spec); 9374 } 9375 destroy() { 9376 } 9377} 9378class Decoration { 9379 /** 9380 @internal 9381 */ 9382 constructor(from2, to, type) { 9383 this.from = from2; 9384 this.to = to; 9385 this.type = type; 9386 } 9387 /** 9388 @internal 9389 */ 9390 copy(from2, to) { 9391 return new Decoration(from2, to, this.type); 9392 } 9393 /** 9394 @internal 9395 */ 9396 eq(other, offset2 = 0) { 9397 return this.type.eq(other.type) && this.from + offset2 == other.from && this.to + offset2 == other.to; 9398 } 9399 /** 9400 @internal 9401 */ 9402 map(mapping, offset2, oldOffset) { 9403 return this.type.map(mapping, this, offset2, oldOffset); 9404 } 9405 /** 9406 Creates a widget decoration, which is a DOM node that's shown in 9407 the document at the given position. It is recommended that you 9408 delay rendering the widget by passing a function that will be 9409 called when the widget is actually drawn in a view, but you can 9410 also directly pass a DOM node. `getPos` can be used to find the 9411 widget's current document position. 9412 */ 9413 static widget(pos, toDOM, spec) { 9414 return new Decoration(pos, pos, new WidgetType(toDOM, spec)); 9415 } 9416 /** 9417 Creates an inline decoration, which adds the given attributes to 9418 each inline node between `from` and `to`. 9419 */ 9420 static inline(from2, to, attrs, spec) { 9421 return new Decoration(from2, to, new InlineType(attrs, spec)); 9422 } 9423 /** 9424 Creates a node decoration. `from` and `to` should point precisely 9425 before and after a node in the document. That node, and only that 9426 node, will receive the given attributes. 9427 */
vendor: 22,552 bytes, lines 9428-10092
9428 static node(from2, to, attrs, spec) { 9429 return new Decoration(from2, to, new NodeType2(attrs, spec)); 9430 } 9431 /** 9432 The spec provided when creating this decoration. Can be useful 9433 if you've stored extra information in that object. 9434 */ 9435 get spec() { 9436 return this.type.spec; 9437 } 9438 /** 9439 @internal 9440 */ 9441 get inline() { 9442 return this.type instanceof InlineType; 9443 } 9444 /** 9445 @internal 9446 */ 9447 get widget() { 9448 return this.type instanceof WidgetType; 9449 } 9450} 9451const none = [], noSpec = {}; 9452class DecorationSet { 9453 /** 9454 @internal 9455 */ 9456 constructor(local, children) { 9457 this.local = local.length ? local : none; 9458 this.children = children.length ? children : none; 9459 } 9460 /** 9461 Create a set of decorations, using the structure of the given 9462 document. This will consume (modify) the `decorations` array, so 9463 you must make a copy if you want need to preserve that. 9464 */ 9465 static create(doc2, decorations) { 9466 return decorations.length ? buildTree(decorations, doc2, 0, noSpec) : empty; 9467 } 9468 /** 9469 Find all decorations in this set which touch the given range 9470 (including decorations that start or end directly at the 9471 boundaries) and match the given predicate on their spec. When 9472 `start` and `end` are omitted, all decorations in the set are 9473 considered. When `predicate` isn't given, all decorations are 9474 assumed to match. 9475 */ 9476 find(start2, end2, predicate) { 9477 let result = []; 9478 this.findInner(start2 == null ? 0 : start2, end2 == null ? 1e9 : end2, result, 0, predicate); 9479 return result; 9480 } 9481 findInner(start2, end2, result, offset2, predicate) { 9482 for (let i = 0; i < this.local.length; i++) { 9483 let span = this.local[i]; 9484 if (span.from <= end2 && span.to >= start2 && (!predicate || predicate(span.spec))) 9485 result.push(span.copy(span.from + offset2, span.to + offset2)); 9486 } 9487 for (let i = 0; i < this.children.length; i += 3) { 9488 if (this.children[i] < end2 && this.children[i + 1] > start2) { 9489 let childOff = this.children[i] + 1; 9490 this.children[i + 2].findInner(start2 - childOff, end2 - childOff, result, offset2 + childOff, predicate); 9491 } 9492 } 9493 } 9494 /** 9495 Map the set of decorations in response to a change in the 9496 document. 9497 */ 9498 map(mapping, doc2, options) { 9499 if (this == empty || mapping.maps.length == 0) 9500 return this; 9501 return this.mapInner(mapping, doc2, 0, 0, options || noSpec); 9502 } 9503 /** 9504 @internal 9505 */ 9506 mapInner(mapping, node, offset2, oldOffset, options) { 9507 let newLocal; 9508 for (let i = 0; i < this.local.length; i++) { 9509 let mapped = this.local[i].map(mapping, offset2, oldOffset); 9510 if (mapped && mapped.type.valid(node, mapped)) 9511 (newLocal || (newLocal = [])).push(mapped); 9512 else if (options.onRemove) 9513 options.onRemove(this.local[i].spec); 9514 } 9515 if (this.children.length) 9516 return mapChildren(this.children, newLocal || [], mapping, node, offset2, oldOffset, options); 9517 else 9518 return newLocal ? new DecorationSet(newLocal.sort(byPos), none) : empty; 9519 } 9520 /** 9521 Add the given array of decorations to the ones in the set, 9522 producing a new set. Consumes the `decorations` array. Needs 9523 access to the current document to create the appropriate tree 9524 structure. 9525 */ 9526 add(doc2, decorations) { 9527 if (!decorations.length) 9528 return this; 9529 if (this == empty) 9530 return DecorationSet.create(doc2, decorations); 9531 return this.addInner(doc2, decorations, 0); 9532 } 9533 addInner(doc2, decorations, offset2) { 9534 let children, childIndex = 0; 9535 doc2.forEach((childNode, childOffset) => { 9536 let baseOffset = childOffset + offset2, found2; 9537 if (!(found2 = takeSpansForNode(decorations, childNode, baseOffset))) 9538 return; 9539 if (!children) 9540 children = this.children.slice(); 9541 while (childIndex < children.length && children[childIndex] < childOffset) 9542 childIndex += 3; 9543 if (children[childIndex] == childOffset) 9544 children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found2, baseOffset + 1); 9545 else 9546 children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found2, childNode, baseOffset + 1, noSpec)); 9547 childIndex += 3; 9548 }); 9549 let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset2); 9550 for (let i = 0; i < local.length; i++) 9551 if (!local[i].type.valid(doc2, local[i])) 9552 local.splice(i--, 1); 9553 return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, children || this.children); 9554 } 9555 /** 9556 Create a new set that contains the decorations in this set, minus 9557 the ones in the given array. 9558 */ 9559 remove(decorations) { 9560 if (decorations.length == 0 || this == empty) 9561 return this; 9562 return this.removeInner(decorations, 0); 9563 } 9564 removeInner(decorations, offset2) { 9565 let children = this.children, local = this.local; 9566 for (let i = 0; i < children.length; i += 3) { 9567 let found2; 9568 let from2 = children[i] + offset2, to = children[i + 1] + offset2; 9569 for (let j = 0, span; j < decorations.length; j++) 9570 if (span = decorations[j]) { 9571 if (span.from > from2 && span.to < to) { 9572 decorations[j] = null; 9573 (found2 || (found2 = [])).push(span); 9574 } 9575 } 9576 if (!found2) 9577 continue; 9578 if (children == this.children) 9579 children = this.children.slice(); 9580 let removed = children[i + 2].removeInner(found2, from2 + 1); 9581 if (removed != empty) { 9582 children[i + 2] = removed; 9583 } else { 9584 children.splice(i, 3); 9585 i -= 3; 9586 } 9587 } 9588 if (local.length) { 9589 for (let i = 0, span; i < decorations.length; i++) 9590 if (span = decorations[i]) { 9591 for (let j = 0; j < local.length; j++) 9592 if (local[j].eq(span, offset2)) { 9593 if (local == this.local) 9594 local = this.local.slice(); 9595 local.splice(j--, 1); 9596 } 9597 } 9598 } 9599 if (children == this.children && local == this.local) 9600 return this; 9601 return local.length || children.length ? new DecorationSet(local, children) : empty; 9602 } 9603 forChild(offset2, node) { 9604 if (this == empty) 9605 return this; 9606 if (node.isLeaf) 9607 return DecorationSet.empty; 9608 let child, local; 9609 for (let i = 0; i < this.children.length; i += 3) 9610 if (this.children[i] >= offset2) { 9611 if (this.children[i] == offset2) 9612 child = this.children[i + 2]; 9613 break; 9614 } 9615 let start2 = offset2 + 1, end2 = start2 + node.content.size; 9616 for (let i = 0; i < this.local.length; i++) { 9617 let dec = this.local[i]; 9618 if (dec.from < end2 && dec.to > start2 && dec.type instanceof InlineType) { 9619 let from2 = Math.max(start2, dec.from) - start2, to = Math.min(end2, dec.to) - start2; 9620 if (from2 < to) 9621 (local || (local = [])).push(dec.copy(from2, to)); 9622 } 9623 } 9624 if (local) { 9625 let localSet = new DecorationSet(local.sort(byPos), none); 9626 return child ? new DecorationGroup([localSet, child]) : localSet; 9627 } 9628 return child || empty; 9629 } 9630 /** 9631 @internal 9632 */ 9633 eq(other) { 9634 if (this == other) 9635 return true; 9636 if (!(other instanceof DecorationSet) || this.local.length != other.local.length || this.children.length != other.children.length) 9637 return false; 9638 for (let i = 0; i < this.local.length; i++) 9639 if (!this.local[i].eq(other.local[i])) 9640 return false; 9641 for (let i = 0; i < this.children.length; i += 3) 9642 if (this.children[i] != other.children[i] || this.children[i + 1] != other.children[i + 1] || !this.children[i + 2].eq(other.children[i + 2])) 9643 return false; 9644 return true; 9645 } 9646 /** 9647 @internal 9648 */ 9649 locals(node) { 9650 return removeOverlap(this.localsInner(node)); 9651 } 9652 /** 9653 @internal 9654 */ 9655 localsInner(node) { 9656 if (this == empty) 9657 return none; 9658 if (node.inlineContent || !this.local.some(InlineType.is)) 9659 return this.local; 9660 let result = []; 9661 for (let i = 0; i < this.local.length; i++) { 9662 if (!(this.local[i].type instanceof InlineType)) 9663 result.push(this.local[i]); 9664 } 9665 return result; 9666 } 9667} 9668DecorationSet.empty = new DecorationSet([], []); 9669DecorationSet.removeOverlap = removeOverlap; 9670const empty = DecorationSet.empty; 9671class DecorationGroup { 9672 constructor(members) { 9673 this.members = members; 9674 } 9675 map(mapping, doc2) { 9676 const mappedDecos = this.members.map((member) => member.map(mapping, doc2, noSpec)); 9677 return DecorationGroup.from(mappedDecos); 9678 } 9679 forChild(offset2, child) { 9680 if (child.isLeaf) 9681 return DecorationSet.empty; 9682 let found2 = []; 9683 for (let i = 0; i < this.members.length; i++) { 9684 let result = this.members[i].forChild(offset2, child); 9685 if (result == empty) 9686 continue; 9687 if (result instanceof DecorationGroup) 9688 found2 = found2.concat(result.members); 9689 else 9690 found2.push(result); 9691 } 9692 return DecorationGroup.from(found2); 9693 } 9694 eq(other) { 9695 if (!(other instanceof DecorationGroup) || other.members.length != this.members.length) 9696 return false; 9697 for (let i = 0; i < this.members.length; i++) 9698 if (!this.members[i].eq(other.members[i])) 9699 return false; 9700 return true; 9701 } 9702 locals(node) { 9703 let result, sorted = true; 9704 for (let i = 0; i < this.members.length; i++) { 9705 let locals = this.members[i].localsInner(node); 9706 if (!locals.length) 9707 continue; 9708 if (!result) { 9709 result = locals; 9710 } else { 9711 if (sorted) { 9712 result = result.slice(); 9713 sorted = false; 9714 } 9715 for (let j = 0; j < locals.length; j++) 9716 result.push(locals[j]); 9717 } 9718 } 9719 return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none; 9720 } 9721 // Create a group for the given array of decoration sets, or return 9722 // a single set when possible. 9723 static from(members) { 9724 switch (members.length) { 9725 case 0: 9726 return empty; 9727 case 1: 9728 return members[0]; 9729 default: 9730 return new DecorationGroup(members.every((m) => m instanceof DecorationSet) ? members : members.reduce((r, m) => r.concat(m instanceof DecorationSet ? m : m.members), [])); 9731 } 9732 } 9733} 9734function mapChildren(oldChildren, newLocal, mapping, node, offset2, oldOffset, options) { 9735 let children = oldChildren.slice(); 9736 for (let i = 0, baseOffset = oldOffset; i < mapping.maps.length; i++) { 9737 let moved = 0; 9738 mapping.maps[i].forEach((oldStart, oldEnd, newStart, newEnd) => { 9739 let dSize = newEnd - newStart - (oldEnd - oldStart); 9740 for (let i2 = 0; i2 < children.length; i2 += 3) { 9741 let end2 = children[i2 + 1]; 9742 if (end2 < 0 || oldStart > end2 + baseOffset - moved) 9743 continue; 9744 let start2 = children[i2] + baseOffset - moved; 9745 if (oldEnd >= start2) { 9746 children[i2 + 1] = oldStart <= start2 ? -2 : -1; 9747 } else if (oldStart >= baseOffset && dSize) { 9748 children[i2] += dSize; 9749 children[i2 + 1] += dSize; 9750 } 9751 } 9752 moved += dSize; 9753 }); 9754 baseOffset = mapping.maps[i].map(baseOffset, -1); 9755 } 9756 let mustRebuild = false; 9757 for (let i = 0; i < children.length; i += 3) 9758 if (children[i + 1] < 0) { 9759 if (children[i + 1] == -2) { 9760 mustRebuild = true; 9761 children[i + 1] = -1; 9762 continue; 9763 } 9764 let from2 = mapping.map(oldChildren[i] + oldOffset), fromLocal = from2 - offset2; 9765 if (fromLocal < 0 || fromLocal >= node.content.size) { 9766 mustRebuild = true; 9767 continue; 9768 } 9769 let to = mapping.map(oldChildren[i + 1] + oldOffset, -1), toLocal = to - offset2; 9770 let { index, offset: childOffset } = node.content.findIndex(fromLocal); 9771 let childNode = node.maybeChild(index); 9772 if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) { 9773 let mapped = children[i + 2].mapInner(mapping, childNode, from2 + 1, oldChildren[i] + oldOffset + 1, options); 9774 if (mapped != empty) { 9775 children[i] = fromLocal; 9776 children[i + 1] = toLocal; 9777 children[i + 2] = mapped; 9778 } else { 9779 children[i + 1] = -2; 9780 mustRebuild = true; 9781 } 9782 } else { 9783 mustRebuild = true; 9784 } 9785 } 9786 if (mustRebuild) { 9787 let decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal, mapping, offset2, oldOffset, options); 9788 let built = buildTree(decorations, node, 0, options); 9789 newLocal = built.local; 9790 for (let i = 0; i < children.length; i += 3) 9791 if (children[i + 1] < 0) { 9792 children.splice(i, 3); 9793 i -= 3; 9794 } 9795 for (let i = 0, j = 0; i < built.children.length; i += 3) { 9796 let from2 = built.children[i]; 9797 while (j < children.length && children[j] < from2) 9798 j += 3; 9799 children.splice(j, 0, built.children[i], built.children[i + 1], built.children[i + 2]); 9800 } 9801 } 9802 return new DecorationSet(newLocal.sort(byPos), children); 9803} 9804function moveSpans(spans, offset2) { 9805 if (!offset2 || !spans.length) 9806 return spans; 9807 let result = []; 9808 for (let i = 0; i < spans.length; i++) { 9809 let span = spans[i]; 9810 result.push(new Decoration(span.from + offset2, span.to + offset2, span.type)); 9811 } 9812 return result; 9813} 9814function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset2, oldOffset, options) { 9815 function gather(set, oldOffset2) { 9816 for (let i = 0; i < set.local.length; i++) { 9817 let mapped = set.local[i].map(mapping, offset2, oldOffset2); 9818 if (mapped) 9819 decorations.push(mapped); 9820 else if (options.onRemove) 9821 options.onRemove(set.local[i].spec); 9822 } 9823 for (let i = 0; i < set.children.length; i += 3) 9824 gather(set.children[i + 2], set.children[i] + oldOffset2 + 1); 9825 } 9826 for (let i = 0; i < children.length; i += 3) 9827 if (children[i + 1] == -1) 9828 gather(children[i + 2], oldChildren[i] + oldOffset + 1); 9829 return decorations; 9830} 9831function takeSpansForNode(spans, node, offset2) { 9832 if (node.isLeaf) 9833 return null; 9834 let end2 = offset2 + node.nodeSize, found2 = null; 9835 for (let i = 0, span; i < spans.length; i++) { 9836 if ((span = spans[i]) && span.from > offset2 && span.to < end2) { 9837 (found2 || (found2 = [])).push(span); 9838 spans[i] = null; 9839 } 9840 } 9841 return found2; 9842} 9843function withoutNulls(array) { 9844 let result = []; 9845 for (let i = 0; i < array.length; i++) 9846 if (array[i] != null) 9847 result.push(array[i]); 9848 return result; 9849} 9850function buildTree(spans, node, offset2, options) { 9851 let children = [], hasNulls = false; 9852 node.forEach((childNode, localStart) => { 9853 let found2 = takeSpansForNode(spans, childNode, localStart + offset2); 9854 if (found2) { 9855 hasNulls = true; 9856 let subtree = buildTree(found2, childNode, offset2 + localStart + 1, options); 9857 if (subtree != empty) 9858 children.push(localStart, localStart + childNode.nodeSize, subtree); 9859 } 9860 }); 9861 let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset2).sort(byPos); 9862 for (let i = 0; i < locals.length; i++) 9863 if (!locals[i].type.valid(node, locals[i])) { 9864 if (options.onRemove) 9865 options.onRemove(locals[i].spec); 9866 locals.splice(i--, 1); 9867 } 9868 return locals.length || children.length ? new DecorationSet(locals, children) : empty; 9869} 9870function byPos(a, b) { 9871 return a.from - b.from || a.to - b.to; 9872} 9873function removeOverlap(spans) { 9874 let working = spans; 9875 for (let i = 0; i < working.length - 1; i++) { 9876 let span = working[i]; 9877 if (span.from != span.to) 9878 for (let j = i + 1; j < working.length; j++) { 9879 let next = working[j]; 9880 if (next.from == span.from) { 9881 if (next.to != span.to) { 9882 if (working == spans) 9883 working = spans.slice(); 9884 working[j] = next.copy(next.from, span.to); 9885 insertAhead(working, j + 1, next.copy(span.to, next.to)); 9886 } 9887 continue; 9888 } else { 9889 if (next.from < span.to) { 9890 if (working == spans) 9891 working = spans.slice(); 9892 working[i] = span.copy(span.from, next.from); 9893 insertAhead(working, j, span.copy(next.from, span.to)); 9894 } 9895 break; 9896 } 9897 } 9898 } 9899 return working; 9900} 9901function insertAhead(array, i, deco) { 9902 while (i < array.length && byPos(deco, array[i]) > 0) 9903 i++; 9904 array.splice(i, 0, deco); 9905} 9906function viewDecorations(view) { 9907 let found2 = []; 9908 view.someProp("decorations", (f) => { 9909 let result = f(view.state); 9910 if (result && result != empty) 9911 found2.push(result); 9912 }); 9913 if (view.cursorWrapper) 9914 found2.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco])); 9915 return DecorationGroup.from(found2); 9916} 9917const observeOptions = { 9918 childList: true, 9919 characterData: true, 9920 characterDataOldValue: true, 9921 attributes: true, 9922 attributeOldValue: true, 9923 subtree: true 9924}; 9925const useCharData = ie$1 && ie_version <= 11; 9926class SelectionState { 9927 constructor() { 9928 this.anchorNode = null; 9929 this.anchorOffset = 0; 9930 this.focusNode = null; 9931 this.focusOffset = 0; 9932 } 9933 set(sel) { 9934 this.anchorNode = sel.anchorNode; 9935 this.anchorOffset = sel.anchorOffset; 9936 this.focusNode = sel.focusNode; 9937 this.focusOffset = sel.focusOffset; 9938 } 9939 clear() { 9940 this.anchorNode = this.focusNode = null; 9941 } 9942 eq(sel) { 9943 return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset; 9944 } 9945} 9946class DOMObserver { 9947 constructor(view, handleDOMChange) { 9948 this.view = view; 9949 this.handleDOMChange = handleDOMChange; 9950 this.queue = []; 9951 this.flushingSoon = -1; 9952 this.observer = null; 9953 this.currentSelection = new SelectionState(); 9954 this.onCharData = null; 9955 this.suppressingSelectionUpdates = false; 9956 this.observer = window.MutationObserver && new window.MutationObserver((mutations) => { 9957 for (let i = 0; i < mutations.length; i++) 9958 this.queue.push(mutations[i]); 9959 if (ie$1 && ie_version <= 11 && mutations.some((m) => m.type == "childList" && m.removedNodes.length || m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length)) 9960 this.flushSoon(); 9961 else 9962 this.flush(); 9963 }); 9964 if (useCharData) { 9965 this.onCharData = (e) => { 9966 this.queue.push({ target: e.target, type: "characterData", oldValue: e.prevValue }); 9967 this.flushSoon(); 9968 }; 9969 } 9970 this.onSelectionChange = this.onSelectionChange.bind(this); 9971 } 9972 flushSoon() { 9973 if (this.flushingSoon < 0) 9974 this.flushingSoon = window.setTimeout(() => { 9975 this.flushingSoon = -1; 9976 this.flush(); 9977 }, 20); 9978 } 9979 forceFlush() { 9980 if (this.flushingSoon > -1) { 9981 window.clearTimeout(this.flushingSoon); 9982 this.flushingSoon = -1; 9983 this.flush(); 9984 } 9985 } 9986 start() { 9987 if (this.observer) { 9988 this.observer.takeRecords(); 9989 this.observer.observe(this.view.dom, observeOptions); 9990 } 9991 if (this.onCharData) 9992 this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData); 9993 this.connectSelection(); 9994 } 9995 stop() { 9996 if (this.observer) { 9997 let take = this.observer.takeRecords(); 9998 if (take.length) { 9999 for (let i = 0; i < take.length; i++) 10000 this.queue.push(take[i]); 10001 window.setTimeout(() => this.flush(), 20); 10002 } 10003 this.observer.disconnect(); 10004 } 10005 if (this.onCharData) 10006 this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData); 10007 this.disconnectSelection(); 10008 } 10009 connectSelection() { 10010 this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); 10011 } 10012 disconnectSelection() { 10013 this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); 10014 } 10015 suppressSelectionUpdates() { 10016 this.suppressingSelectionUpdates = true; 10017 setTimeout(() => this.suppressingSelectionUpdates = false, 50); 10018 } 10019 onSelectionChange() { 10020 if (!hasFocusAndSelection(this.view)) 10021 return; 10022 if (this.suppressingSelectionUpdates) 10023 return selectionToDOM(this.view); 10024 if (ie$1 && ie_version <= 11 && !this.view.state.selection.empty) { 10025 let sel = this.view.domSelectionRange(); 10026 if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) 10027 return this.flushSoon(); 10028 } 10029 this.flush(); 10030 } 10031 setCurSelection() { 10032 this.currentSelection.set(this.view.domSelectionRange()); 10033 } 10034 ignoreSelectionChange(sel) { 10035 if (!sel.focusNode) 10036 return true; 10037 let ancestors = /* @__PURE__ */ new Set(), container; 10038 for (let scan = sel.focusNode; scan; scan = parentNode(scan)) 10039 ancestors.add(scan); 10040 for (let scan = sel.anchorNode; scan; scan = parentNode(scan)) 10041 if (ancestors.has(scan)) { 10042 container = scan; 10043 break; 10044 } 10045 let desc = container && this.view.docView.nearestDesc(container); 10046 if (desc && desc.ignoreMutation({ 10047 type: "selection", 10048 target: container.nodeType == 3 ? container.parentNode : container 10049 })) { 10050 this.setCurSelection(); 10051 return true; 10052 } 10053 } 10054 pendingRecords() { 10055 if (this.observer) 10056 for (let mut of this.observer.takeRecords()) 10057 this.queue.push(mut); 10058 return this.queue; 10059 } 10060 flush() { 10061 let { view } = this; 10062 if (!view.docView || this.flushingSoon > -1) 10063 return; 10064 let mutations = this.pendingRecords(); 10065 if (mutations.length) 10066 this.queue = []; 10067 let sel = view.domSelectionRange(); 10068 let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel); 10069 let from2 = -1, to = -1, typeOver = false, added = []; 10070 if (view.editable) { 10071 for (let i = 0; i < mutations.length; i++) { 10072 let result = this.registerMutation(mutations[i], added); 10073 if (result) { 10074 from2 = from2 < 0 ? result.from : Math.min(result.from, from2); 10075 to = to < 0 ? result.to : Math.max(result.to, to); 10076 if (result.typeOver) 10077 typeOver = true; 10078 } 10079 } 10080 } 10081 if (gecko && added.length > 1) { 10082 let brs = added.filter((n) => n.nodeName == "BR"); 10083 if (brs.length == 2) { 10084 let a = brs[0], b = brs[1]; 10085 if (a.parentNode && a.parentNode.parentNode == b.parentNode) 10086 b.remove(); 10087 else 10088 a.remove(); 10089 } 10090 } 10091 let readSel = null; 10092 if (from2 < 0 && newSel && view.input.lastFocus > Date.now() - 200 && Math.max(view.input.lastTouch, view.input.last
vendor: 9,157 bytes, lines 10092-10296
10092Click.time) < Date.now() - 300 && selectionCollapsed(sel) && (readSel = selectionFromDOM(view)) && readSel.eq(Selection.near(view.state.doc.resolve(0), 1))) { 10093 view.input.lastFocus = 0; 10094 selectionToDOM(view); 10095 this.currentSelection.set(sel); 10096 view.scrollToSelection(); 10097 } else if (from2 > -1 || newSel) { 10098 if (from2 > -1) { 10099 view.docView.markDirty(from2, to); 10100 checkCSS(view); 10101 } 10102 this.handleDOMChange(from2, to, typeOver, added); 10103 if (view.docView && view.docView.dirty) 10104 view.updateState(view.state); 10105 else if (!this.currentSelection.eq(sel)) 10106 selectionToDOM(view); 10107 this.currentSelection.set(sel); 10108 } 10109 } 10110 registerMutation(mut, added) { 10111 if (added.indexOf(mut.target) > -1) 10112 return null; 10113 let desc = this.view.docView.nearestDesc(mut.target); 10114 if (mut.type == "attributes" && (desc == this.view.docView || mut.attributeName == "contenteditable" || // Firefox sometimes fires spurious events for null/empty styles 10115 mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style"))) 10116 return null; 10117 if (!desc || desc.ignoreMutation(mut)) 10118 return null; 10119 if (mut.type == "childList") { 10120 for (let i = 0; i < mut.addedNodes.length; i++) 10121 added.push(mut.addedNodes[i]); 10122 if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target)) 10123 return { from: desc.posBefore, to: desc.posAfter }; 10124 let prev = mut.previousSibling, next = mut.nextSibling; 10125 if (ie$1 && ie_version <= 11 && mut.addedNodes.length) { 10126 for (let i = 0; i < mut.addedNodes.length; i++) { 10127 let { previousSibling, nextSibling } = mut.addedNodes[i]; 10128 if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) 10129 prev = previousSibling; 10130 if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) 10131 next = nextSibling; 10132 } 10133 } 10134 let fromOffset = prev && prev.parentNode == mut.target ? domIndex(prev) + 1 : 0; 10135 let from2 = desc.localPosFromDOM(mut.target, fromOffset, -1); 10136 let toOffset = next && next.parentNode == mut.target ? domIndex(next) : mut.target.childNodes.length; 10137 let to = desc.localPosFromDOM(mut.target, toOffset, 1); 10138 return { from: from2, to }; 10139 } else if (mut.type == "attributes") { 10140 return { from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border }; 10141 } else { 10142 return { 10143 from: desc.posAtStart, 10144 to: desc.posAtEnd, 10145 // An event was generated for a text change that didn't change 10146 // any text. Mark the dom change to fall back to assuming the 10147 // selection was typed over with an identical value if it can't 10148 // find another change. 10149 typeOver: mut.target.nodeValue == mut.oldValue 10150 }; 10151 } 10152 } 10153} 10154let cssChecked = /* @__PURE__ */ new WeakMap(); 10155let cssCheckWarned = false; 10156function checkCSS(view) { 10157 if (cssChecked.has(view)) 10158 return; 10159 cssChecked.set(view, null); 10160 if (["normal", "nowrap", "pre-line"].indexOf(getComputedStyle(view.dom).whiteSpace) !== -1) { 10161 view.requiresGeckoHackNode = gecko; 10162 if (cssCheckWarned) 10163 return; 10164 console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."); 10165 cssCheckWarned = true; 10166 } 10167} 10168function rangeToSelectionRange(view, range) { 10169 let anchorNode = range.startContainer, anchorOffset = range.startOffset; 10170 let focusNode = range.endContainer, focusOffset = range.endOffset; 10171 let currentAnchor = view.domAtPos(view.state.selection.anchor); 10172 if (isEquivalentPosition(currentAnchor.node, currentAnchor.offset, focusNode, focusOffset)) 10173 [anchorNode, anchorOffset, focusNode, focusOffset] = [focusNode, focusOffset, anchorNode, anchorOffset]; 10174 return { anchorNode, anchorOffset, focusNode, focusOffset }; 10175} 10176function safariShadowSelectionRange(view, selection) { 10177 if (selection.getComposedRanges) { 10178 let range = selection.getComposedRanges(view.root)[0]; 10179 if (range) 10180 return rangeToSelectionRange(view, range); 10181 } 10182 let found2; 10183 function read2(event) { 10184 event.preventDefault(); 10185 event.stopImmediatePropagation(); 10186 found2 = event.getTargetRanges()[0]; 10187 } 10188 view.dom.addEventListener("beforeinput", read2, true); 10189 document.execCommand("indent"); 10190 view.dom.removeEventListener("beforeinput", read2, true); 10191 return found2 ? rangeToSelectionRange(view, found2) : null; 10192} 10193function parseBetween(view, from_, to_) { 10194 let { node: parent, fromOffset, toOffset, from: from2, to } = view.docView.parseRange(from_, to_); 10195 let domSel = view.domSelectionRange(); 10196 let find2; 10197 let anchor = domSel.anchorNode; 10198 if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) { 10199 find2 = [{ node: anchor, offset: domSel.anchorOffset }]; 10200 if (!selectionCollapsed(domSel)) 10201 find2.push({ node: domSel.focusNode, offset: domSel.focusOffset }); 10202 } 10203 if (chrome && view.input.lastKeyCode === 8) { 10204 for (let off = toOffset; off > fromOffset; off--) { 10205 let node = parent.childNodes[off - 1], desc = node.pmViewDesc; 10206 if (node.nodeName == "BR" && !desc) { 10207 toOffset = off; 10208 break; 10209 } 10210 if (!desc || desc.size) 10211 break; 10212 } 10213 } 10214 let startDoc = view.state.doc; 10215 let parser = view.someProp("domParser") || DOMParser.fromSchema(view.state.schema); 10216 let $from = startDoc.resolve(from2); 10217 let sel = null, doc2 = parser.parse(parent, { 10218 topNode: $from.parent, 10219 topMatch: $from.parent.contentMatchAt($from.index()), 10220 topOpen: true, 10221 from: fromOffset, 10222 to: toOffset, 10223 preserveWhitespace: $from.parent.type.whitespace == "pre" ? "full" : true, 10224 findPositions: find2, 10225 ruleFromNode, 10226 context: $from 10227 }); 10228 if (find2 && find2[0].pos != null) { 10229 let anchor2 = find2[0].pos, head = find2[1] && find2[1].pos; 10230 if (head == null) 10231 head = anchor2; 10232 sel = { anchor: anchor2 + from2, head: head + from2 }; 10233 } 10234 return { doc: doc2, sel, from: from2, to }; 10235} 10236function ruleFromNode(dom) { 10237 let desc = dom.pmViewDesc; 10238 if (desc) { 10239 return desc.parseRule(); 10240 } else if (dom.nodeName == "BR" && dom.parentNode) { 10241 if (safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) { 10242 let skip = document.createElement("div"); 10243 skip.appendChild(document.createElement("li")); 10244 return { skip }; 10245 } else if (dom.parentNode.lastChild == dom || safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) { 10246 return { ignore: true }; 10247 } 10248 } else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) { 10249 return { ignore: true }; 10250 } 10251 return null; 10252} 10253const isInline = /^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i; 10254function readDOMChange(view, from2, to, typeOver, addedNodes) { 10255 let compositionID = view.input.compositionPendingChanges || (view.composing ? view.input.compositionID : 0); 10256 view.input.compositionPendingChanges = 0; 10257 if (from2 < 0) { 10258 let origin = view.input.lastSelectionTime > Date.now() - 50 ? view.input.lastSelectionOrigin : null; 10259 let newSel = selectionFromDOM(view, origin); 10260 if (newSel && !view.state.selection.eq(newSel)) { 10261 if (chrome && android && view.input.lastKeyCode === 13 && Date.now() - 100 < view.input.lastKeyCodeTime && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) 10262 return; 10263 let tr3 = view.state.tr.setSelection(newSel); 10264 if (origin == "pointer") 10265 tr3.setMeta("pointer", true); 10266 else if (origin == "key") 10267 tr3.scrollIntoView(); 10268 if (compositionID) 10269 tr3.setMeta("composition", compositionID); 10270 view.dispatch(tr3); 10271 } 10272 return; 10273 } 10274 let $before = view.state.doc.resolve(from2); 10275 let shared = $before.sharedDepth(to); 10276 from2 = $before.before(shared + 1); 10277 to = view.state.doc.resolve(to).after(shared + 1); 10278 let sel = view.state.selection; 10279 let parse = parseBetween(view, from2, to); 10280 let doc2 = view.state.doc, compare = doc2.slice(parse.from, parse.to); 10281 let preferredPos, preferredSide; 10282 if (view.input.lastKeyCode === 8 && Date.now() - 100 < view.input.lastKeyCodeTime) { 10283 preferredPos = view.state.selection.to; 10284 preferredSide = "end"; 10285 } else { 10286 preferredPos = view.state.selection.from; 10287 preferredSide = "start"; 10288 } 10289 view.input.lastKeyCode = null; 10290 let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide); 10291 if ((ios && view.input.lastIOSEnter > Date.now() - 225 || android) && addedNodes.some((n) => n.nodeType == 1 && !isInline.test(n.nodeName)) && (!change || change.endA >= change.endB) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) { 10292 view.input.lastIOSEnter = 0; 10293 return; 10294 } 10295 if (!change) { 10296 if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)
10296) { 10297 change = { start: sel.from, endA: sel.to, endB: sel.to }; 10298 } else { 10299 if (parse.sel) { 10300 let sel2 = resolveSelection(view, view.state.doc, parse.sel); 10301 if (sel2 && !sel2.eq(view.state.selection)) { 10302 let tr3 = view.state.tr.setSelection(sel2); 10303 if (compositionID) 10304 tr3.setMeta("composition", compositionID); 10305 view.dispatch(tr3); 10306 } 10307 } 10308 return; 10309 } 10310 } 10311 view.input.domChangeCount++; 10312 if (view.state.selection.from < view.state.selection.to && change.start == change.endB && view.state.selection instanceof TextSelection) { 10313 if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2 && view.state.selection.from >= parse.from) { 10314 change.start = view.state.selection.from; 10315 } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2 && view.state.selection.to <= parse.to) { 10316 change.endB += view.state.selection.to - change.endA; 10317 change.endA = view.state.selection.to; 10318 } 10319 } 10320 if (ie$1 && ie_version <= 11 && change.endB == change.start + 1 && change.endA == change.start && change.start > parse.from && parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == " Â ") { 10321 change.start--; 10322 change.endA--; 10323 change.endB--; 10324 } 10325 let $from = parse.doc.resolveNoCache(change.start - parse.from); 10326 let $to = parse.doc.resolveNoCache(change.endB - parse.from); 10327 let $fromA = doc2.resolve(change.start); 10328 let inlineChange = $from.sameParent($to) && $from.parent.inlineContent && $fromA.end() >= change.endA; 10329 let nextSel; 10330 if ((ios && view.input.lastIOSEnter > Date.now() - 225 && (!inlineChange || addedNodes.some((n) => n.nodeName == "DIV" || n.nodeName == "P")) || !inlineChange && $from.pos < parse.doc.content.size && !$from.sameParent($to) && (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && nextSel.head == $to.pos) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) { 10331 view.input.lastIOSEnter = 0; 10332 return; 10333 } 10334 if (view.state.selection.anchor > change.start && looksLikeBackspace(doc2, change.start, change.endA, $from, $to) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(8, "Backspace")))) { 10335 if (android && chrome) 10336 view.domObserver.suppressSelectionUpdates(); 10337 return; 10338 } 10339 if (chrome && android && change.endB == change.start) 10340 view.input.lastAndroidDelete = Date.now(); 10341 if (android && !inlineChange && $from.start() != $to.start() && $to.parentOffset == 0 && $from.depth == $to.depth && parse.sel && parse.sel.anchor == parse.sel.head && parse.sel.head == change.endA) { 10342 change.endB -= 2; 10343 $to = parse.doc.resolveNoCache(change.endB - parse.from); 10344 setTimeout(() => { 10345 view.someProp("handleKeyDown", function(f) { 10346 return f(view, keyEvent(13, "Enter")); 10347 }); 10348 }, 20); 10349 } 10350 let chFrom = change.start, chTo = change.endA; 10351 let tr2, storedMarks, markChange; 10352 if (inlineChange) { 10353 if ($from.pos == $to.pos) { 10354 if (ie$1 && ie_version <= 11 && $from.parentOffset == 0) { 10355 view.domObserver.suppressSelectionUpdates(); 10356 setTimeout(() => selectionToDOM(view), 20); 10357 } 10358 tr2 = view.state.tr.delete(chFrom, chTo); 10359 storedMarks = doc2.resolve(change.start).marksAcross(doc2.resolve(change.endA)); 10360 } else if ( 10361 // Adding or removing a mark 10362 change.endA == change.endB && (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), $fromA.parent.content.cut($fromA.parentOffset, change.endA - $fromA.start()))) 10363 ) { 10364 tr2 = view.state.tr; 10365 if (markChange.type == "add") 10366 tr2.addMark(chFrom, chTo, markChange.mark); 10367 else 10368 tr2.removeMark(chFrom, chTo, markChange.mark); 10369 } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) { 10370 let text = $from.parent.textBetween($from.parentOffset, $to.parentOffset); 10371 if (view.someProp("handleTextInput", (f) => f(view, chFrom, chTo, text))) 10372 return; 10373 tr2 = view.state.tr.insertText(text, chFrom, chTo); 10374 } 10375 } 10376 if (!tr2) 10377 tr2 = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from,
vendor: 10,871 bytes, lines 10377-10659
10377change.endB - parse.from)); 10378 if (parse.sel) { 10379 let sel2 = resolveSelection(view, tr2.doc, parse.sel); 10380 if (sel2 && !(chrome && android && view.composing && sel2.empty && (change.start != change.endB || view.input.lastAndroidDelete < Date.now() - 100) && (sel2.head == chFrom || sel2.head == tr2.mapping.map(chTo) - 1) || ie$1 && sel2.empty && sel2.head == chFrom)) 10381 tr2.setSelection(sel2); 10382 } 10383 if (storedMarks) 10384 tr2.ensureMarks(storedMarks); 10385 if (compositionID) 10386 tr2.setMeta("composition", compositionID); 10387 view.dispatch(tr2.scrollIntoView()); 10388} 10389function resolveSelection(view, doc2, parsedSel) { 10390 if (Math.max(parsedSel.anchor, parsedSel.head) > doc2.content.size) 10391 return null; 10392 return selectionBetween(view, doc2.resolve(parsedSel.anchor), doc2.resolve(parsedSel.head)); 10393} 10394function isMarkChange(cur, prev) { 10395 let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks; 10396 let added = curMarks, removed = prevMarks, type, mark, update; 10397 for (let i = 0; i < prevMarks.length; i++) 10398 added = prevMarks[i].removeFromSet(added); 10399 for (let i = 0; i < curMarks.length; i++) 10400 removed = curMarks[i].removeFromSet(removed); 10401 if (added.length == 1 && removed.length == 0) { 10402 mark = added[0]; 10403 type = "add"; 10404 update = (node) => node.mark(mark.addToSet(node.marks)); 10405 } else if (added.length == 0 && removed.length == 1) { 10406 mark = removed[0]; 10407 type = "remove"; 10408 update = (node) => node.mark(mark.removeFromSet(node.marks)); 10409 } else { 10410 return null; 10411 } 10412 let updated = []; 10413 for (let i = 0; i < prev.childCount; i++) 10414 updated.push(update(prev.child(i))); 10415 if (Fragment.from(updated).eq(cur)) 10416 return { mark, type }; 10417} 10418function looksLikeBackspace(old, start2, end2, $newStart, $newEnd) { 10419 if ( 10420 // The content must have shrunk 10421 end2 - start2 <= $newEnd.pos - $newStart.pos || // newEnd must point directly at or after the end of the block that newStart points into 10422 skipClosingAndOpening($newStart, true, false) < $newEnd.pos 10423 ) 10424 return false; 10425 let $start = old.resolve(start2); 10426 if (!$newStart.parent.isTextblock) { 10427 let after = $start.nodeAfter; 10428 return after != null && end2 == start2 + after.nodeSize; 10429 } 10430 if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) 10431 return false; 10432 let $next = old.resolve(skipClosingAndOpening($start, true, true)); 10433 if (!$next.parent.isTextblock || $next.pos > end2 || skipClosingAndOpening($next, true, false) < end2) 10434 return false; 10435 return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content); 10436} 10437function skipClosingAndOpening($pos, fromEnd, mayOpen) { 10438 let depth = $pos.depth, end2 = fromEnd ? $pos.end() : $pos.pos; 10439 while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) { 10440 depth--; 10441 end2++; 10442 fromEnd = false; 10443 } 10444 if (mayOpen) { 10445 let next = $pos.node(depth).maybeChild($pos.indexAfter(depth)); 10446 while (next && !next.isLeaf) { 10447 next = next.firstChild; 10448 end2++; 10449 } 10450 } 10451 return end2; 10452} 10453function findDiff(a, b, pos, preferredPos, preferredSide) { 10454 let start2 = a.findDiffStart(b, pos); 10455 if (start2 == null) 10456 return null; 10457 let { a: endA, b: endB } = a.findDiffEnd(b, pos + a.size, pos + b.size); 10458 if (preferredSide == "end") { 10459 let adjust = Math.max(0, start2 - Math.min(endA, endB)); 10460 preferredPos -= endA + adjust - start2; 10461 } 10462 if (endA < start2 && a.size < b.size) { 10463 let move = preferredPos <= start2 && preferredPos >= endA ? start2 - preferredPos : 0; 10464 start2 -= move; 10465 if (start2 && start2 < b.size && isSurrogatePair(b.textBetween(start2 - 1, start2 + 1))) 10466 start2 += move ? 1 : -1; 10467 endB = start2 + (endB - endA); 10468 endA = start2; 10469 } else if (endB < start2) { 10470 let move = preferredPos <= start2 && preferredPos >= endB ? start2 - preferredPos : 0; 10471 start2 -= move; 10472 if (start2 && start2 < a.size && isSurrogatePair(a.textBetween(start2 - 1, start2 + 1))) 10473 start2 += move ? 1 : -1; 10474 endA = start2 + (endA - endB); 10475 endB = start2; 10476 } 10477 return { start: start2, endA, endB }; 10478} 10479function isSurrogatePair(str) { 10480 if (str.length != 2) 10481 return false; 10482 let a = str.charCodeAt(0), b = str.charCodeAt(1); 10483 return a >= 56320 && a <= 57343 && b >= 55296 && b <= 56319; 10484} 10485class EditorView { 10486 /** 10487 Create a view. `place` may be a DOM node that the editor should 10488 be appended to, a function that will place it into the document, 10489 or an object whose `mount` property holds the node to use as the 10490 document container. If it is `null`, the editor will not be 10491 added to the document. 10492 */ 10493 constructor(place, props) { 10494 this._root = null; 10495 this.focused = false; 10496 this.trackWrites = null; 10497 this.mounted = false; 10498 this.markCursor = null; 10499 this.cursorWrapper = null; 10500 this.lastSelectedViewDesc = void 0; 10501 this.input = new InputState(); 10502 this.prevDirectPlugins = []; 10503 this.pluginViews = []; 10504 this.requiresGeckoHackNode = false; 10505 this.dragging = null; 10506 this._props = props; 10507 this.state = props.state; 10508 this.directPlugins = props.plugins || []; 10509 this.directPlugins.forEach(checkStateComponent); 10510 this.dispatch = this.dispatch.bind(this); 10511 this.dom = place && place.mount || document.createElement("div"); 10512 if (place) { 10513 if (place.appendChild) 10514 place.appendChild(this.dom); 10515 else if (typeof place == "function") 10516 place(this.dom); 10517 else if (place.mount) 10518 this.mounted = true; 10519 } 10520 this.editable = getEditable(this); 10521 updateCursorWrapper(this); 10522 this.nodeViews = buildNodeViews(this); 10523 this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this); 10524 this.domObserver = new DOMObserver(this, (from2, to, typeOver, added) => readDOMChange(this, from2, to, typeOver, added)); 10525 this.domObserver.start(); 10526 initInput(this); 10527 this.updatePluginViews(); 10528 } 10529 /** 10530 Holds `true` when a 10531 [composition](https://w3c.github.io/uievents/#events-compositionevents) 10532 is active. 10533 */ 10534 get composing() { 10535 return this.input.composing; 10536 } 10537 /** 10538 The view's current [props](https://prosemirror.net/docs/ref/#view.EditorProps). 10539 */ 10540 get props() { 10541 if (this._props.state != this.state) { 10542 let prev = this._props; 10543 this._props = {}; 10544 for (let name in prev) 10545 this._props[name] = prev[name]; 10546 this._props.state = this.state; 10547 } 10548 return this._props; 10549 } 10550 /** 10551 Update the view's props. Will immediately cause an update to 10552 the DOM. 10553 */ 10554 update(props) { 10555 if (props.handleDOMEvents != this._props.handleDOMEvents) 10556 ensureListeners(this); 10557 let prevProps = this._props; 10558 this._props = props; 10559 if (props.plugins) { 10560 props.plugins.forEach(checkStateComponent); 10561 this.directPlugins = props.plugins; 10562 } 10563 this.updateStateInner(props.state, prevProps); 10564 } 10565 /** 10566 Update the view by updating existing props object with the object 10567 given as argument. Equivalent to `view.update(Object.assign({}, 10568 view.props, props))`. 10569 */ 10570 setProps(props) { 10571 let updated = {}; 10572 for (let name in this._props) 10573 updated[name] = this._props[name]; 10574 updated.state = this.state; 10575 for (let name in props) 10576 updated[name] = props[name]; 10577 this.update(updated); 10578 } 10579 /** 10580 Update the editor's `state` prop, without touching any of the 10581 other props. 10582 */ 10583 updateState(state) { 10584 this.updateStateInner(state, this._props); 10585 } 10586 updateStateInner(state, prevProps) { 10587 var _a; 10588 let prev = this.state, redraw = false, updateSel = false; 10589 if (state.storedMarks && this.composing) { 10590 clearComposition(this); 10591 updateSel = true; 10592 } 10593 this.state = state; 10594 let pluginsChanged = prev.plugins != state.plugins || this._props.plugins != prevProps.plugins; 10595 if (pluginsChanged || this._props.plugins != prevProps.plugins || this._props.nodeViews != prevProps.nodeViews) { 10596 let nodeViews = buildNodeViews(this); 10597 if (changedNodeViews(nodeViews, this.nodeViews)) { 10598 this.nodeViews = nodeViews; 10599 redraw = true; 10600 } 10601 } 10602 if (pluginsChanged || prevProps.handleDOMEvents != this._props.handleDOMEvents) { 10603 ensureListeners(this); 10604 } 10605 this.editable = getEditable(this); 10606 updateCursorWrapper(this); 10607 let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this); 10608 let scroll = prev.plugins != state.plugins && !prev.doc.eq(state.doc) ? "reset" : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve"; 10609 let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco); 10610 if (updateDoc || !state.selection.eq(prev.selection)) 10611 updateSel = true; 10612 let oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this); 10613 if (updateSel) { 10614 this.domObserver.stop(); 10615 let forceSelUpdate = updateDoc && (ie$1 || chrome) && !this.composing && !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection); 10616 if (updateDoc) { 10617 let chromeKludge = chrome ? this.trackWrites = this.domSelectionRange().focusNode : null; 10618 if (this.composing) 10619 this.input.compositionNode = findCompositionNode(this); 10620 if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) { 10621 this.docView.updateOuterDeco(outerDeco); 10622 this.docView.destroy(); 10623 this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this); 10624 } 10625 if (chromeKludge && !this.trackWrites) 10626 forceSelUpdate = true; 10627 } 10628 if (forceSelUpdate || !(this.input.mouseDown && this.domObserver.currentSelection.eq(this.domSelectionRange()) && anchorInRightPlace(this))) { 10629 selectionToDOM(this, forceSelUpdate); 10630 } else { 10631 syncNodeSelection(this, state.selection); 10632 this.domObserver.setCurSelection(); 10633 } 10634 this.domObserver.start(); 10635 } 10636 this.updatePluginViews(prev); 10637 if (((_a = this.dragging) === null || _a === void 0 ? void 0 : _a.node) && !prev.doc.eq(state.doc)) 10638 this.updateDraggedNode(this.dragging, prev); 10639 if (scroll == "reset") { 10640 this.dom.scrollTop = 0; 10641 } else if (scroll == "to selection") { 10642 this.scrollToSelection(); 10643 } else if (oldScrollPos) { 10644 resetScrollPos(oldScrollPos); 10645 } 10646 } 10647 /** 10648 @internal 10649 */ 10650 scrollToSelection() { 10651 let startDOM = this.domSelectionRange().focusNode; 10652 if (this.someProp("handleScrollToSelection", (f) => f(this))) 10653 ; 10654 else if (this.state.selection instanceof NodeSelection) { 10655 let target = this.docView.domAfterPos(this.state.selection.from); 10656 if (target.nodeType == 1) 10657 scrollRectIntoView(this, target.getBoundingClientRect(), startDOM); 10658 } else { 10659 scrollRectIntoView(this, this.coordsAtPos(this.state.selection.head, 1
vendor: 8,121 bytes, lines 10659-10894
10659), startDOM); 10660 } 10661 } 10662 destroyPluginViews() { 10663 let view; 10664 while (view = this.pluginViews.pop()) 10665 if (view.destroy) 10666 view.destroy(); 10667 } 10668 updatePluginViews(prevState) { 10669 if (!prevState || prevState.plugins != this.state.plugins || this.directPlugins != this.prevDirectPlugins) { 10670 this.prevDirectPlugins = this.directPlugins; 10671 this.destroyPluginViews(); 10672 for (let i = 0; i < this.directPlugins.length; i++) { 10673 let plugin = this.directPlugins[i]; 10674 if (plugin.spec.view) 10675 this.pluginViews.push(plugin.spec.view(this)); 10676 } 10677 for (let i = 0; i < this.state.plugins.length; i++) { 10678 let plugin = this.state.plugins[i]; 10679 if (plugin.spec.view) 10680 this.pluginViews.push(plugin.spec.view(this)); 10681 } 10682 } else { 10683 for (let i = 0; i < this.pluginViews.length; i++) { 10684 let pluginView = this.pluginViews[i]; 10685 if (pluginView.update) 10686 pluginView.update(this, prevState); 10687 } 10688 } 10689 } 10690 updateDraggedNode(dragging, prev) { 10691 let sel = dragging.node, found2 = -1; 10692 if (this.state.doc.nodeAt(sel.from) == sel.node) { 10693 found2 = sel.from; 10694 } else { 10695 let movedPos = sel.from + (this.state.doc.content.size - prev.doc.content.size); 10696 let moved = movedPos > 0 && this.state.doc.nodeAt(movedPos); 10697 if (moved == sel.node) 10698 found2 = movedPos; 10699 } 10700 this.dragging = new Dragging(dragging.slice, dragging.move, found2 < 0 ? void 0 : NodeSelection.create(this.state.doc, found2)); 10701 } 10702 someProp(propName, f) { 10703 let prop = this._props && this._props[propName], value; 10704 if (prop != null && (value = f ? f(prop) : prop)) 10705 return value; 10706 for (let i = 0; i < this.directPlugins.length; i++) { 10707 let prop2 = this.directPlugins[i].props[propName]; 10708 if (prop2 != null && (value = f ? f(prop2) : prop2)) 10709 return value; 10710 } 10711 let plugins = this.state.plugins; 10712 if (plugins) 10713 for (let i = 0; i < plugins.length; i++) { 10714 let prop2 = plugins[i].props[propName]; 10715 if (prop2 != null && (value = f ? f(prop2) : prop2)) 10716 return value; 10717 } 10718 } 10719 /** 10720 Query whether the view has focus. 10721 */ 10722 hasFocus() { 10723 if (ie$1) { 10724 let node = this.root.activeElement; 10725 if (node == this.dom) 10726 return true; 10727 if (!node || !this.dom.contains(node)) 10728 return false; 10729 while (node && this.dom != node && this.dom.contains(node)) { 10730 if (node.contentEditable == "false") 10731 return false; 10732 node = node.parentElement; 10733 } 10734 return true; 10735 } 10736 return this.root.activeElement == this.dom; 10737 } 10738 /** 10739 Focus the editor. 10740 */ 10741 focus() { 10742 this.domObserver.stop(); 10743 if (this.editable) 10744 focusPreventScroll(this.dom); 10745 selectionToDOM(this); 10746 this.domObserver.start(); 10747 } 10748 /** 10749 Get the document root in which the editor exists. This will 10750 usually be the top-level `document`, but might be a [shadow 10751 DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM) 10752 root if the editor is inside one. 10753 */ 10754 get root() { 10755 let cached = this._root; 10756 if (cached == null) 10757 for (let search = this.dom.parentNode; search; search = search.parentNode) { 10758 if (search.nodeType == 9 || search.nodeType == 11 && search.host) { 10759 if (!search.getSelection) 10760 Object.getPrototypeOf(search).getSelection = () => search.ownerDocument.getSelection(); 10761 return this._root = search; 10762 } 10763 } 10764 return cached || document; 10765 } 10766 /** 10767 When an existing editor view is moved to a new document or 10768 shadow tree, call this to make it recompute its root. 10769 */ 10770 updateRoot() { 10771 this._root = null; 10772 } 10773 /** 10774 Given a pair of viewport coordinates, return the document 10775 position that corresponds to them. May return null if the given 10776 coordinates aren't inside of the editor. When an object is 10777 returned, its `pos` property is the position nearest to the 10778 coordinates, and its `inside` property holds the position of the 10779 inner node that the position falls inside of, or -1 if it is at 10780 the top level, not in any node. 10781 */ 10782 posAtCoords(coords) { 10783 return posAtCoords(this, coords); 10784 } 10785 /** 10786 Returns the viewport rectangle at a given document position. 10787 `left` and `right` will be the same number, as this returns a 10788 flat cursor-ish rectangle. If the position is between two things 10789 that aren't directly adjacent, `side` determines which element 10790 is used. When < 0, the element before the position is used, 10791 otherwise the element after. 10792 */ 10793 coordsAtPos(pos, side = 1) { 10794 return coordsAtPos(this, pos, side); 10795 } 10796 /** 10797 Find the DOM position that corresponds to the given document 10798 position. When `side` is negative, find the position as close as 10799 possible to the content before the position. When positive, 10800 prefer positions close to the content after the position. When 10801 zero, prefer as shallow a position as possible. 10802 10803 Note that you should **not** mutate the editor's internal DOM, 10804 only inspect it (and even that is usually not necessary). 10805 */ 10806 domAtPos(pos, side = 0) { 10807 return this.docView.domFromPos(pos, side); 10808 } 10809 /** 10810 Find the DOM node that represents the document node after the 10811 given position. May return `null` when the position doesn't point 10812 in front of a node or if the node is inside an opaque node view. 10813 10814 This is intended to be able to call things like 10815 `getBoundingClientRect` on that DOM node. Do **not** mutate the 10816 editor DOM directly, or add styling this way, since that will be 10817 immediately overriden by the editor as it redraws the node. 10818 */ 10819 nodeDOM(pos) { 10820 let desc = this.docView.descAt(pos); 10821 return desc ? desc.nodeDOM : null; 10822 } 10823 /** 10824 Find the document position that corresponds to a given DOM 10825 position. (Whenever possible, it is preferable to inspect the 10826 document structure directly, rather than poking around in the 10827 DOM, but sometimesâfor example when interpreting an event 10828 targetâyou don't have a choice.) 10829 10830 The `bias` parameter can be used to influence which side of a DOM 10831 node to use when the position is inside a leaf node. 10832 */ 10833 posAtDOM(node, offset2, bias = -1) { 10834 let pos = this.docView.posFromDOM(node, offset2, bias); 10835 if (pos == null) 10836 throw new RangeError("DOM position not inside the editor"); 10837 return pos; 10838 } 10839 /** 10840 Find out whether the selection is at the end of a textblock when 10841 moving in a given direction. When, for example, given `"left"`, 10842 it will return true if moving left from the current cursor 10843 position would leave that position's parent textblock. Will apply 10844 to the view's current state by default, but it is possible to 10845 pass a different state. 10846 */ 10847 endOfTextblock(dir, state) { 10848 return endOfTextblock(this, state || this.state, dir); 10849 } 10850 /** 10851 Run the editor's paste logic with the given HTML string. The 10852 `event`, if given, will be passed to the 10853 [`handlePaste`](https://prosemirror.net/docs/ref/#view.EditorProps.handlePaste) hook. 10854 */ 10855 pasteHTML(html, event) { 10856 return doPaste(this, "", html, false, event || new ClipboardEvent("paste")); 10857 } 10858 /** 10859 Run the editor's paste logic with the given plain-text input. 10860 */ 10861 pasteText(text, event) { 10862 return doPaste(this, text, null, true, event || new ClipboardEvent("paste")); 10863 } 10864 /** 10865 Removes the editor from the DOM and destroys all [node 10866 views](https://prosemirror.net/docs/ref/#view.NodeView). 10867 */ 10868 destroy() { 10869 if (!this.docView) 10870 return; 10871 destroyInput(this); 10872 this.destroyPluginViews(); 10873 if (this.mounted) { 10874 this.docView.update(this.state.doc, [], viewDecorations(this), this); 10875 this.dom.textContent = ""; 10876 } else if (this.dom.parentNode) { 10877 this.dom.parentNode.removeChild(this.dom); 10878 } 10879 this.docView.destroy(); 10880 this.docView = null; 10881 clearReusedRange(); 10882 } 10883 /** 10884 This is true when the view has been 10885 [destroyed](https://prosemirror.net/docs/ref/#view.EditorView.destroy) (and thus should not be 10886 used anymore). 10887 */ 10888 get isDestroyed() { 10889 return this.docView == null; 10890 } 10891 /** 10892 Used for testing. 10893 */ 10894 dispatchEvent(event) {
10895 return dispatchEvent(this, event); 10896 } 10897 /** 10898 Dispatch a transaction. Will call 10899 [`dispatchTransaction`](https://prosemirror.net/docs/ref/#view.DirectEditorProps.dispatchTransaction) 10900 when given, and otherwise defaults to applying the transaction to 10901 the current state and calling 10902 [`updateState`](https://prosemirror.net/docs/ref/#view.EditorView.updateState) with the result. 10903 This method is bound to the view instance, so that it can be 10904 easily passed around. 10905 */ 10906 dispatch(tr2) { 10907 let dispatchTransaction = this._props.dispatchTransaction; 10908 if (dispatchTransaction) 10909 dispatchTransaction.call(this, tr2); 10910 else 10911 this.updateState(this.state.apply(tr2)); 10912 } 10913 /** 10914 @internal 10915 */ 10916 domSelectionRange() { 10917 let sel = this.domSelection(); 10918 return safari && this.root.nodeType === 11 && deepActiveElement(this.dom.ownerDocument) == this.dom && safariShadowSelectionRange(this, sel) || sel; 10919 } 10920 /** 10921 @internal 10922 */ 10923 domSelection() { 10924 return this.root.getSelection(); 10925 } 10926} 10927function computeDocDeco(view) { 10928 let attrs = /* @__PURE__ */ Object.create(null); 10929 attrs.class = "ProseMirror"; 10930 attrs.contenteditable = String(view.editable); 10931 view.someProp("attributes", (value) => { 10932 if (typeof value == "function") 10933 value = value(view.state); 10934 if (value) 10935 for (let attr in value) { 10936 if (attr == "class") 10937 attrs.class += " " + value[attr]; 10938 else if (attr == "style") 10939 attrs.style = (attrs.style ? attrs.style + ";" : "") + value[attr]; 10940 else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") 10941 attrs[attr] = String(value[attr]); 10942 } 10943 }); 10944 if (!attrs.translate) 10945 attrs.translate = "no"; 10946 return [Decoration.node(0, view.state.doc.content.size, attrs)]; 10947} 10948function updateCursorWrapper(view) { 10949 if (view.markCursor) { 10950 let dom = document.createElement("img"); 10951 dom.className = "ProseMirror-separator"; 10952 dom.setAttribute("mark-placeholder", "true"); 10953 dom.setAttribute("alt", ""); 10954 view.cursorWrapper = { dom, deco: Decoration.widget(view.state.selection.head, dom, { raw: true, marks: view.markCursor }) }; 10955 } else { 10956 view.cursorWrapper = null; 10957 } 10958} 10959function getEditable(view) { 10960 return !view.someProp("editable", (value) => value(view.state) === false); 10961} 10962function selectionContextChanged(sel1, sel2) { 10963 let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head)); 10964 return sel1.$anchor.start(depth) != sel2.$anchor.start(depth); 10965} 10966function buildNodeViews(view) { 10967 let result = /* @__PURE__ */ Object.create(null); 10968 function add(obj) { 10969 for (let prop in obj) 10970 if (!Object.prototype.hasOwnProperty.call(result, prop)) 10971 result[prop] = obj[prop]; 10972 } 10973 view.someProp("nodeViews", add); 10974 view.someProp("markViews", add); 10975 return result; 10976} 10977function changedNodeViews(a, b) { 10978 let nA = 0, nB = 0; 10979 for (let prop in a) { 10980 if (a[prop] != b[prop]) 10981 return true; 10982 nA++; 10983 } 10984 for (let _ in b) 10985 nB++; 10986 return nA != nB; 10987} 10988function checkStateComponent(plugin) { 10989 if (plugin.spec.state || plugin.spec.filterTransaction || plugin.spec.appendTransaction) 10990 throw new RangeError("Plugins passed directly to the view must not have a state component"); 10991} 10992var base = { 10993 8: "Backspace", 10994 9: "Tab", 10995 10: "Enter", 10996 12: "NumLock", 10997 13: "Enter", 10998 16: "Shift", 10999 17: "Control", 11000 18: "Alt", 11001 20: "CapsLock", 11002 27: "Escape", 11003 32: " ", 11004 33: "PageUp", 11005 34: "PageDown", 11006 35: "End", 11007 36: "Home", 11008 37: "ArrowLeft", 11009 38: "ArrowUp", 11010 39: "ArrowRight", 11011 40: "ArrowDown", 11012 44: "PrintScreen", 11013 45: "Insert", 11014 46: "Delete", 11015 59: ";", 11016 61: "=", 11017 91: "Meta", 11018 92: "Meta", 11019 106: "*", 11020 107: "+", 11021 108: ",", 11022 109: "-", 11023 110: ".", 11024 111: "/", 11025 144: "NumLock", 11026 145: "ScrollLock", 11027 160: "Shift", 11028 161: "Shift", 11029 162: "Control", 11030 163: "Control", 11031 164: "Alt", 11032 165: "Alt", 11033 173: "-", 11034 186: ";", 11035 187: "=", 11036 188: ",", 11037 189: "-", 11038 190: ".", 11039 191: "/", 11040 192: "`", 11041 219: "[", 11042 220: "\\", 11043 221: "]", 11044 222: "'" 11045}; 11046var shift = { 11047 48: ")", 11048 49: "!", 11049 50: "@", 11050 51: "#", 11051 52: "$", 11052 53: "%", 11053 54: "^", 11054 55: "&", 11055 56: "*", 11056 57: "(", 11057 59: ":", 11058 61: "+", 11059 173: "_", 11060 186: ":", 11061 187: "+", 11062 188: "<", 11063 189: "_", 11064 190: ">", 11065 191: "?", 11066 192: "~", 11067 219: "{", 11068 220: "|", 11069 221: "}", 11070 222: '"' 11071}; 11072var mac$1 = typeof navigator != "undefined" && /Mac/.test(navigator.platform); 11073var ie = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); 11074for (var i = 0; i < 10; i++) 11075 base[48 + i] = base[96 + i] = String(i); 11076for (var i = 1; i <= 24; i++) 11077 base[i + 111] = "F" + i; 11078for (var i = 65; i <= 90; i++) { 11079 base[i] = String.fromCharCode(i + 32); 11080 shift[i] = String.fromCharCode(i); 11081} 11082for (var code in base) 11083 if (!shift.hasOwnProperty(code)) 11084 shift[code] = base[code]; 11085function keyName(event) { 11086 var ignoreKey = mac$1 && event.metaKey && event.shiftKey && !event.ctrlKey && !event.altKey || ie && event.shiftKey && event.key && event.key.length == 1 || event.key == "Unidentified"; 11087 var name = !ignoreKey && event.key || (event.shiftKey ? shift : base)[event.keyCode] || event.key || "Unidentified"; 11088 if (name == "Esc") 11089 name = "Escape"; 11090 if (name == "Del") 11091 name = "Delete"; 11092 if (name == "Left") 11093 name = "ArrowLeft"; 11094 if (name == "Up") 11095 name = "ArrowUp"; 11096 if (name == "Right") 11097 name = "ArrowRight"; 11098 if (name == "Down") 11099 name = "ArrowDown"; 11100 return name; 11101} 11102const mac = typeof navigator != "undefined" ? /Mac|iP(hone|[oa]d)/.test(navigator.platform) : false;
vendor: 1,438 bytes, lines 11103-11156
11103function normalizeKeyName$1(name) { 11104 let parts = name.split(/-(?!$)/), result = parts[parts.length - 1]; 11105 if (result == "Space") 11106 result = " "; 11107 let alt, ctrl, shift2, meta; 11108 for (let i = 0; i < parts.length - 1; i++) { 11109 let mod = parts[i]; 11110 if (/^(cmd|meta|m)$/i.test(mod)) 11111 meta = true; 11112 else if (/^a(lt)?$/i.test(mod)) 11113 alt = true; 11114 else if (/^(c|ctrl|control)$/i.test(mod)) 11115 ctrl = true; 11116 else if (/^s(hift)?$/i.test(mod)) 11117 shift2 = true; 11118 else if (/^mod$/i.test(mod)) { 11119 if (mac) 11120 meta = true; 11121 else 11122 ctrl = true; 11123 } else 11124 throw new Error("Unrecognized modifier name: " + mod); 11125 } 11126 if (alt) 11127 result = "Alt-" + result; 11128 if (ctrl) 11129 result = "Ctrl-" + result; 11130 if (meta) 11131 result = "Meta-" + result; 11132 if (shift2) 11133 result = "Shift-" + result; 11134 return result; 11135} 11136function normalize(map2) { 11137 let copy2 = /* @__PURE__ */ Object.create(null); 11138 for (let prop in map2) 11139 copy2[normalizeKeyName$1(prop)] = map2[prop]; 11140 return copy2; 11141} 11142function modifiers(name, event, shift2 = true) { 11143 if (event.altKey) 11144 name = "Alt-" + name; 11145 if (event.ctrlKey) 11146 name = "Ctrl-" + name; 11147 if (event.metaKey) 11148 name = "Meta-" + name; 11149 if (shift2 && event.shiftKey) 11150 name = "Shift-" + name; 11151 return name; 11152} 11153function keymap(bindings) { 11154 return new Plugin({ props: { handleKeyDown: keydownHandler(bindings) } }); 11155} 11156function keydownHandler(bindings) {
vendor: 4,243 bytes, lines 11157-11272
11157 let map2 = normalize(bindings); 11158 return function(view, event) { 11159 let name = keyName(event), baseName, direct = map2[modifiers(name, event)]; 11160 if (direct && direct(view.state, view.dispatch, view)) 11161 return true; 11162 if (name.length == 1 && name != " ") { 11163 if (event.shiftKey) { 11164 let noShift = map2[modifiers(name, event, false)]; 11165 if (noShift && noShift(view.state, view.dispatch, view)) 11166 return true; 11167 } 11168 if ((event.shiftKey || event.altKey || event.metaKey || name.charCodeAt(0) > 127) && (baseName = base[event.keyCode]) && baseName != name) { 11169 let fromCode = map2[modifiers(baseName, event)]; 11170 if (fromCode && fromCode(view.state, view.dispatch, view)) 11171 return true; 11172 } 11173 } 11174 return false; 11175 }; 11176} 11177const deleteSelection$1 = (state, dispatch) => { 11178 if (state.selection.empty) 11179 return false; 11180 if (dispatch) 11181 dispatch(state.tr.deleteSelection().scrollIntoView()); 11182 return true; 11183}; 11184function atBlockStart(state, view) { 11185 let { $cursor } = state.selection; 11186 if (!$cursor || (view ? !view.endOfTextblock("backward", state) : $cursor.parentOffset > 0)) 11187 return null; 11188 return $cursor; 11189} 11190const joinBackward$1 = (state, dispatch, view) => { 11191 let $cursor = atBlockStart(state, view); 11192 if (!$cursor) 11193 return false; 11194 let $cut = findCutBefore($cursor); 11195 if (!$cut) { 11196 let range = $cursor.blockRange(), target = range && liftTarget(range); 11197 if (target == null) 11198 return false; 11199 if (dispatch) 11200 dispatch(state.tr.lift(range, target).scrollIntoView()); 11201 return true; 11202 } 11203 let before = $cut.nodeBefore; 11204 if (!before.type.spec.isolating && deleteBarrier(state, $cut, dispatch)) 11205 return true; 11206 if ($cursor.parent.content.size == 0 && (textblockAt(before, "end") || NodeSelection.isSelectable(before))) { 11207 let delStep = replaceStep(state.doc, $cursor.before(), $cursor.after(), Slice.empty); 11208 if (delStep && delStep.slice.size < delStep.to - delStep.from) { 11209 if (dispatch) { 11210 let tr2 = state.tr.step(delStep); 11211 tr2.setSelection(textblockAt(before, "end") ? Selection.findFrom(tr2.doc.resolve(tr2.mapping.map($cut.pos, -1)), -1) : NodeSelection.create(tr2.doc, $cut.pos - before.nodeSize)); 11212 dispatch(tr2.scrollIntoView()); 11213 } 11214 return true; 11215 } 11216 } 11217 if (before.isAtom && $cut.depth == $cursor.depth - 1) { 11218 if (dispatch) 11219 dispatch(state.tr.delete($cut.pos - before.nodeSize, $cut.pos).scrollIntoView()); 11220 return true; 11221 } 11222 return false; 11223}; 11224const joinTextblockBackward$1 = (state, dispatch, view) => { 11225 let $cursor = atBlockStart(state, view); 11226 if (!$cursor) 11227 return false; 11228 let $cut = findCutBefore($cursor); 11229 return $cut ? joinTextblocksAround(state, $cut, dispatch) : false; 11230}; 11231const joinTextblockForward$1 = (state, dispatch, view) => { 11232 let $cursor = atBlockEnd(state, view); 11233 if (!$cursor) 11234 return false; 11235 let $cut = findCutAfter($cursor); 11236 return $cut ? joinTextblocksAround(state, $cut, dispatch) : false; 11237}; 11238function joinTextblocksAround(state, $cut, dispatch) { 11239 let before = $cut.nodeBefore, beforeText = before, beforePos = $cut.pos - 1; 11240 for (; !beforeText.isTextblock; beforePos--) { 11241 if (beforeText.type.spec.isolating) 11242 return false; 11243 let child = beforeText.lastChild; 11244 if (!child) 11245 return false; 11246 beforeText = child; 11247 } 11248 let after = $cut.nodeAfter, afterText = after, afterPos = $cut.pos + 1; 11249 for (; !afterText.isTextblock; afterPos++) { 11250 if (afterText.type.spec.isolating) 11251 return false; 11252 let child = afterText.firstChild; 11253 if (!child) 11254 return false; 11255 afterText = child; 11256 } 11257 let step = replaceStep(state.doc, beforePos, afterPos, Slice.empty); 11258 if (!step || step.from != beforePos || step instanceof ReplaceStep && step.slice.size >= afterPos - beforePos) 11259 return false; 11260 if (dispatch) { 11261 let tr2 = state.tr.step(step); 11262 tr2.setSelection(TextSelection.create(tr2.doc, beforePos)); 11263 dispatch(tr2.scrollIntoView()); 11264 } 11265 return true; 11266} 11267function textblockAt(node, side, only = false) { 11268 for (let scan = node; scan; scan = side == "start" ? scan.firstChild : scan.lastChild) { 11269 if (scan.isTextblock) 11270 return true; 11271 if (only && scan.childCount != 1) 11272 return false;
vendor: 16,846 bytes, lines 11273-11710
11273 } 11274 return false; 11275} 11276const selectNodeBackward$1 = (state, dispatch, view) => { 11277 let { $head, empty: empty2 } = state.selection, $cut = $head; 11278 if (!empty2) 11279 return false; 11280 if ($head.parent.isTextblock) { 11281 if (view ? !view.endOfTextblock("backward", state) : $head.parentOffset > 0) 11282 return false; 11283 $cut = findCutBefore($head); 11284 } 11285 let node = $cut && $cut.nodeBefore; 11286 if (!node || !NodeSelection.isSelectable(node)) 11287 return false; 11288 if (dispatch) 11289 dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos - node.nodeSize)).scrollIntoView()); 11290 return true; 11291}; 11292function findCutBefore($pos) { 11293 if (!$pos.parent.type.spec.isolating) 11294 for (let i = $pos.depth - 1; i >= 0; i--) { 11295 if ($pos.index(i) > 0) 11296 return $pos.doc.resolve($pos.before(i + 1)); 11297 if ($pos.node(i).type.spec.isolating) 11298 break; 11299 } 11300 return null; 11301} 11302function atBlockEnd(state, view) { 11303 let { $cursor } = state.selection; 11304 if (!$cursor || (view ? !view.endOfTextblock("forward", state) : $cursor.parentOffset < $cursor.parent.content.size)) 11305 return null; 11306 return $cursor; 11307} 11308const joinForward$1 = (state, dispatch, view) => { 11309 let $cursor = atBlockEnd(state, view); 11310 if (!$cursor) 11311 return false; 11312 let $cut = findCutAfter($cursor); 11313 if (!$cut) 11314 return false; 11315 let after = $cut.nodeAfter; 11316 if (deleteBarrier(state, $cut, dispatch)) 11317 return true; 11318 if ($cursor.parent.content.size == 0 && (textblockAt(after, "start") || NodeSelection.isSelectable(after))) { 11319 let delStep = replaceStep(state.doc, $cursor.before(), $cursor.after(), Slice.empty); 11320 if (delStep && delStep.slice.size < delStep.to - delStep.from) { 11321 if (dispatch) { 11322 let tr2 = state.tr.step(delStep); 11323 tr2.setSelection(textblockAt(after, "start") ? Selection.findFrom(tr2.doc.resolve(tr2.mapping.map($cut.pos)), 1) : NodeSelection.create(tr2.doc, tr2.mapping.map($cut.pos))); 11324 dispatch(tr2.scrollIntoView()); 11325 } 11326 return true; 11327 } 11328 } 11329 if (after.isAtom && $cut.depth == $cursor.depth - 1) { 11330 if (dispatch) 11331 dispatch(state.tr.delete($cut.pos, $cut.pos + after.nodeSize).scrollIntoView()); 11332 return true; 11333 } 11334 return false; 11335}; 11336const selectNodeForward$1 = (state, dispatch, view) => { 11337 let { $head, empty: empty2 } = state.selection, $cut = $head; 11338 if (!empty2) 11339 return false; 11340 if ($head.parent.isTextblock) { 11341 if (view ? !view.endOfTextblock("forward", state) : $head.parentOffset < $head.parent.content.size) 11342 return false; 11343 $cut = findCutAfter($head); 11344 } 11345 let node = $cut && $cut.nodeAfter; 11346 if (!node || !NodeSelection.isSelectable(node)) 11347 return false; 11348 if (dispatch) 11349 dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos)).scrollIntoView()); 11350 return true; 11351}; 11352function findCutAfter($pos) { 11353 if (!$pos.parent.type.spec.isolating) 11354 for (let i = $pos.depth - 1; i >= 0; i--) { 11355 let parent = $pos.node(i); 11356 if ($pos.index(i) + 1 < parent.childCount) 11357 return $pos.doc.resolve($pos.after(i + 1)); 11358 if (parent.type.spec.isolating) 11359 break; 11360 } 11361 return null; 11362} 11363const joinUp$1 = (state, dispatch) => { 11364 let sel = state.selection, nodeSel = sel instanceof NodeSelection, point; 11365 if (nodeSel) { 11366 if (sel.node.isTextblock || !canJoin(state.doc, sel.from)) 11367 return false; 11368 point = sel.from; 11369 } else { 11370 point = joinPoint(state.doc, sel.from, -1); 11371 if (point == null) 11372 return false; 11373 } 11374 if (dispatch) { 11375 let tr2 = state.tr.join(point); 11376 if (nodeSel) 11377 tr2.setSelection(NodeSelection.create(tr2.doc, point - state.doc.resolve(point).nodeBefore.nodeSize)); 11378 dispatch(tr2.scrollIntoView()); 11379 } 11380 return true; 11381}; 11382const joinDown$1 = (state, dispatch) => { 11383 let sel = state.selection, point; 11384 if (sel instanceof NodeSelection) { 11385 if (sel.node.isTextblock || !canJoin(state.doc, sel.to)) 11386 return false; 11387 point = sel.to; 11388 } else { 11389 point = joinPoint(state.doc, sel.to, 1); 11390 if (point == null) 11391 return false; 11392 } 11393 if (dispatch) 11394 dispatch(state.tr.join(point).scrollIntoView()); 11395 return true; 11396}; 11397const lift$1 = (state, dispatch) => { 11398 let { $from, $to } = state.selection; 11399 let range = $from.blockRange($to), target = range && liftTarget(range); 11400 if (target == null) 11401 return false; 11402 if (dispatch) 11403 dispatch(state.tr.lift(range, target).scrollIntoView()); 11404 return true; 11405}; 11406const newlineInCode$1 = (state, dispatch) => { 11407 let { $head, $anchor } = state.selection; 11408 if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) 11409 return false; 11410 if (dispatch) 11411 dispatch(state.tr.insertText("\n").scrollIntoView()); 11412 return true; 11413}; 11414function defaultBlockAt$1(match) { 11415 for (let i = 0; i < match.edgeCount; i++) { 11416 let { type } = match.edge(i); 11417 if (type.isTextblock && !type.hasRequiredAttrs()) 11418 return type; 11419 } 11420 return null; 11421} 11422const exitCode$1 = (state, dispatch) => { 11423 let { $head, $anchor } = state.selection; 11424 if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) 11425 return false; 11426 let above = $head.node(-1), after = $head.indexAfter(-1), type = defaultBlockAt$1(above.contentMatchAt(after)); 11427 if (!type || !above.canReplaceWith(after, after, type)) 11428 return false; 11429 if (dispatch) { 11430 let pos = $head.after(), tr2 = state.tr.replaceWith(pos, pos, type.createAndFill()); 11431 tr2.setSelection(Selection.near(tr2.doc.resolve(pos), 1)); 11432 dispatch(tr2.scrollIntoView()); 11433 } 11434 return true; 11435}; 11436const createParagraphNear$1 = (state, dispatch) => { 11437 let sel = state.selection, { $from, $to } = sel; 11438 if (sel instanceof AllSelection || $from.parent.inlineContent || $to.parent.inlineContent) 11439 return false; 11440 let type = defaultBlockAt$1($to.parent.contentMatchAt($to.indexAfter())); 11441 if (!type || !type.isTextblock) 11442 return false; 11443 if (dispatch) { 11444 let side = (!$from.parentOffset && $to.index() < $to.parent.childCount ? $from : $to).pos; 11445 let tr2 = state.tr.insert(side, type.createAndFill()); 11446 tr2.setSelection(TextSelection.create(tr2.doc, side + 1)); 11447 dispatch(tr2.scrollIntoView()); 11448 } 11449 return true; 11450}; 11451const liftEmptyBlock$1 = (state, dispatch) => { 11452 let { $cursor } = state.selection; 11453 if (!$cursor || $cursor.parent.content.size) 11454 return false; 11455 if ($cursor.depth > 1 && $cursor.after() != $cursor.end(-1)) { 11456 let before = $cursor.before(); 11457 if (canSplit(state.doc, before)) { 11458 if (dispatch) 11459 dispatch(state.tr.split(before).scrollIntoView()); 11460 return true; 11461 } 11462 } 11463 let range = $cursor.blockRange(), target = range && liftTarget(range); 11464 if (target == null) 11465 return false; 11466 if (dispatch) 11467 dispatch(state.tr.lift(range, target).scrollIntoView()); 11468 return true; 11469}; 11470const selectParentNode$1 = (state, dispatch) => { 11471 let { $from, to } = state.selection, pos; 11472 let same = $from.sharedDepth(to); 11473 if (same == 0) 11474 return false; 11475 pos = $from.before(same); 11476 if (dispatch) 11477 dispatch(state.tr.setSelection(NodeSelection.create(state.doc, pos))); 11478 return true; 11479}; 11480function joinMaybeClear(state, $pos, dispatch) { 11481 let before = $pos.nodeBefore, after = $pos.nodeAfter, index = $pos.index(); 11482 if (!before || !after || !before.type.compatibleContent(after.type)) 11483 return false; 11484 if (!before.content.size && $pos.parent.canReplace(index - 1, index)) { 11485 if (dispatch) 11486 dispatch(state.tr.delete($pos.pos - before.nodeSize, $pos.pos).scrollIntoView()); 11487 return true; 11488 } 11489 if (!$pos.parent.canReplace(index, index + 1) || !(after.isTextblock || canJoin(state.doc, $pos.pos))) 11490 return false; 11491 if (dispatch) 11492 dispatch(state.tr.clearIncompatible($pos.pos, before.type, before.contentMatchAt(before.childCount)).join($pos.pos).scrollIntoView()); 11493 return true; 11494} 11495function deleteBarrier(state, $cut, dispatch) { 11496 let before = $cut.nodeBefore, after = $cut.nodeAfter, conn, match; 11497 if (before.type.spec.isolating || after.type.spec.isolating) 11498 return false; 11499 if (joinMaybeClear(state, $cut, dispatch)) 11500 return true; 11501 let canDelAfter = $cut.parent.canReplace($cut.index(), $cut.index() + 1); 11502 if (canDelAfter && (conn = (match = before.contentMatchAt(before.childCount)).findWrapping(after.type)) && match.matchType(conn[0] || after.type).validEnd) { 11503 if (dispatch) { 11504 let end2 = $cut.pos + after.nodeSize, wrap2 = Fragment.empty; 11505 for (let i = conn.length - 1; i >= 0; i--) 11506 wrap2 = Fragment.from(conn[i].create(null, wrap2)); 11507 wrap2 = Fragment.from(before.copy(wrap2)); 11508 let tr2 = state.tr.step(new ReplaceAroundStep($cut.pos - 1, end2, $cut.pos, end2, new Slice(wrap2, 1, 0), conn.length, true)); 11509 let joinAt = end2 + 2 * conn.length; 11510 if (canJoin(tr2.doc, joinAt)) 11511 tr2.join(joinAt); 11512 dispatch(tr2.scrollIntoView()); 11513 } 11514 return true; 11515 } 11516 let selAfter = Selection.findFrom($cut, 1); 11517 let range = selAfter && selAfter.$from.blockRange(selAfter.$to), target = range && liftTarget(range); 11518 if (target != null && target >= $cut.depth) { 11519 if (dispatch) 11520 dispatch(state.tr.lift(range, target).scrollIntoView()); 11521 return true; 11522 } 11523 if (canDelAfter && textblockAt(after, "start", true) && textblockAt(before, "end")) { 11524 let at = before, wrap2 = []; 11525 for (; ; ) { 11526 wrap2.push(at); 11527 if (at.isTextblock) 11528 break; 11529 at = at.lastChild; 11530 } 11531 let afterText = after, afterDepth = 1; 11532 for (; !afterText.isTextblock; afterText = afterText.firstChild) 11533 afterDepth++; 11534 if (at.canReplace(at.childCount, at.childCount, afterText.content)) { 11535 if (dispatch) { 11536 let end2 = Fragment.empty; 11537 for (let i = wrap2.length - 1; i >= 0; i--) 11538 end2 = Fragment.from(wrap2[i].copy(end2)); 11539 let tr2 = state.tr.step(new ReplaceAroundStep($cut.pos - wrap2.length, $cut.pos + after.nodeSize, $cut.pos + afterDepth, $cut.pos + after.nodeSize - afterDepth, new Slice(end2, wrap2.length, 0), 0, true)); 11540 dispatch(tr2.scrollIntoView()); 11541 } 11542 return true; 11543 } 11544 } 11545 return false; 11546} 11547function selectTextblockSide(side) { 11548 return function(state, dispatch) { 11549 let sel = state.selection, $pos = side < 0 ? sel.$from : sel.$to; 11550 let depth = $pos.depth; 11551 while ($pos.node(depth).isInline) { 11552 if (!depth) 11553 return false; 11554 depth--; 11555 } 11556 if (!$pos.node(depth).isTextblock) 11557 return false; 11558 if (dispatch) 11559 dispatch(state.tr.setSelection(TextSelection.create(state.doc, side < 0 ? $pos.start(depth) : $pos.end(depth)))); 11560 return true; 11561 }; 11562} 11563const selectTextblockStart$1 = selectTextblockSide(-1); 11564const selectTextblockEnd$1 = selectTextblockSide(1); 11565function wrapIn$1(nodeType, attrs = null) { 11566 return function(state, dispatch) { 11567 let { $from, $to } = state.selection; 11568 let range = $from.blockRange($to), wrapping = range && findWrapping(range, nodeType, attrs); 11569 if (!wrapping) 11570 return false; 11571 if (dispatch) 11572 dispatch(state.tr.wrap(range, wrapping).scrollIntoView()); 11573 return true; 11574 }; 11575} 11576function setBlockType(nodeType, attrs = null) { 11577 return function(state, dispatch) { 11578 let applicable = false; 11579 for (let i = 0; i < state.selection.ranges.length && !applicable; i++) { 11580 let { $from: { pos: from2 }, $to: { pos: to } } = state.selection.ranges[i]; 11581 state.doc.nodesBetween(from2, to, (node, pos) => { 11582 if (applicable) 11583 return false; 11584 if (!node.isTextblock || node.hasMarkup(nodeType, attrs)) 11585 return; 11586 if (node.type == nodeType) { 11587 applicable = true; 11588 } else { 11589 let $pos = state.doc.resolve(pos), index = $pos.index(); 11590 applicable = $pos.parent.canReplaceWith(index, index + 1, nodeType); 11591 } 11592 }); 11593 } 11594 if (!applicable) 11595 return false; 11596 if (dispatch) { 11597 let tr2 = state.tr; 11598 for (let i = 0; i < state.selection.ranges.length; i++) { 11599 let { $from: { pos: from2 }, $to: { pos: to } } = state.selection.ranges[i]; 11600 tr2.setBlockType(from2, to, nodeType, attrs); 11601 } 11602 dispatch(tr2.scrollIntoView()); 11603 } 11604 return true; 11605 }; 11606} 11607typeof navigator != "undefined" ? /Mac|iP(hone|[oa]d)/.test(navigator.platform) : typeof os != "undefined" && os.platform ? os.platform() == "darwin" : false; 11608function wrapInList$1(listType, attrs = null) { 11609 return function(state, dispatch) { 11610 let { $from, $to } = state.selection; 11611 let range = $from.blockRange($to), doJoin = false, outerRange = range; 11612 if (!range) 11613 return false; 11614 if (range.depth >= 2 && $from.node(range.depth - 1).type.compatibleContent(listType) && range.startIndex == 0) { 11615 if ($from.index(range.depth - 1) == 0) 11616 return false; 11617 let $insert = state.doc.resolve(range.start - 2); 11618 outerRange = new NodeRange($insert, $insert, range.depth); 11619 if (range.endIndex < range.parent.childCount) 11620 range = new NodeRange($from, state.doc.resolve($to.end(range.depth)), range.depth); 11621 doJoin = true; 11622 } 11623 let wrap2 = findWrapping(outerRange, listType, attrs, range); 11624 if (!wrap2) 11625 return false; 11626 if (dispatch) 11627 dispatch(doWrapInList(state.tr, range, wrap2, doJoin, listType).scrollIntoView()); 11628 return true; 11629 }; 11630} 11631function doWrapInList(tr2, range, wrappers, joinBefore, listType) { 11632 let content = Fragment.empty; 11633 for (let i = wrappers.length - 1; i >= 0; i--) 11634 content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content)); 11635 tr2.step(new ReplaceAroundStep(range.start - (joinBefore ? 2 : 0), range.end, range.start, range.end, new Slice(content, 0, 0), wrappers.length, true)); 11636 let found2 = 0; 11637 for (let i = 0; i < wrappers.length; i++) 11638 if (wrappers[i].type == listType) 11639 found2 = i + 1; 11640 let splitDepth = wrappers.length - found2; 11641 let splitPos = range.start + wrappers.length - (joinBefore ? 2 : 0), parent = range.parent; 11642 for (let i = range.startIndex, e = range.endIndex, first2 = true; i < e; i++, first2 = false) { 11643 if (!first2 && canSplit(tr2.doc, splitPos, splitDepth)) { 11644 tr2.split(splitPos, splitDepth); 11645 splitPos += 2 * splitDepth; 11646 } 11647 splitPos += parent.child(i).nodeSize; 11648 } 11649 return tr2; 11650} 11651function liftListItem$1(itemType) { 11652 return function(state, dispatch) { 11653 let { $from, $to } = state.selection; 11654 let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType); 11655 if (!range) 11656 return false; 11657 if (!dispatch) 11658 return true; 11659 if ($from.node(range.depth - 1).type == itemType) 11660 return liftToOuterList(state, dispatch, itemType, range); 11661 else 11662 return liftOutOfList(state, dispatch, range); 11663 }; 11664} 11665function liftToOuterList(state, dispatch, itemType, range) { 11666 let tr2 = state.tr, end2 = range.end, endOfList = range.$to.end(range.depth); 11667 if (end2 < endOfList) { 11668 tr2.step(new ReplaceAroundStep(end2 - 1, endOfList, end2, endOfList, new Slice(Fragment.from(itemType.create(null, range.parent.copy())), 1, 0), 1, true)); 11669 range = new NodeRange(tr2.doc.resolve(range.$from.pos), tr2.doc.resolve(endOfList), range.depth); 11670 } 11671 const target = liftTarget(range); 11672 if (target == null) 11673 return false; 11674 tr2.lift(range, target); 11675 let after = tr2.mapping.map(end2, -1) - 1; 11676 if (canJoin(tr2.doc, after)) 11677 tr2.join(after); 11678 dispatch(tr2.scrollIntoView()); 11679 return true; 11680} 11681function liftOutOfList(state, dispatch, range) { 11682 let tr2 = state.tr, list = range.parent; 11683 for (let pos = range.end, i = range.endIndex - 1, e = range.startIndex; i > e; i--) { 11684 pos -= list.child(i).nodeSize; 11685 tr2.delete(pos - 1, pos + 1); 11686 } 11687 let $start = tr2.doc.resolve(range.start), item = $start.nodeAfter; 11688 if (tr2.mapping.map(range.end) != range.start + $start.nodeAfter.nodeSize) 11689 return false; 11690 let atStart = range.startIndex == 0, atEnd = range.endIndex == list.childCount; 11691 let parent = $start.node(-1), indexBefore = $start.index(-1); 11692 if (!parent.canReplace(indexBefore + (atStart ? 0 : 1), indexBefore + 1, item.content.append(atEnd ? Fragment.empty : Fragment.from(list)))) 11693 return false; 11694 let start2 = $start.pos, end2 = start2 + item.nodeSize; 11695 tr2.step(new ReplaceAroundStep(start2 - (atStart ? 1 : 0), end2 + (atEnd ? 1 : 0), start2 + 1, end2 - 1, new Slice((atStart ? Fragment.empty : Fragment.from(list.copy(Fragment.empty))).append(atEnd ? Fragment.empty : Fragment.from(list.copy(Fragment.empty))), atStart ? 0 : 1, atEnd ? 0 : 1), atStart ? 0 : 1)); 11696 dispatch(tr2.scrollIntoView()); 11697 return true; 11698} 11699function sinkListItem$1(itemType) { 11700 return function(state, dispatch) { 11701 let { $from, $to } = state.selection; 11702 let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType); 11703 if (!range) 11704 return false; 11705 let startIndex = range.startIndex; 11706 if (startIndex == 0) 11707 return false; 11708 let parent = range.parent, nodeBefore = parent.child(startIndex - 1); 11709 if (nodeBefore.type != itemType) 11710 return false;
11711 if (dispatch) { 11712 let nestedBefore = nodeBefore.lastChild && nodeBefore.lastChild.type == parent.type; 11713 let inner = Fragment.from(nestedBefore ? itemType.create() : null); 11714 let slice2 = new Slice(Fragment.from(itemType.create(null, Fragment.from(parent.type.create(null, inner)))), nestedBefore ? 3 : 1, 0); 11715 let before = range.start, after = range.end; 11716 dispatch(state.tr.step(new ReplaceAroundStep(before - (nestedBefore ? 3 : 1), after, before, after, slice2, 1, true)).scrollIntoView()); 11717 } 11718 return true; 11719 }; 11720} 11721function createChainableState(config) { 11722 const { state, transaction } = config; 11723 let { selection } = transaction; 11724 let { doc: doc2 } = transaction; 11725 let { storedMarks } = transaction; 11726 return { 11727 ...state, 11728 apply: state.apply.bind(state), 11729 applyTransaction: state.applyTransaction.bind(state), 11730 plugins: state.plugins, 11731 schema: state.schema, 11732 reconfigure: state.reconfigure.bind(state), 11733 toJSON: state.toJSON.bind(state), 11734 get storedMarks() { 11735 return storedMarks; 11736 }, 11737 get selection() { 11738 return selection; 11739 }, 11740 get doc() { 11741 return doc2; 11742 }, 11743 get tr() { 11744 selection = transaction.selection; 11745 doc2 = transaction.doc; 11746 storedMarks = transaction.storedMarks; 11747 return transaction; 11748 } 11749 }; 11750} 11751class CommandManager { 11752 constructor(props) { 11753 this.editor = props.editor; 11754 this.rawCommands = this.editor.extensionManager.commands; 11755 this.customState = props.state; 11756 } 11757 get hasCustomState() { 11758 return !!this.customState; 11759 } 11760 get state() { 11761 return this.customState || this.editor.state; 11762 } 11763 get commands() { 11764 const { rawCommands, editor, state } = this; 11765 const { view } = editor; 11766 const { tr: tr2 } = state; 11767 const props = this.buildProps(tr2); 11768 return Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => { 11769 const method = (...args) => { 11770 const callback = command2(...args)(props); 11771 if (!tr2.getMeta("preventDispatch") && !this.hasCustomState) { 11772 view.dispatch(tr2); 11773 } 11774 return callback; 11775 }; 11776 return [name, method]; 11777 })); 11778 } 11779 get chain() { 11780 return () => this.createChain(); 11781 } 11782 get can() { 11783 return () => this.createCan(); 11784 } 11785 createChain(startTr, shouldDispatch = true) { 11786 const { rawCommands, editor, state } = this; 11787 const { view } = editor; 11788 const callbacks = []; 11789 const hasStartTransaction = !!startTr; 11790 const tr2 = startTr || state.tr; 11791 const run2 = () => { 11792 if (!hasStartTransaction && shouldDispatch && !tr2.getMeta("preventDispatch") && !this.hasCustomState) { 11793 view.dispatch(tr2); 11794 } 11795 return callbacks.every((callback) => callback === true); 11796 }; 11797 const chain = { 11798 ...Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => { 11799 const chainedCommand = (...args) => { 11800 const props = this.buildProps(tr2, shouldDispatch); 11801 const callback = command2(...args)(props); 11802 callbacks.push(callback); 11803 return chain; 11804 }; 11805 return [name, chainedCommand]; 11806 })), 11807 run: run2 11808 }; 11809 return chain; 11810 } 11811 createCan(startTr) { 11812 const { rawCommands, state } = this; 11813 const dispatch = false; 11814 const tr2 = startTr || state.tr; 11815 const props = this.buildProps(tr2, dispatch); 11816 const formattedCommands = Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => { 11817 return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })]; 11818 })); 11819 return { 11820 ...formattedCommands, 11821 chain: () => this.createChain(tr2, dispatch) 11822 }; 11823 } 11824 buildProps(tr2, shouldDispatch = true) { 11825 const { rawCommands, editor, state } = this; 11826 const { view } = editor; 11827 const props = { 11828 tr: tr2, 11829 editor, 11830 view, 11831 state: createChainableState({ 11832 state, 11833 transaction: tr2 11834 }), 11835 dispatch: shouldDispatch ? () => void 0 : void 0, 11836 chain: () => this.createChain(tr2, shouldDispatch), 11837 can: () => this.createCan(tr2), 11838 get commands() { 11839 return Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => { 11840 return [name, (...args) => command2(...args)(props)]; 11841 })); 11842 } 11843 }; 11844 return props; 11845 } 11846} 11847class EventEmitter {
11848 constructor() { 11849 this.callbacks = {}; 11850 } 11851 on(event, fn2) { 11852 if (!this.callbacks[event]) { 11853 this.callbacks[event] = []; 11854 } 11855 this.callbacks[event].push(fn2); 11856 return this; 11857 } 11858 emit(event, ...args) { 11859 const callbacks = this.callbacks[event]; 11860 if (callbacks) { 11861 callbacks.forEach((callback) => callback.apply(this, args)); 11862 } 11863 return this; 11864 } 11865 off(event, fn2) { 11866 const callbacks = this.callbacks[event]; 11867 if (callbacks) { 11868 if (fn2) { 11869 this.callbacks[event] = callbacks.filter((callback) => callback !== fn2); 11870 } else { 11871 delete this.callbacks[event]; 11872 } 11873 } 11874 return this; 11875 } 11876 removeAllListeners() { 11877 this.callbacks = {}; 11878 } 11879} 11880function getExtensionField(extension, field, context) { 11881 if (extension.config[field] === void 0 && extension.parent) { 11882 return getExtensionField(extension.parent, field, context); 11883 } 11884 if (typeof extension.config[field] === "function") { 11885 const value = extension.config[field].bind({ 11886 ...context, 11887 parent: extension.parent ? getExtensionField(extension.parent, field, context) : null 11888 }); 11889 return value; 11890 } 11891 return extension.config[field]; 11892} 11893function splitExtensions(extensions) { 11894 const baseExtensions = extensions.filter((extension) => extension.type === "extension"); 11895 const nodeExtensions = extensions.filter((extension) => extension.type === "node"); 11896 const markExtensions = extensions.filter((extension) => extension.type === "mark"); 11897 return { 11898 baseExtensions, 11899 nodeExtensions, 11900 markExtensions 11901 }; 11902} 11903function getAttributesFromExtensions(extensions) { 11904 const extensionAttributes = []; 11905 const { nodeExtensions, markExtensions } = splitExtensions(extensions); 11906 const nodeAndMarkExtensions = [...nodeExtensions, ...markExtensions]; 11907 const defaultAttribute = { 11908 default: null, 11909 rendered: true, 11910 renderHTML: null, 11911 parseHTML: null, 11912 keepOnSplit: true, 11913 isRequired: false 11914 }; 11915 extensions.forEach((extension) => { 11916 const context = { 11917 name: extension.name, 11918 options: extension.options, 11919 storage: extension.storage 11920 }; 11921 const addGlobalAttributes = getExtensionField(extension, "addGlobalAttributes", context); 11922 if (!addGlobalAttributes) { 11923 return; 11924 } 11925 const globalAttributes = addGlobalAttributes(); 11926 globalAttributes.forEach((globalAttribute) => { 11927 globalAttribute.types.forEach((type) => { 11928 Object.entries(globalAttribute.attributes).forEach(([name, attribute]) => { 11929 extensionAttributes.push({ 11930 type, 11931 name, 11932 attribute: { 11933 ...defaultAttribute, 11934 ...attribute 11935 } 11936 }); 11937 }); 11938 }); 11939 }); 11940 }); 11941 nodeAndMarkExtensions.forEach((extension) => { 11942 const context = { 11943 name: extension.name, 11944 options: extension.options, 11945 storage: extension.storage 11946 }; 11947 const addAttributes = getExtensionField(extension, "addAttributes", context); 11948 if (!addAttributes) { 11949 return; 11950 } 11951 const attributes = addAttributes(); 11952 Object.entries(attributes).forEach(([name, attribute]) => { 11953 const mergedAttr = { 11954 ...defaultAttribute, 11955 ...attribute 11956 }; 11957 if (typeof (mergedAttr === null || mergedAttr === void 0 ? void 0 : mergedAttr.default) === "function") { 11958 mergedAttr.default = mergedAttr.default(); 11959 } 11960 if ((mergedAttr === null || mergedAttr === void 0 ? void 0 : mergedAttr.isRequired) && (mergedAttr === null || mergedAttr === void 0 ? void 0 : mergedAttr.default) === void 0) { 11961 delete mergedAttr.default; 11962 } 11963 extensionAttributes.push({ 11964 type: extension.name, 11965 name, 11966 attribute: mergedAttr 11967 }); 11968 }); 11969 }); 11970 return extensionAttributes; 11971} 11972function getNodeType(nameOrType, schema) { 11973 if (typeof nameOrType === "string") { 11974 if (!schema.nodes[nameOrType]) { 11975 throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`); 11976 } 11977 return schema.nodes[nameOrType]; 11978 } 11979 return nameOrType; 11980} 11981function mergeAttributes(...objects) { 11982 return objects.filter((item) => !!item).reduce((items, item) => { 11983 const mergedAttributes = { ...items };
11984 Object.entries(item).forEach(([key, value]) => { 11985 const exists = mergedAttributes[key]; 11986 if (!exists) { 11987 mergedAttributes[key] = value; 11988 return; 11989 } 11990 if (key === "class") { 11991 const valueClasses = value ? value.split(" ") : []; 11992 const existingClasses = mergedAttributes[key] ? mergedAttributes[key].split(" ") : []; 11993 const insertClasses = valueClasses.filter((valueClass) => !existingClasses.includes(valueClass)); 11994 mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" "); 11995 } else if (key === "style") { 11996 mergedAttributes[key] = [mergedAttributes[key], value].join("; "); 11997 } else { 11998 mergedAttributes[key] = value; 11999 } 12000 }); 12001 return mergedAttributes; 12002 }, {}); 12003} 12004function getRenderedAttributes(nodeOrMark, extensionAttributes) { 12005 return extensionAttributes.filter((item) => item.attribute.rendered).map((item) => { 12006 if (!item.attribute.renderHTML) { 12007 return { 12008 [item.name]: nodeOrMark.attrs[item.name] 12009 }; 12010 } 12011 return item.attribute.renderHTML(nodeOrMark.attrs) || {}; 12012 }).reduce((attributes, attribute) => mergeAttributes(attributes, attribute), {}); 12013} 12014function isFunction(value) { 12015 return typeof value === "function"; 12016} 12017function callOrReturn(value, context = void 0, ...props) { 12018 if (isFunction(value)) { 12019 if (context) { 12020 return value.bind(context)(...props); 12021 } 12022 return value(...props); 12023 } 12024 return value; 12025} 12026function isEmptyObject(value = {}) { 12027 return Object.keys(value).length === 0 && value.constructor === Object; 12028} 12029function fromString(value) { 12030 if (typeof value !== "string") { 12031 return value; 12032 } 12033 if (value.match(/^[+-]?(?:\d*\.)?\d+$/)) { 12034 return Number(value); 12035 } 12036 if (value === "true") { 12037 return true; 12038 } 12039 if (value === "false") { 12040 return false; 12041 } 12042 return value; 12043} 12044function injectExtensionAttributesToParseRule(parseRule, extensionAttributes) { 12045 if (parseRule.style) { 12046 return parseRule; 12047 } 12048 return { 12049 ...parseRule, 12050 getAttrs: (node) => { 12051 const oldAttributes = parseRule.getAttrs ? parseRule.getAttrs(node) : parseRule.attrs; 12052 if (oldAttributes === false) { 12053 return false; 12054 } 12055 const newAttributes = extensionAttributes.reduce((items, item) => { 12056 const value = item.attribute.parseHTML ? item.attribute.parseHTML(node) : fromString(node.getAttribute(item.name)); 12057 if (value === null || value === void 0) { 12058 return items; 12059 } 12060 return { 12061 ...items, 12062 [item.name]: value 12063 }; 12064 }, {}); 12065 return { ...oldAttributes, ...newAttributes }; 12066 } 12067 }; 12068} 12069function cleanUpSchemaItem(data) { 12070 return Object.fromEntries( 12071 // @ts-ignore 12072 Object.entries(data).filter(([key, value]) => { 12073 if (key === "attrs" && isEmptyObject(value)) { 12074 return false; 12075 } 12076 return value !== null && value !== void 0; 12077 }) 12078 ); 12079} 12080function getSchemaByResolvedExtensions(extensions, editor) { 12081 var _a; 12082 const allAttributes = getAttributesFromExtensions(extensions); 12083 const { nodeExtensions, markExtensions } = splitExtensions(extensions); 12084 const topNode = (_a = nodeExtensions.find((extension) => getExtensionField(extension, "topNode"))) === null || _a === void 0 ? void 0 : _a.name; 12085 const nodes = Object.fromEntries(nodeExtensions.map((extension) => { 12086 const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name); 12087 const context = { 12088 name: extension.name, 12089 options: extension.options, 12090 storage: extension.storage, 12091 editor 12092 }; 12093 const extraNodeFields = extensions.reduce((fields, e) => { 12094 const extendNodeSchema = getExtensionField(e, "extendNodeSchema", context); 12095 return { 12096 ...fields, 12097 ...extendNodeSchema ? extendNodeSchema(extension) : {} 12098 }; 12099 }, {}); 12100 const schema = cleanUpSchemaItem({ 12101 ...extraNodeFields, 12102 content: callOrReturn(getExtensionField(extension, "content", context)), 12103 marks: callOrReturn(getExtensionField(extension, "marks", context)), 12104 group: callOrReturn(getExtensionField(extension, "group", context)), 12105 inline: callOrReturn(getExtensionField(extension, "inline", context)), 12106 atom: callOrReturn(getExtensionField(extension, "atom", context)), 12107 selectable: callOrReturn(getExtensionField(extension, "selectable", context)), 12108 draggable: callOrReturn(getExtensionField(extension, "draggable", context)),
12109 code: callOrReturn(getExtensionField(extension, "code", context)), 12110 defining: callOrReturn(getExtensionField(extension, "defining", context)), 12111 isolating: callOrReturn(getExtensionField(extension, "isolating", context)), 12112 attrs: Object.fromEntries(extensionAttributes.map((extensionAttribute) => { 12113 var _a2; 12114 return [extensionAttribute.name, { default: (_a2 = extensionAttribute === null || extensionAttribute === void 0 ? void 0 : extensionAttribute.attribute) === null || _a2 === void 0 ? void 0 : _a2.default }]; 12115 })) 12116 }); 12117 const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context)); 12118 if (parseHTML) { 12119 schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes)); 12120 } 12121 const renderHTML = getExtensionField(extension, "renderHTML", context); 12122 if (renderHTML) { 12123 schema.toDOM = (node) => renderHTML({ 12124 node, 12125 HTMLAttributes: getRenderedAttributes(node, extensionAttributes) 12126 }); 12127 } 12128 const renderText = getExtensionField(extension, "renderText", context); 12129 if (renderText) { 12130 schema.toText = renderText; 12131 } 12132 return [extension.name, schema]; 12133 })); 12134 const marks = Object.fromEntries(markExtensions.map((extension) => { 12135 const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name); 12136 const context = { 12137 name: extension.name, 12138 options: extension.options, 12139 storage: extension.storage, 12140 editor 12141 }; 12142 const extraMarkFields = extensions.reduce((fields, e) => { 12143 const extendMarkSchema = getExtensionField(e, "extendMarkSchema", context); 12144 return { 12145 ...fields, 12146 ...extendMarkSchema ? extendMarkSchema(extension) : {} 12147 }; 12148 }, {}); 12149 const schema = cleanUpSchemaItem({ 12150 ...extraMarkFields, 12151 inclusive: callOrReturn(getExtensionField(extension, "inclusive", context)), 12152 excludes: callOrReturn(getExtensionField(extension, "excludes", context)), 12153 group: callOrReturn(getExtensionField(extension, "group", context)), 12154 spanning: callOrReturn(getExtensionField(extension, "spanning", context)), 12155 code: callOrReturn(getExtensionField(extension, "code", context)), 12156 attrs: Object.fromEntries(extensionAttributes.map((extensionAttribute) => { 12157 var _a2; 12158 return [extensionAttribute.name, { default: (_a2 = extensionAttribute === null || extensionAttribute === void 0 ? void 0 : extensionAttribute.attribute) === null || _a2 === void 0 ? void 0 : _a2.default }]; 12159 })) 12160 }); 12161 const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context)); 12162 if (parseHTML) { 12163 schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes)); 12164 } 12165 const renderHTML = getExtensionField(extension, "renderHTML", context); 12166 if (renderHTML) { 12167 schema.toDOM = (mark) => renderHTML({ 12168 mark, 12169 HTMLAttributes: getRenderedAttributes(mark, extensionAttributes) 12170 }); 12171 } 12172 return [extension.name, schema]; 12173 })); 12174 return new Schema({ 12175 topNode, 12176 nodes, 12177 marks 12178 }); 12179} 12180function getSchemaTypeByName(name, schema) { 12181 return schema.nodes[name] || schema.marks[name] || null; 12182} 12183function isExtensionRulesEnabled(extension, enabled) { 12184 if (Array.isArray(enabled)) { 12185 return enabled.some((enabledExtension) => { 12186 const name = typeof enabledExtension === "string" ? enabledExtension : enabledExtension.name; 12187 return name === extension.name; 12188 }); 12189 } 12190 return enabled; 12191} 12192const getTextContentFromNodes = ($from, maxMatch = 500) => { 12193 let textBefore = ""; 12194 const sliceEndPos = $from.parentOffset; 12195 $from.parent.nodesBetween(Math.max(0, sliceEndPos - maxMatch), sliceEndPos, (node, pos, parent, index) => { 12196 var _a, _b; 12197 const chunk = ((_b = (_a = node.type.spec).toText) === null || _b === void 0 ? void 0 : _b.call(_a, { 12198 node, 12199 pos, 12200 parent, 12201 index 12202 })) || node.textContent || "%leaf%"; 12203 textBefore += chunk.slice(0, Math.max(0, sliceEndPos - pos)); 12204 }); 12205 return textBefore; 12206}; 12207function isRegExp(value) { 12208 return Object.prototype.toString.call(value) === "[object RegExp]"; 12209} 12210class InputRule { 12211 constructor(config) { 12212 this.find = config.find; 12213 this.handler = config.handler; 12214 } 12215} 12216const inputRuleMatcherHandler = (text, find2) => { 12217 if (isRegExp(find2)) { 12218 return find2.exec(text); 12219 } 12220 const inputRuleMatch = find2(text); 12221 if (!inputRuleMatch) { 12222 return null; 12223 } 12224 const result = [inputRuleMatch.text]; 12225 result.index = inputRuleMatch.index; 12226 result.input = text; 12227 result.data = inputRuleMatch.data; 12228 if (inputRuleMatch.replaceWith) { 12229 if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) { 12230 console.warn('[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'); 12231 } 12232 result.push(inputRuleMatch.replaceWith); 12233 } 12234 return result; 12235}; 12236function run$1$1(config) { 12237 var _a; 12238 const { editor, from: from2, to, text, rules, plugin } = config; 12239 const { view } = editor; 12240 if (view.composing) { 12241 return false;
12242 } 12243 const $from = view.state.doc.resolve(from2); 12244 if ( 12245 // check for code node 12246 $from.parent.type.spec.code || !!((_a = $from.nodeBefore || $from.nodeAfter) === null || _a === void 0 ? void 0 : _a.marks.find((mark) => mark.type.spec.code)) 12247 ) { 12248 return false; 12249 } 12250 let matched = false; 12251 const textBefore = getTextContentFromNodes($from) + text; 12252 rules.forEach((rule) => { 12253 if (matched) { 12254 return; 12255 } 12256 const match = inputRuleMatcherHandler(textBefore, rule.find); 12257 if (!match) { 12258 return; 12259 } 12260 const tr2 = view.state.tr; 12261 const state = createChainableState({ 12262 state: view.state, 12263 transaction: tr2 12264 }); 12265 const range = { 12266 from: from2 - (match[0].length - text.length), 12267 to 12268 }; 12269 const { commands: commands2, chain, can } = new CommandManager({ 12270 editor, 12271 state 12272 }); 12273 const handler = rule.handler({ 12274 state, 12275 range, 12276 match, 12277 commands: commands2, 12278 chain, 12279 can 12280 }); 12281 if (handler === null || !tr2.steps.length) { 12282 return; 12283 } 12284 tr2.setMeta(plugin, { 12285 transform: tr2, 12286 from: from2, 12287 to, 12288 text 12289 }); 12290 view.dispatch(tr2); 12291 matched = true; 12292 }); 12293 return matched; 12294} 12295function inputRulesPlugin(props) { 12296 const { editor, rules } = props; 12297 const plugin = new Plugin({ 12298 state: { 12299 init() { 12300 return null; 12301 }, 12302 apply(tr2, prev) { 12303 const stored = tr2.getMeta(plugin); 12304 if (stored) { 12305 return stored; 12306 } 12307 const simulatedInputMeta = tr2.getMeta("applyInputRules"); 12308 const isSimulatedInput = !!simulatedInputMeta; 12309 if (isSimulatedInput) { 12310 setTimeout(() => { 12311 const { from: from2, text } = simulatedInputMeta; 12312 const to = from2 + text.length; 12313 run$1$1({ 12314 editor, 12315 from: from2, 12316 to, 12317 text, 12318 rules, 12319 plugin 12320 }); 12321 }); 12322 } 12323 return tr2.selectionSet || tr2.docChanged ? null : prev; 12324 } 12325 }, 12326 props: { 12327 handleTextInput(view, from2, to, text) { 12328 return run$1$1({ 12329 editor, 12330 from: from2, 12331 to, 12332 text, 12333 rules, 12334 plugin 12335 }); 12336 }, 12337 handleDOMEvents: { 12338 compositionend: (view) => { 12339 setTimeout(() => { 12340 const { $cursor } = view.state.selection; 12341 if ($cursor) { 12342 run$1$1({ 12343 editor, 12344 from: $cursor.pos, 12345 to: $cursor.pos, 12346 text: "", 12347 rules, 12348 plugin 12349 }); 12350 } 12351 }); 12352 return false; 12353 } 12354 }, 12355 // add support for input rules to trigger on enter 12356 // this is useful for example for code blocks 12357 handleKeyDown(view, event) { 12358 if (event.key !== "Enter") { 12359 return false; 12360 } 12361 const { $cursor } = view.state.selection; 12362 if ($cursor) { 12363 return run$1$1({ 12364 editor, 12365 from: $cursor.pos, 12366 to: $cursor.pos, 12367 text: "\n", 12368 rules, 12369 plugin 12370 }); 12371 } 12372 return false; 12373 } 12374 }, 12375 // @ts-ignore 12376 isInputRules: true 12377 }); 12378 return plugin; 12379} 12380function isNumber(value) { 12381 return typeof value === "number"; 12382} 12383class PasteRule { 12384 constructor(config) { 12385 this.find = config.find; 12386 this.handler = config.handler; 12387 } 12388} 12389const pasteRuleMatcherHandler = (text, find2, event) => { 12390 if (isRegExp(find2)) { 12391 return [...text.matchAll(find2)]; 12392 } 12393 const matches2 = find2(text, event); 12394 if (!matches2) { 12395 return []; 12396 } 12397 return matches2.map((pasteRuleMatch) => { 12398 const result = [pasteRuleMatch.text]; 12399 result.index = pasteRuleMatch.index; 12400 result.input = text; 12401 result.data = pasteRuleMatch.data; 12402 if (pasteRuleMatch.replaceWith) { 12403 if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) { 12404 console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".'); 12405 } 12406 result.push(pasteRuleMatch.replaceWith); 12407 } 12408 return result; 12409 }); 12410}; 12411function run$2(config) { 12412 const { editor, state, from: from2, to, rule, pasteEvent, dropEvent } = config; 12413 const { commands: commands2, chain, can } = new CommandManager({ 12414 editor, 12415 state 12416 }); 12417 const handlers2 = []; 12418 state.doc.nodesBetween(from2, to, (node, pos) => { 12419 if (!node.isTextblock || node.type.spec.code) { 12420 return; 12421 } 12422 const resolvedFrom = Math.max(from2, pos); 12423 const resolvedTo = Math.min(to, pos + node.content.size); 12424 const textToMatch = node.textBetween(resolvedFrom - pos, resolvedTo - pos, void 0, ""); 12425 const matches2 = pasteRuleMatcherHandler(textToMatch, rule.find, pasteEvent); 12426 matches2.forEach((match) => { 12427 if (match.index === void 0) { 12428 return; 12429 } 12430 const start2 = resolvedFrom + match.index + 1; 12431 const end2 = start2 + match[0].length; 12432 const range = { 12433 from: state.tr.mapping.map(start2),
12434 to: state.tr.mapping.map(end2) 12435 }; 12436 const handler = rule.handler({ 12437 state, 12438 range, 12439 match, 12440 commands: commands2, 12441 chain, 12442 can, 12443 pasteEvent, 12444 dropEvent 12445 }); 12446 handlers2.push(handler); 12447 }); 12448 }); 12449 const success = handlers2.every((handler) => handler !== null); 12450 return success; 12451} 12452const createClipboardPasteEvent = (text) => { 12453 var _a; 12454 const event = new ClipboardEvent("paste", { 12455 clipboardData: new DataTransfer() 12456 }); 12457 (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.setData("text/html", text); 12458 return event; 12459}; 12460function pasteRulesPlugin(props) { 12461 const { editor, rules } = props; 12462 let dragSourceElement = null; 12463 let isPastedFromProseMirror = false; 12464 let isDroppedFromProseMirror = false; 12465 let pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null; 12466 let dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null; 12467 const processEvent = ({ state, from: from2, to, rule, pasteEvt }) => { 12468 const tr2 = state.tr; 12469 const chainableState = createChainableState({ 12470 state, 12471 transaction: tr2 12472 }); 12473 const handler = run$2({ 12474 editor, 12475 state: chainableState, 12476 from: Math.max(from2 - 1, 0), 12477 to: to.b - 1, 12478 rule, 12479 pasteEvent: pasteEvt, 12480 dropEvent 12481 }); 12482 if (!handler || !tr2.steps.length) { 12483 return; 12484 } 12485 dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null; 12486 pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null; 12487 return tr2; 12488 }; 12489 const plugins = rules.map((rule) => { 12490 return new Plugin({ 12491 // we register a global drag handler to track the current drag source element 12492 view(view) { 12493 const handleDragstart = (event) => { 12494 var _a; 12495 dragSourceElement = ((_a = view.dom.parentElement) === null || _a === void 0 ? void 0 : _a.contains(event.target)) ? view.dom.parentElement : null; 12496 }; 12497 window.addEventListener("dragstart", handleDragstart); 12498 return { 12499 destroy() { 12500 window.removeEventListener("dragstart", handleDragstart); 12501 } 12502 }; 12503 }, 12504 props: { 12505 handleDOMEvents: { 12506 drop: (view, event) => { 12507 isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement; 12508 dropEvent = event; 12509 return false; 12510 }, 12511 paste: (_view, event) => { 12512 var _a; 12513 const html = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData("text/html"); 12514 pasteEvent = event; 12515 isPastedFromProseMirror = !!(html === null || html === void 0 ? void 0 : html.includes("data-pm-slice")); 12516 return false; 12517 } 12518 } 12519 }, 12520 appendTransaction: (transactions, oldState, state) => { 12521 const transaction = transactions[0]; 12522 const isPaste = transaction.getMeta("uiEvent") === "paste" && !isPastedFromProseMirror; 12523 const isDrop = transaction.getMeta("uiEvent") === "drop" && !isDroppedFromProseMirror; 12524 const simulatedPasteMeta = transaction.getMeta("applyPasteRules"); 12525 const isSimulatedPaste = !!simulatedPasteMeta; 12526 if (!isPaste && !isDrop && !isSimulatedPaste) { 12527 return; 12528 } 12529 if (isSimulatedPaste) { 12530 const { from: from3, text } = simulatedPasteMeta; 12531 const to2 = from3 + text.length; 12532 const pasteEvt = createClipboardPasteEvent(text); 12533 return processEvent({ 12534 rule, 12535 state, 12536 from: from3, 12537 to: { b: to2 }, 12538 pasteEvt 12539 }); 12540 } 12541 const from2 = oldState.doc.content.findDiffStart(state.doc.content); 12542 const to = oldState.doc.content.findDiffEnd(state.doc.content); 12543 if (!isNumber(from2) || !to || from2 === to.b) { 12544 return; 12545 } 12546 return processEvent({ 12547 rule, 12548 state, 12549 from: from2, 12550 to, 12551 pasteEvt: pasteEvent 12552 }); 12553 } 12554 }); 12555 }); 12556 return plugins; 12557} 12558function findDuplicates(items) { 12559 const filtered = items.filter((el, index) => items.indexOf(el) !== index); 12560 return [...new Set(filtered)]; 12561} 12562class ExtensionManager { 12563 constructor(extensions, editor) { 12564 this.splittableMarks = []; 12565 this.editor = editor; 12566 this.extensions = ExtensionManager.resolve(extensions); 12567 this.schema = getSchemaByResolvedExtensions(this.extensions, editor); 12568 this.setupExtensions(); 12569 } 12570 /** 12571 * Returns a flattened and sorted extension list while 12572 * also checking for duplicated extensions and warns the user. 12573 * @param extensions An array of Tiptap extensions 12574 * @returns An flattened and sorted array of Tiptap extensions 12575 */ 12576 static resolve(extensions) { 12577 const resolvedExtensions = ExtensionManager.sort(ExtensionManager.flatten(extensions)); 12578 const duplicatedNames = findDuplicates(resolvedExtensions.map((extension) => extension.name)); 12579 if (duplicatedNames.length) { 12580 console.warn(`[tiptap warn]: Duplicate extension names found: [${duplicatedNames.map((item) => `'${item}'`).join(", ")}]. This can lead to issues.`); 12581 } 12582 return resolvedExtensions; 12583 } 12584 /** 12585 * Create a flattened array of extensions by traversing the `addExtensions` field. 12586 * @param extensions An array of Tiptap extensions 12587 * @returns A flattened array of Tiptap extensions 12588 */ 12589 static flatten(extensions) { 12590 return extensions.map((extension) => { 12591 const context = { 12592 name: extension.name, 12593 options: extension.options, 12594 storage: extension.storage 12595 }; 12596 const addExtensions = getExtensionField(extension, "addExtensions", context); 12597 if (addExtensions) { 12598 return [extension, ...this.flatten(addExtensions())]; 12599 } 12600 return extension; 12601 }).flat(10); 12602 } 12603 /** 12604 * Sort extensions by priority. 12605 * @param extensions An array of Tiptap extensions 12606 * @returns A sorted array of Tiptap extensions by priority 12607 */ 12608 static sort(extensions) { 12609 const defaultPriority = 100; 12610 return extensions.sort((a, b) => { 12611 const priorityA = getExtensionField(a, "priority") || defaultPriority; 12612 const priorityB = getExtensionField(b, "priority") || defaultPriority; 12613 if (priorityA > priorityB) { 12614 return -1; 12615 } 12616 if (priorityA < priorityB) { 12617 return 1; 12618 } 12619 return 0; 12620 }); 12621 } 12622 /** 12623 * Get all commands from the extensions. 12624 * @returns An object with all commands where the key is the command name and the value is the command function 12625 */ 12626 get commands() { 12627 return this.extensions.reduce((commands2, extension) => { 12628 const context = { 12629 name: extension.name, 12630 options: extension.options, 12631 storage: extension.storage, 12632 editor: this.editor, 12633 type: getSchemaTypeByName(extension.name, this.schema) 12634 }; 12635 const addCommands = getExtensionField(extension, "addCommands", context); 12636 if (!addCommands) { 12637 return commands2; 12638 } 12639 return { 12640 ...commands2, 12641 ...addCommands() 12642 }; 12643 }, {}); 12644 } 12645 /** 12646 * Get all registered Prosemirror plugins from the extensions. 12647 * @returns An array of Prosemirror plugins 12648 */ 12649 get plugins() { 12650 const { editor } = this; 12651 const extensions = ExtensionManager.sort([...this.extensions].reverse()); 12652 const inputRules = []; 12653 const pasteRules = []; 12654 const allPlugins = extensions.map((extension) => { 12655 const context = { 12656 name: extension.name, 12657 options: extension.options, 12658 storage: extension.storage, 12659 editor, 12660 type: getSchemaTypeByName(extension.name, this.schema) 12661 }; 12662 const plugins = []; 12663 const addKeyboardShortcuts = getExtensionField(extension, "addKeyboardShortcuts", context); 12664 let defaultBindings = {}; 12665 if (extension.type === "mark" && extension.config.exitable) { 12666 defaultBindings.ArrowRight = () => Mark2.handleExit({ editor, mark: extension }); 12667 } 12668 if (addKeyboardShortcuts) { 12669 const bindings = Object.fromEntries(Object.entries(addKeyboardShortcuts()).map(([shortcut, method]) => { 12670 return [shortcut, () => method({ editor })]; 12671 })); 12672 defaultBindings = { ...defaultBindings, ...bindings }; 12673 }
12674 const keyMapPlugin = keymap(defaultBindings); 12675 plugins.push(keyMapPlugin); 12676 const addInputRules = getExtensionField(extension, "addInputRules", context); 12677 if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) { 12678 inputRules.push(...addInputRules()); 12679 } 12680 const addPasteRules = getExtensionField(extension, "addPasteRules", context); 12681 if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) { 12682 pasteRules.push(...addPasteRules()); 12683 } 12684 const addProseMirrorPlugins = getExtensionField(extension, "addProseMirrorPlugins", context); 12685 if (addProseMirrorPlugins) { 12686 const proseMirrorPlugins = addProseMirrorPlugins(); 12687 plugins.push(...proseMirrorPlugins); 12688 } 12689 return plugins; 12690 }).flat(); 12691 return [ 12692 inputRulesPlugin({ 12693 editor, 12694 rules: inputRules 12695 }), 12696 ...pasteRulesPlugin({ 12697 editor, 12698 rules: pasteRules 12699 }), 12700 ...allPlugins 12701 ]; 12702 } 12703 /** 12704 * Get all attributes from the extensions. 12705 * @returns An array of attributes 12706 */ 12707 get attributes() { 12708 return getAttributesFromExtensions(this.extensions); 12709 } 12710 /** 12711 * Get all node views from the extensions. 12712 * @returns An object with all node views where the key is the node name and the value is the node view function 12713 */ 12714 get nodeViews() { 12715 const { editor } = this; 12716 const { nodeExtensions } = splitExtensions(this.extensions); 12717 return Object.fromEntries(nodeExtensions.filter((extension) => !!getExtensionField(extension, "addNodeView")).map((extension) => { 12718 const extensionAttributes = this.attributes.filter((attribute) => attribute.type === extension.name); 12719 const context = { 12720 name: extension.name, 12721 options: extension.options, 12722 storage: extension.storage, 12723 editor, 12724 type: getNodeType(extension.name, this.schema) 12725 }; 12726 const addNodeView = getExtensionField(extension, "addNodeView", context); 12727 if (!addNodeView) { 12728 return []; 12729 } 12730 const nodeview = (node, view, getPos, decorations) => { 12731 const HTMLAttributes = getRenderedAttributes(node, extensionAttributes); 12732 return addNodeView()({ 12733 editor, 12734 node, 12735 getPos, 12736 decorations, 12737 HTMLAttributes, 12738 extension 12739 }); 12740 }; 12741 return [extension.name, nodeview]; 12742 })); 12743 } 12744 /** 12745 * Go through all extensions, create extension storages & setup marks 12746 * & bind editor event listener. 12747 */ 12748 setupExtensions() { 12749 this.extensions.forEach((extension) => { 12750 var _a; 12751 this.editor.extensionStorage[extension.name] = extension.storage; 12752 const context = { 12753 name: extension.name, 12754 options: extension.options, 12755 storage: extension.storage, 12756 editor: this.editor, 12757 type: getSchemaTypeByName(extension.name, this.schema) 12758 }; 12759 if (extension.type === "mark") { 12760 const keepOnSplit = (_a = callOrReturn(getExtensionField(extension, "keepOnSplit", context))) !== null && _a !== void 0 ? _a : true; 12761 if (keepOnSplit) { 12762 this.splittableMarks.push(extension.name); 12763 } 12764 } 12765 const onBeforeCreate = getExtensionField(extension, "onBeforeCreate", context); 12766 const onCreate2 = getExtensionField(extension, "onCreate", context); 12767 const onUpdate = getExtensionField(extension, "onUpdate", context); 12768 const onSelectionUpdate = getExtensionField(extension, "onSelectionUpdate", context); 12769 const onTransaction = getExtensionField(extension, "onTransaction", context); 12770 const onFocus = getExtensionField(extension, "onFocus", context); 12771 const onBlur = getExtensionField(extension, "onBlur", context); 12772 const onDestroy2 = getExtensionField(extension, "onDestroy", context); 12773 if (onBeforeCreate) { 12774 this.editor.on("beforeCreate", onBeforeCreate); 12775 } 12776 if (onCreate2) { 12777 this.editor.on("create", onCreate2); 12778 } 12779 if (onUpdate) { 12780 this.editor.on("update", onUpdate); 12781 } 12782 if (onSelectionUpdate) { 12783 this.editor.on("selectionUpdate", onSelectionUpdate); 12784 } 12785 if (onTransaction) { 12786 this.editor.on("transaction", onTransaction); 12787 } 12788 if (onFocus) { 12789 this.editor.on("focus", onFocus); 12790 } 12791 if (onBlur) { 12792 this.editor.on("blur", onBlur); 12793 } 12794 if (onDestroy2) { 12795 this.editor.on("destroy", onDestroy2); 12796 } 12797 }); 12798 } 12799} 12800function getType(value) { 12801 return Object.prototype.toString.call(value).slice(8, -1); 12802} 12803function isPlainObject(value) { 12804 if (getType(value) !== "Object") { 12805 return false;
12806 } 12807 return value.constructor === Object && Object.getPrototypeOf(value) === Object.prototype; 12808} 12809function mergeDeep(target, source) { 12810 const output = { ...target }; 12811 if (isPlainObject(target) && isPlainObject(source)) { 12812 Object.keys(source).forEach((key) => { 12813 if (isPlainObject(source[key])) { 12814 if (!(key in target)) { 12815 Object.assign(output, { [key]: source[key] }); 12816 } else { 12817 output[key] = mergeDeep(target[key], source[key]); 12818 } 12819 } else { 12820 Object.assign(output, { [key]: source[key] }); 12821 } 12822 }); 12823 } 12824 return output; 12825} 12826class Extension { 12827 constructor(config = {}) { 12828 this.type = "extension"; 12829 this.name = "extension"; 12830 this.parent = null; 12831 this.child = null; 12832 this.config = { 12833 name: this.name, 12834 defaultOptions: {} 12835 }; 12836 this.config = { 12837 ...this.config, 12838 ...config 12839 }; 12840 this.name = this.config.name; 12841 if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) { 12842 console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`); 12843 } 12844 this.options = this.config.defaultOptions; 12845 if (this.config.addOptions) { 12846 this.options = callOrReturn(getExtensionField(this, "addOptions", { 12847 name: this.name 12848 })); 12849 } 12850 this.storage = callOrReturn(getExtensionField(this, "addStorage", { 12851 name: this.name, 12852 options: this.options 12853 })) || {}; 12854 } 12855 static create(config = {}) { 12856 return new Extension(config); 12857 } 12858 configure(options = {}) { 12859 const extension = this.extend(); 12860 extension.parent = this.parent; 12861 extension.options = mergeDeep(this.options, options); 12862 extension.storage = callOrReturn(getExtensionField(extension, "addStorage", { 12863 name: extension.name, 12864 options: extension.options 12865 })); 12866 return extension; 12867 } 12868 extend(extendedConfig = {}) { 12869 const extension = new Extension({ ...this.config, ...extendedConfig }); 12870 extension.parent = this; 12871 this.child = extension; 12872 extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name; 12873 if (extendedConfig.defaultOptions) { 12874 console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`); 12875 } 12876 extension.options = callOrReturn(getExtensionField(extension, "addOptions", { 12877 name: extension.name 12878 })); 12879 extension.storage = callOrReturn(getExtensionField(extension, "addStorage", { 12880 name: extension.name, 12881 options: extension.options 12882 })); 12883 return extension; 12884 } 12885} 12886function getTextBetween(startNode, range, options) { 12887 const { from: from2, to } = range;
12888 const { blockSeparator = "\n\n", textSerializers = {} } = options || {}; 12889 let text = ""; 12890 startNode.nodesBetween(from2, to, (node, pos, parent, index) => { 12891 var _a; 12892 if (node.isBlock && pos > from2) { 12893 text += blockSeparator; 12894 } 12895 const textSerializer = textSerializers === null || textSerializers === void 0 ? void 0 : textSerializers[node.type.name]; 12896 if (textSerializer) { 12897 if (parent) { 12898 text += textSerializer({ 12899 node, 12900 pos, 12901 parent, 12902 index, 12903 range 12904 }); 12905 } 12906 return false; 12907 } 12908 if (node.isText) { 12909 text += (_a = node === null || node === void 0 ? void 0 : node.text) === null || _a === void 0 ? void 0 : _a.slice(Math.max(from2, pos) - pos, to - pos); 12910 } 12911 }); 12912 return text; 12913} 12914function getTextSerializersFromSchema(schema) { 12915 return Object.fromEntries(Object.entries(schema.nodes).filter(([, node]) => node.spec.toText).map(([name, node]) => [name, node.spec.toText])); 12916} 12917const ClipboardTextSerializer = Extension.create({ 12918 name: "clipboardTextSerializer", 12919 addOptions() { 12920 return { 12921 blockSeparator: void 0 12922 }; 12923 }, 12924 addProseMirrorPlugins() { 12925 return [ 12926 new Plugin({ 12927 key: new PluginKey("clipboardTextSerializer"), 12928 props: { 12929 clipboardTextSerializer: () => { 12930 const { editor } = this; 12931 const { state, schema } = editor; 12932 const { doc: doc2, selection } = state; 12933 const { ranges } = selection; 12934 const from2 = Math.min(...ranges.map((range2) => range2.$from.pos)); 12935 const to = Math.max(...ranges.map((range2) => range2.$to.pos)); 12936 const textSerializers = getTextSerializersFromSchema(schema); 12937 const range = { from: from2, to }; 12938 return getTextBetween(doc2, range, { 12939 ...this.options.blockSeparator !== void 0 ? { blockSeparator: this.options.blockSeparator } : {}, 12940 textSerializers 12941 }); 12942 } 12943 } 12944 }) 12945 ]; 12946 } 12947}); 12948const blur = () => ({ editor, view }) => { 12949 requestAnimationFrame(() => { 12950 var _a; 12951 if (!editor.isDestroyed) { 12952 view.dom.blur(); 12953 (_a = window === null || window === void 0 ? void 0 : window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges(); 12954 } 12955 }); 12956 return true; 12957}; 12958const clearContent = (emitUpdate = false) => ({ commands: commands2 }) => { 12959 return commands2.setContent("", emitUpdate); 12960}; 12961const clearNodes = () => ({ state, tr: tr2, dispatch }) => { 12962 const { selection } = tr2; 12963 const { ranges } = selection; 12964 if (!dispatch) { 12965 return true; 12966 } 12967 ranges.forEach(({ $from, $to }) => { 12968 state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => { 12969 if (node.type.isText) { 12970 return; 12971 } 12972 const { doc: doc2, mapping } = tr2; 12973 const $mappedFrom = doc2.resolve(mapping.map(pos)); 12974 const $mappedTo = doc2.resolve(mapping.map(pos + node.nodeSize)); 12975 const nodeRange = $mappedFrom.blockRange($mappedTo); 12976 if (!nodeRange) { 12977 return; 12978 } 12979 const targetLiftDepth = liftTarget(nodeRange); 12980 if (node.type.isTextblock) { 12981 const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index()); 12982 tr2.setNodeMarkup(nodeRange.start, defaultType); 12983 } 12984 if (targetLiftDepth || targetLiftDepth === 0) { 12985 tr2.lift(nodeRange, targetLiftDepth); 12986 } 12987 }); 12988 }); 12989 return true; 12990}; 12991const command = (fn2) => (props) => { 12992 return fn2(props); 12993}; 12994const createParagraphNear = () => ({ state, dispatch }) => { 12995 return createParagraphNear$1(state, dispatch); 12996}; 12997const cut = (originRange, targetPos) => ({ editor, tr: tr2 }) => { 12998 const { state } = editor; 12999 const contentSlice = state.doc.slice(originRange.from, originRange.to); 13000 tr2.deleteRange(originRange.from, originRange.to); 13001 const newPos = tr2.mapping.map(targetPos); 13002 tr2.insert(newPos, contentSlice.content); 13003 tr2.setSelection(new TextSelection(tr2.doc.resolve(newPos - 1))); 13004 return true; 13005}; 13006const deleteCurrentNode = () => ({ tr: tr2, dispatch }) => { 13007 const { selection } = tr2; 13008 const currentNode = selection.$anchor.node(); 13009 if (currentNode.content.size > 0) { 13010 return false;
13011 } 13012 const $pos = tr2.selection.$anchor; 13013 for (let depth = $pos.depth; depth > 0; depth -= 1) { 13014 const node = $pos.node(depth); 13015 if (node.type === currentNode.type) { 13016 if (dispatch) { 13017 const from2 = $pos.before(depth); 13018 const to = $pos.after(depth); 13019 tr2.delete(from2, to).scrollIntoView(); 13020 } 13021 return true; 13022 } 13023 } 13024 return false; 13025}; 13026const deleteNode = (typeOrName) => ({ tr: tr2, state, dispatch }) => { 13027 const type = getNodeType(typeOrName, state.schema); 13028 const $pos = tr2.selection.$anchor; 13029 for (let depth = $pos.depth; depth > 0; depth -= 1) { 13030 const node = $pos.node(depth); 13031 if (node.type === type) { 13032 if (dispatch) { 13033 const from2 = $pos.before(depth); 13034 const to = $pos.after(depth); 13035 tr2.delete(from2, to).scrollIntoView(); 13036 } 13037 return true; 13038 } 13039 } 13040 return false; 13041}; 13042const deleteRange = (range) => ({ tr: tr2, dispatch }) => { 13043 const { from: from2, to } = range; 13044 if (dispatch) { 13045 tr2.delete(from2, to); 13046 } 13047 return true; 13048}; 13049const deleteSelection = () => ({ state, dispatch }) => { 13050 return deleteSelection$1(state, dispatch); 13051}; 13052const enter = () => ({ commands: commands2 }) => { 13053 return commands2.keyboardShortcut("Enter"); 13054}; 13055const exitCode = () => ({ state, dispatch }) => { 13056 return exitCode$1(state, dispatch); 13057}; 13058function objectIncludes(object1, object2, options = { strict: true }) { 13059 const keys2 = Object.keys(object2); 13060 if (!keys2.length) { 13061 return true; 13062 } 13063 return keys2.every((key) => { 13064 if (options.strict) { 13065 return object2[key] === object1[key]; 13066 } 13067 if (isRegExp(object2[key])) { 13068 return object2[key].test(object1[key]); 13069 } 13070 return object2[key] === object1[key]; 13071 }); 13072} 13073function findMarkInSet(marks, type, attributes = {}) { 13074 return marks.find((item) => { 13075 return item.type === type && objectIncludes(item.attrs, attributes); 13076 }); 13077} 13078function isMarkInSet(marks, type, attributes = {}) { 13079 return !!findMarkInSet(marks, type, attributes); 13080} 13081function getMarkRange($pos, type, attributes = {}) { 13082 if (!$pos || !type) { 13083 return; 13084 } 13085 let start2 = $pos.parent.childAfter($pos.parentOffset); 13086 if ($pos.parentOffset === start2.offset && start2.offset !== 0) { 13087 start2 = $pos.parent.childBefore($pos.parentOffset); 13088 } 13089 if (!start2.node) { 13090 return; 13091 } 13092 const mark = findMarkInSet([...start2.node.marks], type, attributes); 13093 if (!mark) { 13094 return; 13095 } 13096 let startIndex = start2.index; 13097 let startPos = $pos.start() + start2.offset; 13098 let endIndex = startIndex + 1; 13099 let endPos = startPos + start2.node.nodeSize; 13100 findMarkInSet([...start2.node.marks], type, attributes); 13101 while (startIndex > 0 && mark.isInSet($pos.parent.child(startIndex - 1).marks)) { 13102 startIndex -= 1; 13103 startPos -= $pos.parent.child(startIndex).nodeSize; 13104 } 13105 while (endIndex < $pos.parent.childCount && isMarkInSet([...$pos.parent.child(endIndex).marks], type, attributes)) { 13106 endPos += $pos.parent.child(endIndex).nodeSize; 13107 endIndex += 1; 13108 } 13109 return { 13110 from: startPos, 13111 to: endPos 13112 }; 13113} 13114function getMarkType(nameOrType, schema) { 13115 if (typeof nameOrType === "string") { 13116 if (!schema.marks[nameOrType]) { 13117 throw Error(`There is no mark type named '${nameOrType}'. Maybe you forgot to add the extension?`); 13118 } 13119 return schema.marks[nameOrType]; 13120 } 13121 return nameOrType; 13122} 13123const extendMarkRange = (typeOrName, attributes = {}) => ({ tr: tr2, state, dispatch }) => { 13124 const type = getMarkType(typeOrName, state.schema); 13125 const { doc: doc2, selection } = tr2; 13126 const { $from, from: from2, to } = selection; 13127 if (dispatch) { 13128 const range = getMarkRange($from, type, attributes); 13129 if (range && range.from <= from2 && range.to >= to) { 13130 const newSelection = TextSelection.create(doc2, range.from, range.to); 13131 tr2.setSelection(newSelection); 13132 } 13133 } 13134 return true; 13135}; 13136const first = (commands2) => (props) => { 13137 const items = typeof commands2 === "function" ? commands2(props) : commands2; 13138 for (let i = 0; i < items.length; i += 1) { 13139 if (items[i](props)) { 13140 return true; 13141 } 13142 } 13143 return false;
13144}; 13145function isTextSelection(value) { 13146 return value instanceof TextSelection; 13147} 13148function minMax(value = 0, min2 = 0, max2 = 0) { 13149 return Math.min(Math.max(value, min2), max2); 13150} 13151function resolveFocusPosition(doc2, position = null) { 13152 if (!position) { 13153 return null; 13154 } 13155 const selectionAtStart = Selection.atStart(doc2); 13156 const selectionAtEnd = Selection.atEnd(doc2); 13157 if (position === "start" || position === true) { 13158 return selectionAtStart; 13159 } 13160 if (position === "end") { 13161 return selectionAtEnd; 13162 } 13163 const minPos = selectionAtStart.from; 13164 const maxPos = selectionAtEnd.to; 13165 if (position === "all") { 13166 return TextSelection.create(doc2, minMax(0, minPos, maxPos), minMax(doc2.content.size, minPos, maxPos)); 13167 } 13168 return TextSelection.create(doc2, minMax(position, minPos, maxPos), minMax(position, minPos, maxPos)); 13169} 13170function isiOS() { 13171 return [ 13172 "iPad Simulator", 13173 "iPhone Simulator", 13174 "iPod Simulator", 13175 "iPad", 13176 "iPhone", 13177 "iPod" 13178 ].includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document; 13179} 13180const focus = (position = null, options = {}) => ({ editor, view, tr: tr2, dispatch }) => { 13181 options = { 13182 scrollIntoView: true, 13183 ...options 13184 }; 13185 const delayedFocus = () => { 13186 if (isiOS()) { 13187 view.dom.focus(); 13188 } 13189 requestAnimationFrame(() => { 13190 if (!editor.isDestroyed) { 13191 view.focus(); 13192 if (options === null || options === void 0 ? void 0 : options.scrollIntoView) { 13193 editor.commands.scrollIntoView(); 13194 } 13195 } 13196 }); 13197 }; 13198 if (view.hasFocus() && position === null || position === false) { 13199 return true; 13200 } 13201 if (dispatch && position === null && !isTextSelection(editor.state.selection)) { 13202 delayedFocus(); 13203 return true; 13204 } 13205 const selection = resolveFocusPosition(tr2.doc, position) || editor.state.selection; 13206 const isSameSelection = editor.state.selection.eq(selection); 13207 if (dispatch) { 13208 if (!isSameSelection) { 13209 tr2.setSelection(selection); 13210 } 13211 if (isSameSelection && tr2.storedMarks) { 13212 tr2.setStoredMarks(tr2.storedMarks); 13213 } 13214 delayedFocus(); 13215 } 13216 return true; 13217}; 13218const forEach = (items, fn2) => (props) => { 13219 return items.every((item, index) => fn2(item, { ...props, index })); 13220}; 13221const insertContent = (value, options) => ({ tr: tr2, commands: commands2 }) => { 13222 return commands2.insertContentAt({ from: tr2.selection.from, to: tr2.selection.to }, value, options); 13223}; 13224const removeWhitespaces = (node) => { 13225 const children = node.childNodes; 13226 for (let i = children.length - 1; i >= 0; i -= 1) { 13227 const child = children[i]; 13228 if (child.nodeType === 3 && child.nodeValue && /^(\n\s\s|\n)$/.test(child.nodeValue)) { 13229 node.removeChild(child); 13230 } else if (child.nodeType === 1) { 13231 removeWhitespaces(child); 13232 } 13233 } 13234 return node; 13235}; 13236function elementFromString(value) { 13237 const wrappedValue = `<body>${value}</body>`; 13238 const html = new window.DOMParser().parseFromString(wrappedValue, "text/html").body; 13239 return removeWhitespaces(html); 13240} 13241function createNodeFromContent(content, schema, options) { 13242 options = { 13243 slice: true, 13244 parseOptions: {}, 13245 ...options 13246 }; 13247 const isJSONContent = typeof content === "object" && content !== null; 13248 const isTextContent = typeof content === "string"; 13249 if (isJSONContent) { 13250 try { 13251 const isArrayContent = Array.isArray(content) && content.length > 0; 13252 if (isArrayContent) { 13253 return Fragment.fromArray(content.map((item) => schema.nodeFromJSON(item))); 13254 } 13255 return schema.nodeFromJSON(content); 13256 } catch (error) { 13257 console.warn("[tiptap warn]: Invalid content.", "Passed value:", content, "Error:", error); 13258 return createNodeFromContent("", schema, options); 13259 } 13260 } 13261 if (isTextContent) { 13262 const parser = DOMParser.fromSchema(schema); 13263 return options.slice ? parser.parseSlice(elementFromString(content), options.parseOptions).content : parser.parse(elementFromString(content), options.parseOptions); 13264 } 13265 return createNodeFromContent("", schema, options); 13266} 13267function selectionToInsertionEnd(tr2, startLen, bias) { 13268 const last = tr2.steps.length - 1; 13269 if (last < startLen) { 13270 return; 13271 } 13272 const step = tr2.steps[last]; 13273 if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) { 13274 return; 13275 } 13276 const map2 = tr2.mapping.maps[last]; 13277 let end2 = 0; 13278 map2.forEach((_from, _to, _newFrom, newTo) => { 13279 if (end2 === 0) { 13280 end2 = newTo; 13281 } 13282 }); 13283 tr2.setSelection(Selection.near(tr2.doc.resolve(end2), bias)); 13284} 13285const isFragment = (nodeOrFragment) => { 13286 return nodeOrFragment.toString().startsWith("<"); 13287}; 13288const insertContentAt = (position, value, options) => ({ tr: tr2, dispatch, editor }) => {
13289 if (dispatch) { 13290 options = { 13291 parseOptions: {}, 13292 updateSelection: true, 13293 applyInputRules: false, 13294 applyPasteRules: false, 13295 ...options 13296 }; 13297 const content = createNodeFromContent(value, editor.schema, { 13298 parseOptions: { 13299 preserveWhitespace: "full", 13300 ...options.parseOptions 13301 } 13302 }); 13303 if (content.toString() === "<>") { 13304 return true; 13305 } 13306 let { from: from2, to } = typeof position === "number" ? { from: position, to: position } : { from: position.from, to: position.to }; 13307 let isOnlyTextContent = true; 13308 let isOnlyBlockContent = true; 13309 const nodes = isFragment(content) ? content : [content]; 13310 nodes.forEach((node) => { 13311 node.check(); 13312 isOnlyTextContent = isOnlyTextContent ? node.isText && node.marks.length === 0 : false; 13313 isOnlyBlockContent = isOnlyBlockContent ? node.isBlock : false; 13314 }); 13315 if (from2 === to && isOnlyBlockContent) { 13316 const { parent } = tr2.doc.resolve(from2); 13317 const isEmptyTextBlock = parent.isTextblock && !parent.type.spec.code && !parent.childCount; 13318 if (isEmptyTextBlock) { 13319 from2 -= 1; 13320 to += 1; 13321 } 13322 } 13323 let newContent; 13324 if (isOnlyTextContent) { 13325 if (Array.isArray(value)) { 13326 newContent = value.map((v) => v.text || "").join(""); 13327 } else if (typeof value === "object" && !!value && !!value.text) { 13328 newContent = value.text; 13329 } else { 13330 newContent = value; 13331 } 13332 tr2.insertText(newContent, from2, to); 13333 } else { 13334 newContent = content; 13335 tr2.replaceWith(from2, to, newContent); 13336 } 13337 if (options.updateSelection) { 13338 selectionToInsertionEnd(tr2, tr2.steps.length - 1, -1); 13339 } 13340 if (options.applyInputRules) { 13341 tr2.setMeta("applyInputRules", { from: from2, text: newContent }); 13342 } 13343 if (options.applyPasteRules) { 13344 tr2.setMeta("applyPasteRules", { from: from2, text: newContent }); 13345 } 13346 } 13347 return true; 13348}; 13349const joinUp = () => ({ state, dispatch }) => { 13350 return joinUp$1(state, dispatch); 13351}; 13352const joinDown = () => ({ state, dispatch }) => { 13353 return joinDown$1(state, dispatch); 13354}; 13355const joinBackward = () => ({ state, dispatch }) => { 13356 return joinBackward$1(state, dispatch); 13357}; 13358const joinForward = () => ({ state, dispatch }) => { 13359 return joinForward$1(state, dispatch); 13360}; 13361const joinItemBackward = () => ({ tr: tr2, state, dispatch }) => { 13362 try { 13363 const point = joinPoint(state.doc, state.selection.$from.pos, -1); 13364 if (point === null || point === void 0) { 13365 return false; 13366 } 13367 tr2.join(point, 2); 13368 if (dispatch) { 13369 dispatch(tr2); 13370 } 13371 return true; 13372 } catch { 13373 return false; 13374 } 13375}; 13376const joinItemForward = () => ({ state, dispatch, tr: tr2 }) => { 13377 try { 13378 const point = joinPoint(state.doc, state.selection.$from.pos, 1); 13379 if (point === null || point === void 0) { 13380 return false; 13381 } 13382 tr2.join(point, 2); 13383 if (dispatch) { 13384 dispatch(tr2); 13385 } 13386 return true; 13387 } catch (e) { 13388 return false; 13389 } 13390}; 13391const joinTextblockBackward = () => ({ state, dispatch }) => { 13392 return joinTextblockBackward$1(state, dispatch); 13393}; 13394const joinTextblockForward = () => ({ state, dispatch }) => { 13395 return joinTextblockForward$1(state, dispatch); 13396}; 13397function isMacOS() { 13398 return typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; 13399} 13400function normalizeKeyName(name) { 13401 const parts = name.split(/-(?!$)/); 13402 let result = parts[parts.length - 1]; 13403 if (result === "Space") { 13404 result = " "; 13405 } 13406 let alt; 13407 let ctrl; 13408 let shift2; 13409 let meta; 13410 for (let i = 0; i < parts.length - 1; i += 1) { 13411 const mod = parts[i]; 13412 if (/^(cmd|meta|m)$/i.test(mod)) { 13413 meta = true; 13414 } else if (/^a(lt)?$/i.test(mod)) { 13415 alt = true; 13416 } else if (/^(c|ctrl|control)$/i.test(mod)) { 13417 ctrl = true; 13418 } else if (/^s(hift)?$/i.test(mod)) { 13419 shift2 = true; 13420 } else if (/^mod$/i.test(mod)) { 13421 if (isiOS() || isMacOS()) { 13422 meta = true; 13423 } else { 13424 ctrl = true; 13425 } 13426 } else { 13427 throw new Error(`Unrecognized modifier name: ${mod}`); 13428 } 13429 } 13430 if (alt) { 13431 result = `Alt-${result}`; 13432 } 13433 if (ctrl) { 13434 result = `Ctrl-${result}`; 13435 } 13436 if (meta) { 13437 result = `Meta-${result}`; 13438 } 13439 if (shift2) { 13440 result = `Shift-${result}`; 13441 } 13442 return result; 13443} 13444const keyboardShortcut = (name) => ({ editor, view, tr: tr2, dispatch }) => { 13445 const keys2 = normalizeKeyName(name).split(/-(?!$)/); 13446 const key = keys2.find((item) => !["Alt", "Ctrl", "Meta", "Shift"].includes(item)); 13447 const event = new KeyboardEvent("keydown", { 13448 key: key === "Space" ? " " : key, 13449 altKey: keys2.includes("Alt"), 13450 ctrlKey: keys2.includes("Ctrl"), 13451 metaKey: keys2.includes("Meta"),
13452 shiftKey: keys2.includes("Shift"), 13453 bubbles: true, 13454 cancelable: true 13455 }); 13456 const capturedTransaction = editor.captureTransaction(() => { 13457 view.someProp("handleKeyDown", (f) => f(view, event)); 13458 }); 13459 capturedTransaction === null || capturedTransaction === void 0 ? void 0 : capturedTransaction.steps.forEach((step) => { 13460 const newStep = step.map(tr2.mapping); 13461 if (newStep && dispatch) { 13462 tr2.maybeStep(newStep); 13463 } 13464 }); 13465 return true; 13466}; 13467function isNodeActive(state, typeOrName, attributes = {}) { 13468 const { from: from2, to, empty: empty2 } = state.selection; 13469 const type = typeOrName ? getNodeType(typeOrName, state.schema) : null; 13470 const nodeRanges = []; 13471 state.doc.nodesBetween(from2, to, (node, pos) => { 13472 if (node.isText) { 13473 return; 13474 } 13475 const relativeFrom = Math.max(from2, pos); 13476 const relativeTo = Math.min(to, pos + node.nodeSize); 13477 nodeRanges.push({ 13478 node, 13479 from: relativeFrom, 13480 to: relativeTo 13481 }); 13482 }); 13483 const selectionRange = to - from2; 13484 const matchedNodeRanges = nodeRanges.filter((nodeRange) => { 13485 if (!type) { 13486 return true; 13487 } 13488 return type.name === nodeRange.node.type.name; 13489 }).filter((nodeRange) => objectIncludes(nodeRange.node.attrs, attributes, { strict: false })); 13490 if (empty2) { 13491 return !!matchedNodeRanges.length; 13492 } 13493 const range = matchedNodeRanges.reduce((sum, nodeRange) => sum + nodeRange.to - nodeRange.from, 0); 13494 return range >= selectionRange; 13495} 13496const lift = (typeOrName, attributes = {}) => ({ state, dispatch }) => { 13497 const type = getNodeType(typeOrName, state.schema); 13498 const isActive2 = isNodeActive(state, type, attributes); 13499 if (!isActive2) { 13500 return false; 13501 } 13502 return lift$1(state, dispatch); 13503}; 13504const liftEmptyBlock = () => ({ state, dispatch }) => { 13505 return liftEmptyBlock$1(state, dispatch); 13506}; 13507const liftListItem = (typeOrName) => ({ state, dispatch }) => { 13508 const type = getNodeType(typeOrName, state.schema); 13509 return liftListItem$1(type)(state, dispatch); 13510}; 13511const newlineInCode = () => ({ state, dispatch }) => { 13512 return newlineInCode$1(state, dispatch); 13513}; 13514function getSchemaTypeNameByName(name, schema) { 13515 if (schema.nodes[name]) { 13516 return "node"; 13517 } 13518 if (schema.marks[name]) { 13519 return "mark"; 13520 } 13521 return null; 13522} 13523function deleteProps(obj, propOrProps) { 13524 const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps; 13525 return Object.keys(obj).reduce((newObj, prop) => { 13526 if (!props.includes(prop)) { 13527 newObj[prop] = obj[prop]; 13528 } 13529 return newObj; 13530 }, {}); 13531} 13532const resetAttributes = (typeOrName, attributes) => ({ tr: tr2, state, dispatch }) => { 13533 let nodeType = null; 13534 let markType = null; 13535 const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema); 13536 if (!schemaType) { 13537 return false; 13538 } 13539 if (schemaType === "node") { 13540 nodeType = getNodeType(typeOrName, state.schema); 13541 } 13542 if (schemaType === "mark") { 13543 markType = getMarkType(typeOrName, state.schema); 13544 } 13545 if (dispatch) { 13546 tr2.selection.ranges.forEach((range) => { 13547 state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => { 13548 if (nodeType && nodeType === node.type) { 13549 tr2.setNodeMarkup(pos, void 0, deleteProps(node.attrs, attributes)); 13550 } 13551 if (markType && node.marks.length) { 13552 node.marks.forEach((mark) => { 13553 if (markType === mark.type) { 13554 tr2.addMark(pos, pos + node.nodeSize, markType.create(deleteProps(mark.attrs, attributes))); 13555 } 13556 }); 13557 } 13558 }); 13559 }); 13560 } 13561 return true; 13562}; 13563const scrollIntoView = () => ({ tr: tr2, dispatch }) => { 13564 if (dispatch) { 13565 tr2.scrollIntoView(); 13566 } 13567 return true; 13568}; 13569const selectAll = () => ({ tr: tr2, commands: commands2 }) => { 13570 return commands2.setTextSelection({ 13571 from: 0, 13572 to: tr2.doc.content.size 13573 }); 13574}; 13575const selectNodeBackward = () => ({ state, dispatch }) => { 13576 return selectNodeBackward$1(state, dispatch); 13577}; 13578const selectNodeForward = () => ({ state, dispatch }) => { 13579 return selectNodeForward$1(state, dispatch); 13580}; 13581const selectParentNode = () => ({ state, dispatch }) => { 13582 return selectParentNode$1(state, dispatch); 13583}; 13584const selectTextblockEnd = () => ({ state, dispatch }) => { 13585 return selectTextblockEnd$1(state, dispatch); 13586}; 13587const selectTextblockStart = () => ({ state, dispatch }) => { 13588 return selectTextblockStart$1(state, dispatch); 13589}; 13590function createDocument(content, schema, parseOptions = {}) { 13591 return createNodeFromContent(content, schema, { slice: false, parseOptions }); 13592} 13593const setContent$1 = (content, emitUpdate = false, parseOptions = {}) => ({ tr: tr2, editor, dispatch }) => { 13594 const { doc: doc2 } = tr2; 13595 const document2 = createDocument(content, editor.schema, parseOptions);
13596 if (dispatch) { 13597 tr2.replaceWith(0, doc2.content.size, document2).setMeta("preventUpdate", !emitUpdate); 13598 } 13599 return true; 13600}; 13601function getMarkAttributes(state, typeOrName) { 13602 const type = getMarkType(typeOrName, state.schema); 13603 const { from: from2, to, empty: empty2 } = state.selection; 13604 const marks = []; 13605 if (empty2) { 13606 if (state.storedMarks) { 13607 marks.push(...state.storedMarks); 13608 } 13609 marks.push(...state.selection.$head.marks()); 13610 } else { 13611 state.doc.nodesBetween(from2, to, (node) => { 13612 marks.push(...node.marks); 13613 }); 13614 } 13615 const mark = marks.find((markItem) => markItem.type.name === type.name); 13616 if (!mark) { 13617 return {}; 13618 } 13619 return { ...mark.attrs }; 13620} 13621function combineTransactionSteps(oldDoc, transactions) { 13622 const transform = new Transform(oldDoc); 13623 transactions.forEach((transaction) => { 13624 transaction.steps.forEach((step) => { 13625 transform.step(step); 13626 }); 13627 }); 13628 return transform; 13629} 13630function defaultBlockAt(match) { 13631 for (let i = 0; i < match.edgeCount; i += 1) { 13632 const { type } = match.edge(i); 13633 if (type.isTextblock && !type.hasRequiredAttrs()) { 13634 return type; 13635 } 13636 } 13637 return null; 13638} 13639function findChildrenInRange(node, range, predicate) { 13640 const nodesWithPos = []; 13641 node.nodesBetween(range.from, range.to, (child, pos) => { 13642 if (predicate(child)) { 13643 nodesWithPos.push({ 13644 node: child, 13645 pos 13646 }); 13647 } 13648 }); 13649 return nodesWithPos; 13650} 13651function findParentNodeClosestToPos($pos, predicate) { 13652 for (let i = $pos.depth; i > 0; i -= 1) { 13653 const node = $pos.node(i); 13654 if (predicate(node)) { 13655 return { 13656 pos: i > 0 ? $pos.before(i) : 0, 13657 start: $pos.start(i), 13658 depth: i, 13659 node 13660 }; 13661 } 13662 } 13663} 13664function findParentNode(predicate) { 13665 return (selection) => findParentNodeClosestToPos(selection.$from, predicate); 13666} 13667function getHTMLFromFragment(fragment, schema) { 13668 const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment); 13669 const temporaryDocument = document.implementation.createHTMLDocument(); 13670 const container = temporaryDocument.createElement("div"); 13671 container.appendChild(documentFragment); 13672 return container.innerHTML; 13673} 13674function getText(node, options) { 13675 const range = { 13676 from: 0, 13677 to: node.content.size 13678 }; 13679 return getTextBetween(node, range, options); 13680} 13681function getNodeAttributes(state, typeOrName) { 13682 const type = getNodeType(typeOrName, state.schema); 13683 const { from: from2, to } = state.selection; 13684 const nodes = []; 13685 state.doc.nodesBetween(from2, to, (node2) => { 13686 nodes.push(node2); 13687 }); 13688 const node = nodes.reverse().find((nodeItem) => nodeItem.type.name === type.name); 13689 if (!node) { 13690 return {}; 13691 } 13692 return { ...node.attrs }; 13693} 13694function getAttributes(state, typeOrName) { 13695 const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema); 13696 if (schemaType === "node") { 13697 return getNodeAttributes(state, typeOrName); 13698 } 13699 if (schemaType === "mark") { 13700 return getMarkAttributes(state, typeOrName); 13701 } 13702 return {}; 13703} 13704function removeDuplicates(array, by = JSON.stringify) { 13705 const seen = {}; 13706 return array.filter((item) => { 13707 const key = by(item); 13708 return Object.prototype.hasOwnProperty.call(seen, key) ? false : seen[key] = true; 13709 }); 13710} 13711function simplifyChangedRanges(changes) { 13712 const uniqueChanges = removeDuplicates(changes); 13713 return uniqueChanges.length === 1 ? uniqueChanges : uniqueChanges.filter((change, index) => { 13714 const rest = uniqueChanges.filter((_, i) => i !== index); 13715 return !rest.some((otherChange) => { 13716 return change.oldRange.from >= otherChange.oldRange.from && change.oldRange.to <= otherChange.oldRange.to && change.newRange.from >= otherChange.newRange.from && change.newRange.to <= otherChange.newRange.to; 13717 }); 13718 }); 13719} 13720function getChangedRanges(transform) { 13721 const { mapping, steps } = transform; 13722 const changes = []; 13723 mapping.maps.forEach((stepMap, index) => { 13724 const ranges = []; 13725 if (!stepMap.ranges.length) { 13726 const { from: from2, to } = steps[index]; 13727 if (from2 === void 0 || to === void 0) { 13728 return; 13729 } 13730 ranges.push({ from: from2, to }); 13731 } else {
13732 stepMap.forEach((from2, to) => { 13733 ranges.push({ from: from2, to }); 13734 }); 13735 } 13736 ranges.forEach(({ from: from2, to }) => { 13737 const newStart = mapping.slice(index).map(from2, -1); 13738 const newEnd = mapping.slice(index).map(to); 13739 const oldStart = mapping.invert().map(newStart, -1); 13740 const oldEnd = mapping.invert().map(newEnd); 13741 changes.push({ 13742 oldRange: { 13743 from: oldStart, 13744 to: oldEnd 13745 }, 13746 newRange: { 13747 from: newStart, 13748 to: newEnd 13749 } 13750 }); 13751 }); 13752 }); 13753 return simplifyChangedRanges(changes); 13754} 13755function getMarksBetween(from2, to, doc2) { 13756 const marks = []; 13757 if (from2 === to) { 13758 doc2.resolve(from2).marks().forEach((mark) => { 13759 const $pos = doc2.resolve(from2 - 1); 13760 const range = getMarkRange($pos, mark.type); 13761 if (!range) { 13762 return; 13763 } 13764 marks.push({ 13765 mark, 13766 ...range 13767 }); 13768 }); 13769 } else { 13770 doc2.nodesBetween(from2, to, (node, pos) => { 13771 if (!node || (node === null || node === void 0 ? void 0 : node.nodeSize) === void 0) { 13772 return; 13773 } 13774 marks.push(...node.marks.map((mark) => ({ 13775 from: pos, 13776 to: pos + node.nodeSize, 13777 mark 13778 }))); 13779 }); 13780 } 13781 return marks; 13782} 13783function getSplittedAttributes(extensionAttributes, typeName, attributes) { 13784 return Object.fromEntries(Object.entries(attributes).filter(([name]) => { 13785 const extensionAttribute = extensionAttributes.find((item) => { 13786 return item.type === typeName && item.name === name; 13787 }); 13788 if (!extensionAttribute) { 13789 return false; 13790 } 13791 return extensionAttribute.attribute.keepOnSplit; 13792 })); 13793} 13794function isMarkActive(state, typeOrName, attributes = {}) { 13795 const { empty: empty2, ranges } = state.selection; 13796 const type = typeOrName ? getMarkType(typeOrName, state.schema) : null; 13797 if (empty2) { 13798 return !!(state.storedMarks || state.selection.$from.marks()).filter((mark) => { 13799 if (!type) { 13800 return true; 13801 } 13802 return type.name === mark.type.name; 13803 }).find((mark) => objectIncludes(mark.attrs, attributes, { strict: false })); 13804 } 13805 let selectionRange = 0; 13806 const markRanges = []; 13807 ranges.forEach(({ $from, $to }) => { 13808 const from2 = $from.pos; 13809 const to = $to.pos; 13810 state.doc.nodesBetween(from2, to, (node, pos) => { 13811 if (!node.isText && !node.marks.length) { 13812 return; 13813 } 13814 const relativeFrom = Math.max(from2, pos); 13815 const relativeTo = Math.min(to, pos + node.nodeSize); 13816 const range2 = relativeTo - relativeFrom; 13817 selectionRange += range2; 13818 markRanges.push(...node.marks.map((mark) => ({ 13819 mark, 13820 from: relativeFrom, 13821 to: relativeTo 13822 }))); 13823 }); 13824 }); 13825 if (selectionRange === 0) { 13826 return false; 13827 } 13828 const matchedRange = markRanges.filter((markRange) => { 13829 if (!type) { 13830 return true; 13831 } 13832 return type.name === markRange.mark.type.name; 13833 }).filter((markRange) => objectIncludes(markRange.mark.attrs, attributes, { strict: false })).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0); 13834 const excludedRange = markRanges.filter((markRange) => { 13835 if (!type) { 13836 return true; 13837 } 13838 return markRange.mark.type !== type && markRange.mark.type.excludes(type); 13839 }).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0); 13840 const range = matchedRange > 0 ? matchedRange + excludedRange : matchedRange; 13841 return range >= selectionRange; 13842} 13843function isActive(state, name, attributes = {}) { 13844 if (!name) { 13845 return isNodeActive(state, null, attributes) || isMarkActive(state, null, attributes); 13846 } 13847 const schemaType = getSchemaTypeNameByName(name, state.schema); 13848 if (schemaType === "node") { 13849 return isNodeActive(state, name, attributes); 13850 } 13851 if (schemaType === "mark") { 13852 return isMarkActive(state, name, attributes); 13853 } 13854 return false; 13855} 13856function isList(name, extensions) { 13857 const { nodeExtensions } = splitExtensions(extensions); 13858 const extension = nodeExtensions.find((item) => item.name === name); 13859 if (!extension) { 13860 return false;
13861 } 13862 const context = { 13863 name: extension.name, 13864 options: extension.options, 13865 storage: extension.storage 13866 }; 13867 const group = callOrReturn(getExtensionField(extension, "group", context)); 13868 if (typeof group !== "string") { 13869 return false; 13870 } 13871 return group.split(" ").includes("list"); 13872} 13873function isNodeEmpty(node) { 13874 var _a; 13875 const defaultContent = (_a = node.type.createAndFill()) === null || _a === void 0 ? void 0 : _a.toJSON(); 13876 const content = node.toJSON(); 13877 return JSON.stringify(defaultContent) === JSON.stringify(content); 13878} 13879function isNodeSelection(value) { 13880 return value instanceof NodeSelection; 13881} 13882function posToDOMRect(view, from2, to) { 13883 const minPos = 0; 13884 const maxPos = view.state.doc.content.size; 13885 const resolvedFrom = minMax(from2, minPos, maxPos); 13886 const resolvedEnd = minMax(to, minPos, maxPos); 13887 const start2 = view.coordsAtPos(resolvedFrom); 13888 const end2 = view.coordsAtPos(resolvedEnd, -1); 13889 const top2 = Math.min(start2.top, end2.top); 13890 const bottom2 = Math.max(start2.bottom, end2.bottom); 13891 const left2 = Math.min(start2.left, end2.left); 13892 const right2 = Math.max(start2.right, end2.right); 13893 const width = right2 - left2; 13894 const height = bottom2 - top2; 13895 const x = left2; 13896 const y = top2; 13897 const data = { 13898 top: top2, 13899 bottom: bottom2, 13900 left: left2, 13901 right: right2, 13902 width, 13903 height, 13904 x, 13905 y 13906 }; 13907 return { 13908 ...data, 13909 toJSON: () => data 13910 }; 13911} 13912function canSetMark(state, tr2, newMarkType) { 13913 var _a; 13914 const { selection } = tr2; 13915 let cursor = null; 13916 if (isTextSelection(selection)) { 13917 cursor = selection.$cursor; 13918 } 13919 if (cursor) { 13920 const currentMarks = (_a = state.storedMarks) !== null && _a !== void 0 ? _a : cursor.marks(); 13921 return !!newMarkType.isInSet(currentMarks) || !currentMarks.some((mark) => mark.type.excludes(newMarkType)); 13922 } 13923 const { ranges } = selection; 13924 return ranges.some(({ $from, $to }) => { 13925 let someNodeSupportsMark = $from.depth === 0 ? state.doc.inlineContent && state.doc.type.allowsMarkType(newMarkType) : false; 13926 state.doc.nodesBetween($from.pos, $to.pos, (node, _pos, parent) => { 13927 if (someNodeSupportsMark) { 13928 return false; 13929 } 13930 if (node.isInline) { 13931 const parentAllowsMarkType = !parent || parent.type.allowsMarkType(newMarkType); 13932 const currentMarksAllowMarkType = !!newMarkType.isInSet(node.marks) || !node.marks.some((otherMark) => otherMark.type.excludes(newMarkType)); 13933 someNodeSupportsMark = parentAllowsMarkType && currentMarksAllowMarkType; 13934 } 13935 return !someNodeSupportsMark; 13936 }); 13937 return someNodeSupportsMark; 13938 }); 13939} 13940const setMark = (typeOrName, attributes = {}) => ({ tr: tr2, state, dispatch }) => { 13941 const { selection } = tr2; 13942 const { empty: empty2, ranges } = selection; 13943 const type = getMarkType(typeOrName, state.schema); 13944 if (dispatch) { 13945 if (empty2) { 13946 const oldAttributes = getMarkAttributes(state, type); 13947 tr2.addStoredMark(type.create({ 13948 ...oldAttributes, 13949 ...attributes 13950 })); 13951 } else { 13952 ranges.forEach((range) => { 13953 const from2 = range.$from.pos; 13954 const to = range.$to.pos; 13955 state.doc.nodesBetween(from2, to, (node, pos) => { 13956 const trimmedFrom = Math.max(pos, from2); 13957 const trimmedTo = Math.min(pos + node.nodeSize, to); 13958 const someHasMark = node.marks.find((mark) => mark.type === type); 13959 if (someHasMark) { 13960 node.marks.forEach((mark) => { 13961 if (type === mark.type) { 13962 tr2.addMark(trimmedFrom, trimmedTo, type.create({ 13963 ...mark.attrs, 13964 ...attributes 13965 })); 13966 } 13967 }); 13968 } else { 13969 tr2.addMark(trimmedFrom, trimmedTo, type.create(attributes)); 13970 } 13971 }); 13972 }); 13973 } 13974 } 13975 return canSetMark(state, tr2, type); 13976}; 13977const setMeta = (key, value) => ({ tr: tr2 }) => { 13978 tr2.setMeta(key, value); 13979 return true; 13980}; 13981const setNode = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => { 13982 const type = getNodeType(typeOrName, state.schema); 13983 if (!type.isTextblock) { 13984 console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.'); 13985 return false;
13986 } 13987 return chain().command(({ commands: commands2 }) => { 13988 const canSetBlock = setBlockType(type, attributes)(state); 13989 if (canSetBlock) { 13990 return true; 13991 } 13992 return commands2.clearNodes(); 13993 }).command(({ state: updatedState }) => { 13994 return setBlockType(type, attributes)(updatedState, dispatch); 13995 }).run(); 13996}; 13997const setNodeSelection = (position) => ({ tr: tr2, dispatch }) => { 13998 if (dispatch) { 13999 const { doc: doc2 } = tr2; 14000 const from2 = minMax(position, 0, doc2.content.size); 14001 const selection = NodeSelection.create(doc2, from2); 14002 tr2.setSelection(selection); 14003 } 14004 return true; 14005}; 14006const setTextSelection = (position) => ({ tr: tr2, dispatch }) => { 14007 if (dispatch) { 14008 const { doc: doc2 } = tr2; 14009 const { from: from2, to } = typeof position === "number" ? { from: position, to: position } : position; 14010 const minPos = TextSelection.atStart(doc2).from; 14011 const maxPos = TextSelection.atEnd(doc2).to; 14012 const resolvedFrom = minMax(from2, minPos, maxPos); 14013 const resolvedEnd = minMax(to, minPos, maxPos); 14014 const selection = TextSelection.create(doc2, resolvedFrom, resolvedEnd); 14015 tr2.setSelection(selection); 14016 } 14017 return true; 14018}; 14019const sinkListItem = (typeOrName) => ({ state, dispatch }) => { 14020 const type = getNodeType(typeOrName, state.schema); 14021 return sinkListItem$1(type)(state, dispatch); 14022}; 14023function ensureMarks(state, splittableMarks) { 14024 const marks = state.storedMarks || state.selection.$to.parentOffset && state.selection.$from.marks(); 14025 if (marks) { 14026 const filteredMarks = marks.filter((mark) => splittableMarks === null || splittableMarks === void 0 ? void 0 : splittableMarks.includes(mark.type.name)); 14027 state.tr.ensureMarks(filteredMarks); 14028 } 14029} 14030const splitBlock = ({ keepMarks = true } = {}) => ({ tr: tr2, state, dispatch, editor }) => { 14031 const { selection, doc: doc2 } = tr2; 14032 const { $from, $to } = selection; 14033 const extensionAttributes = editor.extensionManager.attributes; 14034 const newAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs); 14035 if (selection instanceof NodeSelection && selection.node.isBlock) { 14036 if (!$from.parentOffset || !canSplit(doc2, $from.pos)) { 14037 return false; 14038 } 14039 if (dispatch) { 14040 if (keepMarks) { 14041 ensureMarks(state, editor.extensionManager.splittableMarks); 14042 } 14043 tr2.split($from.pos).scrollIntoView(); 14044 } 14045 return true; 14046 } 14047 if (!$from.parent.isBlock) { 14048 return false; 14049 } 14050 if (dispatch) { 14051 const atEnd = $to.parentOffset === $to.parent.content.size; 14052 if (selection instanceof TextSelection) { 14053 tr2.deleteSelection(); 14054 } 14055 const deflt = $from.depth === 0 ? void 0 : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1))); 14056 let types = atEnd && deflt ? [ 14057 { 14058 type: deflt, 14059 attrs: newAttributes 14060 } 14061 ] : void 0; 14062 let can = canSplit(tr2.doc, tr2.mapping.map($from.pos), 1, types); 14063 if (!types && !can && canSplit(tr2.doc, tr2.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : void 0)) { 14064 can = true; 14065 types = deflt ? [ 14066 { 14067 type: deflt, 14068 attrs: newAttributes 14069 }
14070 ] : void 0; 14071 } 14072 if (can) { 14073 tr2.split(tr2.mapping.map($from.pos), 1, types); 14074 if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) { 14075 const first2 = tr2.mapping.map($from.before()); 14076 const $first = tr2.doc.resolve(first2); 14077 if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) { 14078 tr2.setNodeMarkup(tr2.mapping.map($from.before()), deflt); 14079 } 14080 } 14081 } 14082 if (keepMarks) { 14083 ensureMarks(state, editor.extensionManager.splittableMarks); 14084 } 14085 tr2.scrollIntoView(); 14086 } 14087 return true; 14088}; 14089const splitListItem = (typeOrName) => ({ tr: tr2, state, dispatch, editor }) => { 14090 var _a; 14091 const type = getNodeType(typeOrName, state.schema); 14092 const { $from, $to } = state.selection; 14093 const node = state.selection.node; 14094 if (node && node.isBlock || $from.depth < 2 || !$from.sameParent($to)) { 14095 return false; 14096 } 14097 const grandParent = $from.node(-1); 14098 if (grandParent.type !== type) { 14099 return false; 14100 } 14101 const extensionAttributes = editor.extensionManager.attributes; 14102 if ($from.parent.content.size === 0 && $from.node(-1).childCount === $from.indexAfter(-1)) { 14103 if ($from.depth === 2 || $from.node(-3).type !== type || $from.index(-2) !== $from.node(-2).childCount - 1) { 14104 return false; 14105 } 14106 if (dispatch) { 14107 let wrap2 = Fragment.empty; 14108 const depthBefore = $from.index(-1) ? 1 : $from.index(-2) ? 2 : 3; 14109 for (let d = $from.depth - depthBefore; d >= $from.depth - 3; d -= 1) { 14110 wrap2 = Fragment.from($from.node(d).copy(wrap2)); 14111 } 14112 const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3; 14113 const newNextTypeAttributes2 = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs); 14114 const nextType2 = ((_a = type.contentMatch.defaultType) === null || _a === void 0 ? void 0 : _a.createAndFill(newNextTypeAttributes2)) || void 0; 14115 wrap2 = wrap2.append(Fragment.from(type.createAndFill(null, nextType2) || void 0)); 14116 const start2 = $from.before($from.depth - (depthBefore - 1)); 14117 tr2.replace(start2, $from.after(-depthAfter), new Slice(wrap2, 4 - depthBefore, 0)); 14118 let sel = -1; 14119 tr2.doc.nodesBetween(start2, tr2.doc.content.size, (n, pos) => { 14120 if (sel > -1) { 14121 return false; 14122 } 14123 if (n.isTextblock && n.content.size === 0) { 14124 sel = pos + 1; 14125 } 14126 }); 14127 if (sel > -1) { 14128 tr2.setSelection(TextSelection.near(tr2.doc.resolve(sel))); 14129 } 14130 tr2.scrollIntoView(); 14131 } 14132 return true; 14133 } 14134 const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null; 14135 const newTypeAttributes = getSplittedAttributes(extensionAttributes, grandParent.type.name, grandParent.attrs); 14136 const newNextTypeAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs); 14137 tr2.delete($from.pos, $to.pos); 14138 const types = nextType ? [ 14139 { type, attrs: newTypeAttributes }, 14140 { type: nextType, attrs: newNextTypeAttributes } 14141 ] : [{ type, attrs: newTypeAttributes }]; 14142 if (!canSplit(tr2.doc, $from.pos, 2)) { 14143 return false; 14144 } 14145 if (dispatch) { 14146 const { selection, storedMarks } = state; 14147 const { splittableMarks } = editor.extensionManager; 14148 const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks(); 14149 tr2.split($from.pos, 2, types).scrollIntoView(); 14150 if (!marks || !dispatch) { 14151 return true; 14152 } 14153 const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name)); 14154 tr2.ensureMarks(filteredMarks); 14155 } 14156 return true; 14157}; 14158const joinListBackwards = (tr2, listType) => { 14159 const list = findParentNode((node) => node.type === listType)(tr2.selection); 14160 if (!list) { 14161 return true; 14162 } 14163 const before = tr2.doc.resolve(Math.max(0, list.pos - 1)).before(list.depth); 14164 if (before === void 0) { 14165 return true; 14166 } 14167 const nodeBefore = tr2.doc.nodeAt(before); 14168 const canJoinBackwards = list.node.type === (nodeBefore === null || nodeBefore === void 0 ? void 0 : nodeBefore.type) && canJoin(tr2.doc, list.pos); 14169 if (!canJoinBackwards) { 14170 return true; 14171 }
14172 tr2.join(list.pos); 14173 return true; 14174}; 14175const joinListForwards = (tr2, listType) => { 14176 const list = findParentNode((node) => node.type === listType)(tr2.selection); 14177 if (!list) { 14178 return true; 14179 } 14180 const after = tr2.doc.resolve(list.start).after(list.depth); 14181 if (after === void 0) { 14182 return true; 14183 } 14184 const nodeAfter = tr2.doc.nodeAt(after); 14185 const canJoinForwards = list.node.type === (nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.type) && canJoin(tr2.doc, after); 14186 if (!canJoinForwards) { 14187 return true; 14188 } 14189 tr2.join(after); 14190 return true; 14191}; 14192const toggleList = (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) => ({ editor, tr: tr2, state, dispatch, chain, commands: commands2, can }) => { 14193 const { extensions, splittableMarks } = editor.extensionManager; 14194 const listType = getNodeType(listTypeOrName, state.schema); 14195 const itemType = getNodeType(itemTypeOrName, state.schema); 14196 const { selection, storedMarks } = state; 14197 const { $from, $to } = selection; 14198 const range = $from.blockRange($to); 14199 const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks(); 14200 if (!range) { 14201 return false; 14202 } 14203 const parentList = findParentNode((node) => isList(node.type.name, extensions))(selection); 14204 if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) { 14205 if (parentList.node.type === listType) { 14206 return commands2.liftListItem(itemType); 14207 } 14208 if (isList(parentList.node.type.name, extensions) && listType.validContent(parentList.node.content) && dispatch) { 14209 return chain().command(() => { 14210 tr2.setNodeMarkup(parentList.pos, listType); 14211 return true; 14212 }).command(() => joinListBackwards(tr2, listType)).command(() => joinListForwards(tr2, listType)).run(); 14213 } 14214 } 14215 if (!keepMarks || !marks || !dispatch) { 14216 return chain().command(() => { 14217 const canWrapInList = can().wrapInList(listType, attributes); 14218 if (canWrapInList) { 14219 return true; 14220 } 14221 return commands2.clearNodes(); 14222 }).wrapInList(listType, attributes).command(() => joinListBackwards(tr2, listType)).command(() => joinListForwards(tr2, listType)).run(); 14223 } 14224 return chain().command(() => { 14225 const canWrapInList = can().wrapInList(listType, attributes); 14226 const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name)); 14227 tr2.ensureMarks(filteredMarks); 14228 if (canWrapInList) { 14229 return true; 14230 } 14231 return commands2.clearNodes(); 14232 }).wrapInList(listType, attributes).command(() => joinListBackwards(tr2, listType)).command(() => joinListForwards(tr2, listType)).run(); 14233}; 14234const toggleMark = (typeOrName, attributes = {}, options = {}) => ({ state, commands: commands2 }) => { 14235 const { extendEmptyMarkRange = false } = options; 14236 const type = getMarkType(typeOrName, state.schema); 14237 const isActive2 = isMarkActive(state, type, attributes); 14238 if (isActive2) { 14239 return commands2.unsetMark(type, { extendEmptyMarkRange }); 14240 } 14241 return commands2.setMark(type, attributes); 14242}; 14243const toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state, commands: commands2 }) => { 14244 const type = getNodeType(typeOrName, state.schema); 14245 const toggleType = getNodeType(toggleTypeOrName, state.schema); 14246 const isActive2 = isNodeActive(state, type, attributes); 14247 if (isActive2) { 14248 return commands2.setNode(toggleType); 14249 } 14250 return commands2.setNode(type, attributes); 14251}; 14252const toggleWrap = (typeOrName, attributes = {}) => ({ state, commands: commands2 }) => { 14253 const type = getNodeType(typeOrName, state.schema); 14254 const isActive2 = isNodeActive(state, type, attributes); 14255 if (isActive2) { 14256 return commands2.lift(type); 14257 } 14258 return commands2.wrapIn(type, attributes); 14259}; 14260const undoInputRule = () => ({ state, dispatch }) => { 14261 const plugins = state.plugins; 14262 for (let i = 0; i < plugins.length; i += 1) { 14263 const plugin = plugins[i]; 14264 let undoable; 14265 if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) { 14266 if (dispatch) { 14267 const tr2 = state.tr; 14268 const toUndo = undoable.transform; 14269 for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) { 14270 tr2.step(toUndo.steps[j].invert(toUndo.docs[j])); 14271 } 14272 if (undoable.text) { 14273 const marks = tr2.doc.resolve(undoable.from).marks(); 14274 tr2.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks)); 14275 } else { 14276 tr2.delete(undoable.from, undoable.to); 14277 } 14278 } 14279 return true; 14280 } 14281 } 14282 return false;
14283}; 14284const unsetAllMarks = () => ({ tr: tr2, dispatch }) => { 14285 const { selection } = tr2; 14286 const { empty: empty2, ranges } = selection; 14287 if (empty2) { 14288 return true; 14289 } 14290 if (dispatch) { 14291 ranges.forEach((range) => { 14292 tr2.removeMark(range.$from.pos, range.$to.pos); 14293 }); 14294 } 14295 return true; 14296}; 14297const unsetMark = (typeOrName, options = {}) => ({ tr: tr2, state, dispatch }) => { 14298 var _a; 14299 const { extendEmptyMarkRange = false } = options; 14300 const { selection } = tr2; 14301 const type = getMarkType(typeOrName, state.schema); 14302 const { $from, empty: empty2, ranges } = selection; 14303 if (!dispatch) { 14304 return true; 14305 } 14306 if (empty2 && extendEmptyMarkRange) { 14307 let { from: from2, to } = selection; 14308 const attrs = (_a = $from.marks().find((mark) => mark.type === type)) === null || _a === void 0 ? void 0 : _a.attrs; 14309 const range = getMarkRange($from, type, attrs); 14310 if (range) { 14311 from2 = range.from; 14312 to = range.to; 14313 } 14314 tr2.removeMark(from2, to, type); 14315 } else { 14316 ranges.forEach((range) => { 14317 tr2.removeMark(range.$from.pos, range.$to.pos, type); 14318 }); 14319 } 14320 tr2.removeStoredMark(type); 14321 return true; 14322}; 14323const updateAttributes = (typeOrName, attributes = {}) => ({ tr: tr2, state, dispatch }) => { 14324 let nodeType = null; 14325 let markType = null; 14326 const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema); 14327 if (!schemaType) { 14328 return false; 14329 } 14330 if (schemaType === "node") { 14331 nodeType = getNodeType(typeOrName, state.schema); 14332 } 14333 if (schemaType === "mark") { 14334 markType = getMarkType(typeOrName, state.schema); 14335 } 14336 if (dispatch) { 14337 tr2.selection.ranges.forEach((range) => { 14338 const from2 = range.$from.pos; 14339 const to = range.$to.pos; 14340 state.doc.nodesBetween(from2, to, (node, pos) => { 14341 if (nodeType && nodeType === node.type) { 14342 tr2.setNodeMarkup(pos, void 0, { 14343 ...node.attrs, 14344 ...attributes 14345 }); 14346 } 14347 if (markType && node.marks.length) { 14348 node.marks.forEach((mark) => { 14349 if (markType === mark.type) { 14350 const trimmedFrom = Math.max(pos, from2); 14351 const trimmedTo = Math.min(pos + node.nodeSize, to); 14352 tr2.addMark(trimmedFrom, trimmedTo, markType.create({ 14353 ...mark.attrs, 14354 ...attributes 14355 })); 14356 } 14357 }); 14358 } 14359 }); 14360 }); 14361 } 14362 return true; 14363}; 14364const wrapIn = (typeOrName, attributes = {}) => ({ state, dispatch }) => { 14365 const type = getNodeType(typeOrName, state.schema); 14366 return wrapIn$1(type, attributes)(state, dispatch); 14367}; 14368const wrapInList = (typeOrName, attributes = {}) => ({ state, dispatch }) => { 14369 const type = getNodeType(typeOrName, state.schema); 14370 return wrapInList$1(type, attributes)(state, dispatch); 14371}; 14372var commands = /* @__PURE__ */ Object.freeze({ 14373 __proto__: null, 14374 blur, 14375 clearContent, 14376 clearNodes, 14377 command, 14378 createParagraphNear, 14379 cut, 14380 deleteCurrentNode, 14381 deleteNode, 14382 deleteRange, 14383 deleteSelection, 14384 enter, 14385 exitCode, 14386 extendMarkRange, 14387 first, 14388 focus, 14389 forEach, 14390 insertContent, 14391 insertContentAt, 14392 joinUp, 14393 joinDown, 14394 joinBackward, 14395 joinForward, 14396 joinItemBackward, 14397 joinItemForward, 14398 joinTextblockBackward, 14399 joinTextblockForward, 14400 keyboardShortcut, 14401 lift, 14402 liftEmptyBlock, 14403 liftListItem, 14404 newlineInCode, 14405 resetAttributes, 14406 scrollIntoView, 14407 selectAll, 14408 selectNodeBackward, 14409 selectNodeForward, 14410 selectParentNode, 14411 selectTextblockEnd, 14412 selectTextblockStart, 14413 setContent: setContent$1, 14414 setMark, 14415 setMeta, 14416 setNode, 14417 setNodeSelection, 14418 setTextSelection, 14419 sinkListItem, 14420 splitBlock, 14421 splitListItem, 14422 toggleList, 14423 toggleMark, 14424 toggleNode, 14425 toggleWrap, 14426 undoInputRule, 14427 unsetAllMarks, 14428 unsetMark, 14429 updateAttributes, 14430 wrapIn, 14431 wrapInList 14432}); 14433const Commands = Extension.create({ 14434 name: "commands", 14435 addCommands() { 14436 return { 14437 ...commands 14438 }; 14439 } 14440}); 14441const Editable = Extension.create({ 14442 name: "editable", 14443 addProseMirrorPlugins() { 14444 return [ 14445 new Plugin({ 14446 key: new PluginKey("editable"), 14447 props: { 14448 editable: () => this.editor.options.editable 14449 } 14450 }) 14451 ]; 14452 } 14453}); 14454const FocusEvents = Extension.create({ 14455 name: "focusEvents", 14456 addProseMirrorPlugins() { 14457 const { editor } = this; 14458 return [ 14459 new Plugin({ 14460 key: new PluginKey("focusEvents"), 14461 props: { 14462 handleDOMEvents: { 14463 focus: (view, event) => { 14464 editor.isFocused = true; 14465 const transaction = editor.state.tr.setMeta("focus", { event }).setMeta("addToHistory", false); 14466 view.dispatch(transaction); 14467 return false;
14468 }, 14469 blur: (view, event) => { 14470 editor.isFocused = false; 14471 const transaction = editor.state.tr.setMeta("blur", { event }).setMeta("addToHistory", false); 14472 view.dispatch(transaction); 14473 return false; 14474 } 14475 } 14476 } 14477 }) 14478 ]; 14479 } 14480}); 14481const Keymap = Extension.create({ 14482 name: "keymap", 14483 addKeyboardShortcuts() { 14484 const handleBackspace = () => this.editor.commands.first(({ commands: commands2 }) => [ 14485 () => commands2.undoInputRule(), 14486 // maybe convert first text block node to default node 14487 () => commands2.command(({ tr: tr2 }) => { 14488 const { selection, doc: doc2 } = tr2; 14489 const { empty: empty2, $anchor } = selection; 14490 const { pos, parent } = $anchor; 14491 const $parentPos = $anchor.parent.isTextblock && pos > 0 ? tr2.doc.resolve(pos - 1) : $anchor; 14492 const parentIsIsolating = $parentPos.parent.type.spec.isolating; 14493 const parentPos = $anchor.pos - $anchor.parentOffset; 14494 const isAtStart = parentIsIsolating && $parentPos.parent.childCount === 1 ? parentPos === $anchor.pos : Selection.atStart(doc2).from === pos; 14495 if (!empty2 || !parent.type.isTextblock || parent.textContent.length || !isAtStart || isAtStart && $anchor.parent.type.name === "paragraph") { 14496 return false; 14497 } 14498 return commands2.clearNodes(); 14499 }), 14500 () => commands2.deleteSelection(), 14501 () => commands2.joinBackward(), 14502 () => commands2.selectNodeBackward() 14503 ]); 14504 const handleDelete = () => this.editor.commands.first(({ commands: commands2 }) => [ 14505 () => commands2.deleteSelection(), 14506 () => commands2.deleteCurrentNode(), 14507 () => commands2.joinForward(), 14508 () => commands2.selectNodeForward() 14509 ]); 14510 const handleEnter = () => this.editor.commands.first(({ commands: commands2 }) => [ 14511 () => commands2.newlineInCode(), 14512 () => commands2.createParagraphNear(), 14513 () => commands2.liftEmptyBlock(), 14514 () => commands2.splitBlock() 14515 ]); 14516 const baseKeymap = { 14517 Enter: handleEnter, 14518 "Mod-Enter": () => this.editor.commands.exitCode(), 14519 Backspace: handleBackspace, 14520 "Mod-Backspace": handleBackspace, 14521 "Shift-Backspace": handleBackspace, 14522 Delete: handleDelete, 14523 "Mod-Delete": handleDelete, 14524 "Mod-a": () => this.editor.commands.selectAll() 14525 }; 14526 const pcKeymap = { 14527 ...baseKeymap 14528 }; 14529 const macKeymap = { 14530 ...baseKeymap, 14531 "Ctrl-h": handleBackspace, 14532 "Alt-Backspace": handleBackspace, 14533 "Ctrl-d": handleDelete, 14534 "Ctrl-Alt-Backspace": handleDelete, 14535 "Alt-Delete": handleDelete, 14536 "Alt-d": handleDelete, 14537 "Ctrl-a": () => this.editor.commands.selectTextblockStart(), 14538 "Ctrl-e": () => this.editor.commands.selectTextblockEnd() 14539 }; 14540 if (isiOS() || isMacOS()) { 14541 return macKeymap; 14542 } 14543 return pcKeymap; 14544 }, 14545 addProseMirrorPlugins() { 14546 return [ 14547 // With this plugin we check if the whole document was selected and deleted. 14548 // In this case we will additionally call `clearNodes()` to convert e.g. a heading 14549 // to a paragraph if necessary. 14550 // This is an alternative to ProseMirror's `AllSelection`, which doesnât work well 14551 // with many other commands. 14552 new Plugin({ 14553 key: new PluginKey("clearDocument"), 14554 appendTransaction: (transactions, oldState, newState) => { 14555 const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc); 14556 if (!docChanges) { 14557 return; 14558 } 14559 const { empty: empty2, from: from2, to } = oldState.selection; 14560 const allFrom = Selection.atStart(oldState.doc).from; 14561 const allEnd = Selection.atEnd(oldState.doc).to; 14562 const allWasSelected = from2 === allFrom && to === allEnd; 14563 if (empty2 || !allWasSelected) { 14564 return; 14565 } 14566 const isEmpty2 = newState.doc.textBetween(0, newState.doc.content.size, " ", " ").length === 0; 14567 if (!isEmpty2) { 14568 return; 14569 } 14570 const tr2 = newState.tr; 14571 const state = createChainableState({ 14572 state: newState, 14573 transaction: tr2 14574 }); 14575 const { commands: commands2 } = new CommandManager({ 14576 editor: this.editor, 14577 state 14578 }); 14579 commands2.clearNodes(); 14580 if (!tr2.steps.length) { 14581 return; 14582 } 14583 return tr2; 14584 } 14585 }) 14586 ]; 14587 } 14588}); 14589const Tabindex = Extension.create({ 14590 name: "tabindex", 14591 addProseMirrorPlugins() { 14592 return [ 14593 new Plugin({ 14594 key: new PluginKey("tabindex"), 14595 props: { 14596 attributes: this.editor.isEditable ? { tabindex: "0" } : {} 14597 } 14598 }) 14599 ]; 14600 } 14601}); 14602class NodePos { 14603 constructor(pos, editor, isBlock = false, node = null) { 14604 this.currentNode = null; 14605 this.actualDepth = null; 14606 this.isBlock = isBlock; 14607 this.resolvedPos = pos; 14608 this.editor = editor; 14609 this.currentNode = node; 14610 } 14611 get name() {
vendor: 4,653 bytes, lines 14612-14766
14612 return this.node.type.name; 14613 } 14614 get node() { 14615 return this.currentNode || this.resolvedPos.node(); 14616 } 14617 get element() { 14618 return this.editor.view.domAtPos(this.pos).node; 14619 } 14620 get depth() { 14621 var _a; 14622 return (_a = this.actualDepth) !== null && _a !== void 0 ? _a : this.resolvedPos.depth; 14623 } 14624 get pos() { 14625 return this.resolvedPos.pos; 14626 } 14627 get content() { 14628 return this.node.content; 14629 } 14630 set content(content) { 14631 let from2 = this.from; 14632 let to = this.to; 14633 if (this.isBlock) { 14634 if (this.content.size === 0) { 14635 console.error(`You canât set content on a block node. Tried to set content on ${this.name} at ${this.pos}`); 14636 return; 14637 } 14638 from2 = this.from + 1; 14639 to = this.to - 1; 14640 } 14641 this.editor.commands.insertContentAt({ from: from2, to }, content); 14642 } 14643 get attributes() { 14644 return this.node.attrs; 14645 } 14646 get textContent() { 14647 return this.node.textContent; 14648 } 14649 get size() { 14650 return this.node.nodeSize; 14651 } 14652 get from() { 14653 if (this.isBlock) { 14654 return this.pos; 14655 } 14656 return this.resolvedPos.start(this.resolvedPos.depth); 14657 } 14658 get range() { 14659 return { 14660 from: this.from, 14661 to: this.to 14662 }; 14663 } 14664 get to() { 14665 if (this.isBlock) { 14666 return this.pos + this.size; 14667 } 14668 return this.resolvedPos.end(this.resolvedPos.depth) + (this.node.isText ? 0 : 1); 14669 } 14670 get parent() { 14671 if (this.depth === 0) { 14672 return null; 14673 } 14674 const parentPos = this.resolvedPos.start(this.resolvedPos.depth - 1); 14675 const $pos = this.resolvedPos.doc.resolve(parentPos); 14676 return new NodePos($pos, this.editor); 14677 } 14678 get before() { 14679 let $pos = this.resolvedPos.doc.resolve(this.from - (this.isBlock ? 1 : 2)); 14680 if ($pos.depth !== this.depth) { 14681 $pos = this.resolvedPos.doc.resolve(this.from - 3); 14682 } 14683 return new NodePos($pos, this.editor); 14684 } 14685 get after() { 14686 let $pos = this.resolvedPos.doc.resolve(this.to + (this.isBlock ? 2 : 1)); 14687 if ($pos.depth !== this.depth) { 14688 $pos = this.resolvedPos.doc.resolve(this.to + 3); 14689 } 14690 return new NodePos($pos, this.editor); 14691 } 14692 get children() { 14693 const children = []; 14694 this.node.content.forEach((node, offset2) => { 14695 const isBlock = node.isBlock && !node.isTextblock; 14696 const targetPos = this.pos + offset2 + 1; 14697 const $pos = this.resolvedPos.doc.resolve(targetPos); 14698 if (!isBlock && $pos.depth <= this.depth) { 14699 return; 14700 } 14701 const childNodePos = new NodePos($pos, this.editor, isBlock, isBlock ? node : null); 14702 if (isBlock) { 14703 childNodePos.actualDepth = this.depth + 1; 14704 } 14705 children.push(new NodePos($pos, this.editor, isBlock, isBlock ? node : null)); 14706 }); 14707 return children; 14708 } 14709 get firstChild() { 14710 return this.children[0] || null; 14711 } 14712 get lastChild() { 14713 const children = this.children; 14714 return children[children.length - 1] || null; 14715 } 14716 closest(selector, attributes = {}) { 14717 let node = null; 14718 let currentNode = this.parent; 14719 while (currentNode && !node) { 14720 if (currentNode.node.type.name === selector) { 14721 if (Object.keys(attributes).length > 0) { 14722 const nodeAttributes = currentNode.node.attrs; 14723 const attrKeys = Object.keys(attributes); 14724 for (let index = 0; index < attrKeys.length; index += 1) { 14725 const key = attrKeys[index]; 14726 if (nodeAttributes[key] !== attributes[key]) { 14727 break; 14728 } 14729 } 14730 } else { 14731 node = currentNode; 14732 } 14733 } 14734 currentNode = currentNode.parent; 14735 } 14736 return node; 14737 } 14738 querySelector(selector, attributes = {}) { 14739 return this.querySelectorAll(selector, attributes, true)[0] || null; 14740 } 14741 querySelectorAll(selector, attributes = {}, firstItemOnly = false) { 14742 let nodes = []; 14743 if (!this.children || this.children.length === 0) { 14744 return nodes; 14745 } 14746 const attrKeys = Object.keys(attributes); 14747 this.children.forEach((childPos) => { 14748 if (firstItemOnly && nodes.length > 0) { 14749 return; 14750 } 14751 if (childPos.node.type.name === selector) { 14752 const doesAllAttributesMatch = attrKeys.every((key) => attributes[key] === childPos.node.attrs[key]); 14753 if (doesAllAttributesMatch) { 14754 nodes.push(childPos); 14755 } 14756 } 14757 if (firstItemOnly && nodes.length > 0) { 14758 return; 14759 } 14760 nodes = nodes.concat(childPos.querySelectorAll(selector, attributes, firstItemOnly)); 14761 }); 14762 return nodes; 14763 } 14764 setAttribute(attributes) { 14765 const oldSelection = this.editor.state.selection; 14766 this.editor.chain().setTextSelection(this.from).updateAttributes(this.node.type.n
14766ame, attributes).setTextSelection(oldSelection.from).run(); 14767 } 14768} 14769const style = `.ProseMirror { 14770 position: relative; 14771} 14772 14773.ProseMirror { 14774 word-wrap: break-word; 14775 white-space: pre-wrap; 14776 white-space: break-spaces; 14777 -webkit-font-variant-ligatures: none; 14778 font-variant-ligatures: none; 14779 font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */ 14780} 14781 14782.ProseMirror [contenteditable="false"] { 14783 white-space: normal; 14784} 14785 14786.ProseMirror [contenteditable="false"] [contenteditable="true"] { 14787 white-space: pre-wrap; 14788} 14789 14790.ProseMirror pre { 14791 white-space: pre-wrap; 14792} 14793 14794img.ProseMirror-separator { 14795 display: inline !important; 14796 border: none !important; 14797 margin: 0 !important; 14798 width: 1px !important; 14799 height: 1px !important; 14800} 14801 14802.ProseMirror-gapcursor { 14803 display: none; 14804 pointer-events: none; 14805 position: absolute; 14806 margin: 0; 14807} 14808 14809.ProseMirror-gapcursor:after { 14810 content: ""; 14811 display: block; 14812 position: absolute; 14813 top: -2px; 14814 width: 20px; 14815 border-top: 1px solid black; 14816 animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite; 14817} 14818 14819@keyframes ProseMirror-cursor-blink { 14820 to { 14821 visibility: hidden; 14822 } 14823} 14824 14825.ProseMirror-hideselection *::selection { 14826 background: transparent; 14827} 14828 14829.ProseMirror-hideselection *::-moz-selection { 14830 background: transparent; 14831} 14832 14833.ProseMirror-hideselection * { 14834 caret-color: transparent; 14835} 14836 14837.ProseMirror-focused .ProseMirror-gapcursor { 14838 display: block; 14839} 14840 14841.tippy-box[data-animation=fade][data-state=hidden] { 14842 opacity: 0 14843}`; 14844function createStyleTag(style2, nonce, suffix) { 14845 const tiptapStyleTag = document.querySelector(`style[data-tiptap-style${suffix ? `-${suffix}` : ""}]`); 14846 if (tiptapStyleTag !== null) { 14847 return tiptapStyleTag; 14848 } 14849 const styleNode = document.createElement("style"); 14850 if (nonce) { 14851 styleNode.setAttribute("nonce", nonce); 14852 } 14853 styleNode.setAttribute(`data-tiptap-style${suffix ? `-${suffix}` : ""}`, ""); 14854 styleNode.innerHTML = style2; 14855 document.getElementsByTagName("head")[0].appendChild(styleNode); 14856 return styleNode; 14857} 14858let Editor$1 = class Editor extends EventEmitter { 14859 constructor(options = {}) { 14860 super(); 14861 this.isFocused = false; 14862 this.extensionStorage = {}; 14863 this.options = { 14864 element: document.createElement("div"), 14865 content: "", 14866 injectCSS: true, 14867 injectNonce: void 0, 14868 extensions: [], 14869 autofocus: false, 14870 editable: true, 14871 editorProps: {}, 14872 parseOptions: {}, 14873 coreExtensionOptions: {}, 14874 enableInputRules: true, 14875 enablePasteRules: true, 14876 enableCoreExtensions: true, 14877 onBeforeCreate: () => null, 14878 onCreate: () => null, 14879 onUpdate: () => null, 14880 onSelectionUpdate: () => null, 14881 onTransaction: () => null, 14882 onFocus: () => null, 14883 onBlur: () => null, 14884 onDestroy: () => null 14885 }; 14886 this.isCapturingTransaction = false; 14887 this.capturedTransaction = null; 14888 this.setOptions(options); 14889 this.createExtensionManager(); 14890 this.createCommandManager(); 14891 this.createSchema(); 14892 this.on("beforeCreate", this.options.onBeforeCreate); 14893 this.emit("beforeCreate", { editor: this }); 14894 this.createView(); 14895 this.injectCSS(); 14896 this.on("create", this.options.onCreate); 14897 this.on("update", this.options.onUpdate); 14898 this.on("selectionUpdate", this.options.onSelectionUpdate); 14899 this.on("transaction", this.options.onTransaction); 14900 this.on("focus", this.options.onFocus); 14901 this.on("blur", this.options.onBlur); 14902 this.on("destroy", this.options.onDestroy); 14903 window.setTimeout(() => { 14904 if (this.isDestroyed) { 14905 return; 14906 } 14907 this.commands.focus(this.options.autofocus); 14908 this.emit("create", { editor: this }); 14909 }, 0); 14910 } 14911 /** 14912 * Returns the editor storage. 14913 */ 14914 get storage() { 14915 return this.extensionStorage; 14916 } 14917 /** 14918 * An object of all registered commands. 14919 */ 14920 get commands() { 14921 return this.commandManager.commands; 14922 } 14923 /** 14924 * Create a command chain to call multiple commands at once. 14925 */ 14926 chain() { 14927 return this.commandManager.chain(); 14928 } 14929 /** 14930 * Check if a command or a command chain can be executed. Without executing it. 14931 */ 14932 can() { 14933 return this.commandManager.can(); 14934 } 14935 /** 14936 * Inject CSS styles. 14937 */ 14938 injectCSS() { 14939 if (this.options.injectCSS && document) { 14940 this.css = createStyleTag(style, this.options.injectNonce); 14941 } 14942 } 14943 /** 14944 * Update editor options. 14945 * 14946 * @param options A list of options 14947 */ 14948 setOptions(options = {}) { 14949 this.options = { 14950 ...this.options, 14951 ...options 14952 }; 14953 if (!this.view || !this.state || this.isDestroyed) { 14954 return; 14955 } 14956 if (this.options.editorProps) { 14957 this.view.setProps(this.options.editorProps); 14958 } 14959 this.view.updateState(this.state); 14960 } 14961 /** 14962 * Update editable state of the editor. 14963 */ 14964 setEditable(editable, emitUpdate = true) { 14965 this.setOptions({ editable }); 14966 if (emitUpdate) {
14967 this.emit("update", { editor: this, transaction: this.state.tr }); 14968 } 14969 } 14970 /** 14971 * Returns whether the editor is editable. 14972 */ 14973 get isEditable() { 14974 return this.options.editable && this.view && this.view.editable; 14975 } 14976 /** 14977 * Returns the editor state. 14978 */ 14979 get state() { 14980 return this.view.state; 14981 } 14982 /** 14983 * Register a ProseMirror plugin. 14984 * 14985 * @param plugin A ProseMirror plugin 14986 * @param handlePlugins Control how to merge the plugin into the existing plugins. 14987 */ 14988 registerPlugin(plugin, handlePlugins) { 14989 const plugins = isFunction(handlePlugins) ? handlePlugins(plugin, [...this.state.plugins]) : [...this.state.plugins, plugin]; 14990 const state = this.state.reconfigure({ plugins }); 14991 this.view.updateState(state); 14992 } 14993 /** 14994 * Unregister a ProseMirror plugin. 14995 * 14996 * @param nameOrPluginKey The plugins name 14997 */ 14998 unregisterPlugin(nameOrPluginKey) { 14999 if (this.isDestroyed) { 15000 return; 15001 } 15002 const name = typeof nameOrPluginKey === "string" ? `${nameOrPluginKey}$` : nameOrPluginKey.key; 15003 const state = this.state.reconfigure({ 15004 // @ts-ignore 15005 plugins: this.state.plugins.filter((plugin) => !plugin.key.startsWith(name)) 15006 }); 15007 this.view.updateState(state); 15008 } 15009 /** 15010 * Creates an extension manager. 15011 */ 15012 createExtensionManager() { 15013 var _a, _b; 15014 const coreExtensions = this.options.enableCoreExtensions ? [ 15015 Editable, 15016 ClipboardTextSerializer.configure({ 15017 blockSeparator: (_b = (_a = this.options.coreExtensionOptions) === null || _a === void 0 ? void 0 : _a.clipboardTextSerializer) === null || _b === void 0 ? void 0 : _b.blockSeparator 15018 }), 15019 Commands, 15020 FocusEvents, 15021 Keymap, 15022 Tabindex 15023 ] : []; 15024 const allExtensions = [...coreExtensions, ...this.options.extensions].filter((extension) => { 15025 return ["extension", "node", "mark"].includes(extension === null || extension === void 0 ? void 0 : extension.type); 15026 }); 15027 this.extensionManager = new ExtensionManager(allExtensions, this); 15028 } 15029 /** 15030 * Creates an command manager. 15031 */ 15032 createCommandManager() { 15033 this.commandManager = new CommandManager({ 15034 editor: this 15035 }); 15036 } 15037 /** 15038 * Creates a ProseMirror schema. 15039 */ 15040 createSchema() { 15041 this.schema = this.extensionManager.schema; 15042 } 15043 /** 15044 * Creates a ProseMirror view. 15045 */ 15046 createView() { 15047 const doc2 = createDocument(this.options.content, this.schema, this.options.parseOptions); 15048 const selection = resolveFocusPosition(doc2, this.options.autofocus); 15049 this.view = new EditorView(this.options.element, { 15050 ...this.options.editorProps, 15051 dispatchTransaction: this.dispatchTransaction.bind(this), 15052 state: EditorState.create({ 15053 doc: doc2, 15054 selection: selection || void 0 15055 }) 15056 }); 15057 const newState = this.state.reconfigure({ 15058 plugins: this.extensionManager.plugins 15059 }); 15060 this.view.updateState(newState); 15061 this.createNodeViews(); 15062 this.prependClass(); 15063 const dom = this.view.dom; 15064 dom.editor = this; 15065 } 15066 /** 15067 * Creates all node views. 15068 */ 15069 createNodeViews() { 15070 this.view.setProps({ 15071 nodeViews: this.extensionManager.nodeViews 15072 }); 15073 } 15074 /** 15075 * Prepend class name to element. 15076 */ 15077 prependClass() { 15078 this.view.dom.className = `tiptap ${this.view.dom.className}`; 15079 } 15080 captureTransaction(fn2) { 15081 this.isCapturingTransaction = true; 15082 fn2(); 15083 this.isCapturingTransaction = false; 15084 const tr2 = this.capturedTransaction; 15085 this.capturedTransaction = null; 15086 return tr2; 15087 } 15088 /** 15089 * The callback over which to send transactions (state updates) produced by the view. 15090 * 15091 * @param transaction An editor state transaction 15092 */ 15093 dispatchTransaction(transaction) { 15094 if (this.view.isDestroyed) { 15095 return; 15096 } 15097 if (this.isCapturingTransaction) { 15098 if (!this.capturedTransaction) { 15099 this.capturedTransaction = transaction; 15100 return; 15101 } 15102 transaction.steps.forEach((step) => { 15103 var _a; 15104 return (_a = this.capturedTransaction) === null || _a === void 0 ? void 0 : _a.step(step); 15105 }); 15106 return; 15107 } 15108 const state = this.state.apply(transaction); 15109 const selectionHasChanged = !this.state.selection.eq(state.selection); 15110 this.view.updateState(state);
15111 this.emit("transaction", { 15112 editor: this, 15113 transaction 15114 }); 15115 if (selectionHasChanged) { 15116 this.emit("selectionUpdate", { 15117 editor: this, 15118 transaction 15119 }); 15120 } 15121 const focus2 = transaction.getMeta("focus"); 15122 const blur2 = transaction.getMeta("blur"); 15123 if (focus2) { 15124 this.emit("focus", { 15125 editor: this, 15126 event: focus2.event, 15127 transaction 15128 }); 15129 } 15130 if (blur2) { 15131 this.emit("blur", { 15132 editor: this, 15133 event: blur2.event, 15134 transaction 15135 }); 15136 } 15137 if (!transaction.docChanged || transaction.getMeta("preventUpdate")) { 15138 return; 15139 } 15140 this.emit("update", { 15141 editor: this, 15142 transaction 15143 }); 15144 } 15145 /** 15146 * Get attributes of the currently selected node or mark. 15147 */ 15148 getAttributes(nameOrType) { 15149 return getAttributes(this.state, nameOrType); 15150 } 15151 isActive(nameOrAttributes, attributesOrUndefined) { 15152 const name = typeof nameOrAttributes === "string" ? nameOrAttributes : null; 15153 const attributes = typeof nameOrAttributes === "string" ? attributesOrUndefined : nameOrAttributes; 15154 return isActive(this.state, name, attributes); 15155 } 15156 /** 15157 * Get the document as JSON. 15158 */ 15159 getJSON() { 15160 return this.state.doc.toJSON(); 15161 } 15162 /** 15163 * Get the document as HTML. 15164 */ 15165 getHTML() { 15166 return getHTMLFromFragment(this.state.doc.content, this.schema); 15167 } 15168 /** 15169 * Get the document as text. 15170 */ 15171 getText(options) {
15172 const { blockSeparator = "\n\n", textSerializers = {} } = options || {}; 15173 return getText(this.state.doc, { 15174 blockSeparator, 15175 textSerializers: { 15176 ...getTextSerializersFromSchema(this.schema), 15177 ...textSerializers 15178 } 15179 }); 15180 } 15181 /** 15182 * Check if there is no content. 15183 */ 15184 get isEmpty() { 15185 return isNodeEmpty(this.state.doc); 15186 } 15187 /** 15188 * Get the number of characters for the current document. 15189 * 15190 * @deprecated 15191 */ 15192 getCharacterCount() { 15193 console.warn('[tiptap warn]: "editor.getCharacterCount()" is deprecated. Please use "editor.storage.characterCount.characters()" instead.'); 15194 return this.state.doc.content.size - 2; 15195 } 15196 /** 15197 * Destroy the editor. 15198 */ 15199 destroy() { 15200 this.emit("destroy"); 15201 if (this.view) { 15202 this.view.destroy(); 15203 } 15204 this.removeAllListeners(); 15205 } 15206 /** 15207 * Check if the editor is already destroyed. 15208 */ 15209 get isDestroyed() { 15210 var _a; 15211 return !((_a = this.view) === null || _a === void 0 ? void 0 : _a.docView); 15212 } 15213 $node(selector, attributes) { 15214 var _a; 15215 return ((_a = this.$doc) === null || _a === void 0 ? void 0 : _a.querySelector(selector, attributes)) || null; 15216 } 15217 $nodes(selector, attributes) { 15218 var _a; 15219 return ((_a = this.$doc) === null || _a === void 0 ? void 0 : _a.querySelectorAll(selector, attributes)) || null; 15220 } 15221 $pos(pos) { 15222 const $pos = this.state.doc.resolve(pos); 15223 return new NodePos($pos, this); 15224 } 15225 get $doc() { 15226 return this.$pos(0); 15227 } 15228}; 15229function markInputRule(config) { 15230 return new InputRule({ 15231 find: config.find, 15232 handler: ({ state, range, match }) => { 15233 const attributes = callOrReturn(config.getAttributes, void 0, match); 15234 if (attributes === false || attributes === null) { 15235 return null; 15236 } 15237 const { tr: tr2 } = state; 15238 const captureGroup = match[match.length - 1]; 15239 const fullMatch = match[0]; 15240 if (captureGroup) { 15241 const startSpaces = fullMatch.search(/\S/); 15242 const textStart = range.from + fullMatch.indexOf(captureGroup); 15243 const textEnd = textStart + captureGroup.length; 15244 const excludedMarks = getMarksBetween(range.from, range.to, state.doc).filter((item) => { 15245 const excluded = item.mark.type.excluded; 15246 return excluded.find((type) => type === config.type && type !== item.mark.type); 15247 }).filter((item) => item.to > textStart); 15248 if (excludedMarks.length) { 15249 return null; 15250 } 15251 if (textEnd < range.to) { 15252 tr2.delete(textEnd, range.to); 15253 } 15254 if (textStart > range.from) { 15255 tr2.delete(range.from + startSpaces, textStart); 15256 } 15257 const markEnd = range.from + startSpaces + captureGroup.length; 15258 tr2.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {})); 15259 tr2.removeStoredMark(config.type); 15260 } 15261 } 15262 }); 15263} 15264function nodeInputRule(config) { 15265 return new InputRule({ 15266 find: config.find, 15267 handler: ({ state, range, match }) => { 15268 const attributes = callOrReturn(config.getAttributes, void 0, match) || {}; 15269 const { tr: tr2 } = state; 15270 const start2 = range.from; 15271 let end2 = range.to; 15272 const newNode = config.type.create(attributes); 15273 if (match[1]) { 15274 const offset2 = match[0].lastIndexOf(match[1]); 15275 let matchStart = start2 + offset2; 15276 if (matchStart > end2) { 15277 matchStart = end2; 15278 } else { 15279 end2 = matchStart + match[1].length; 15280 } 15281 const lastChar = match[0][match[0].length - 1]; 15282 tr2.insertText(lastChar, start2 + match[0].length - 1); 15283 tr2.replaceWith(matchStart, end2, newNode); 15284 } else if (match[0]) { 15285 tr2.insert(start2 - 1, config.type.create(attributes)).delete(tr2.mapping.map(start2), tr2.mapping.map(end2)); 15286 } 15287 tr2.scrollIntoView(); 15288 } 15289 }); 15290} 15291function textblockTypeInputRule(config) { 15292 return new InputRule({ 15293 find: config.find, 15294 handler: ({ state, range, match }) => { 15295 const $start = state.doc.resolve(range.from); 15296 const attributes = callOrReturn(config.getAttributes, void 0, match) || {}; 15297 if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), config.type)) { 15298 return null; 15299 } 15300 state.tr.delete(range.from, range.to).setBlockType(range.from, range.from, config.type, attributes); 15301 } 15302 }); 15303} 15304function textInputRule(config) { 15305 return new InputRule({ 15306 find: config.find, 15307 handler: ({ state, range, match }) => { 15308 let insert = config.replace; 15309 let start2 = range.from; 15310 const end2 = range.to; 15311 if (match[1]) { 15312 const offset2 = match[0].lastIndexOf(match[1]); 15313 insert += match[0].slice(offset2 + match[1].length); 15314 start2 += offset2; 15315 const cutOff = start2 - end2; 15316 if (cutOff > 0) { 15317 insert = match[0].slice(offset2 - cutOff, offset2) + insert; 15318 start2 = end2; 15319 } 15320 } 15321 state.tr.insertText(insert, start2, end2); 15322 } 15323 }); 15324} 15325function wrappingInputRule(config) { 15326 return new InputRule({ 15327 find: config.find, 15328 handler: ({ state, range, match, chain }) => { 15329 const attributes = callOrReturn(config.getAttributes, void 0, match) || {}; 15330 const tr2 = state.tr.delete(range.from, range.to); 15331 const $start = tr2.doc.resolve(range.from); 15332 const blockRange = $start.blockRange(); 15333 const wrapping = blockRange && findWrapping(blockRange, config.type, attributes); 15334 if (!wrapping) { 15335 return null; 15336 } 15337 tr2.wrap(blockRange, wrapping); 15338 if (config.keepMarks && config.editor) { 15339 const { selection, storedMarks } = state; 15340 const { splittableMarks } = config.editor.extensionManager; 15341 const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks(); 15342 if (marks) { 15343 const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name)); 15344 tr2.ensureMarks(filteredMarks); 15345 } 15346 } 15347 if (config.keepAttributes) { 15348 const nodeType = config.type.name === "bulletList" || config.type.name === "orderedList" ? "listItem" : "taskList"; 15349 chain().updateAttributes(nodeType, attributes).run(); 15350 } 15351 const before = tr2.doc.resolve(range.from - 1).nodeBefore; 15352 if (before && before.type === config.type && canJoin(tr2.doc, range.from - 1) && (!config.joinPredicate || config.joinPredicate(match, before))) { 15353 tr2.join(range.from - 1); 15354 } 15355 } 15356 }); 15357} 15358class Mark2 { 15359 constructor(config = {}) { 15360 this.type = "mark"; 15361 this.name = "mark"; 15362 this.parent = null; 15363 this.child = null; 15364 this.config = { 15365 name: this.name, 15366 defaultOptions: {} 15367 }; 15368 this.config = { 15369 ...this.config, 15370 ...config 15371 }; 15372 this.name = this.config.name; 15373 if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) { 15374 console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`); 15375 } 15376 this.options = this.config.defaultOptions; 15377 if (this.config.addOptions) { 15378 this.options = callOrReturn(getExtensionField(this, "addOptions", { 15379 name: this.name 15380 })); 15381 } 15382 this.storage = callOrReturn(getExtensionField(this, "addStorage", { 15383 name: this.name, 15384 options: this.options 15385 })) || {}; 15386 } 15387 static create(config = {}) { 15388 return new Mark2(config); 15389 } 15390 configure(options = {}) { 15391 const extension = this.extend(); 15392 extension.options = mergeDeep(this.options, options); 15393 extension.storage = callOrReturn(getExtensionField(extension, "addStorage", { 15394 name: extension.name, 15395 options: extension.options 15396 })); 15397 return extension; 15398 } 15399 extend(extendedConfig = {}) { 15400 const extension = new Mark2({ ...this.config, ...extendedConfig }); 15401 extension.parent = this; 15402 this.child = extension; 15403 extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name; 15404 if (extendedConfig.defaultOptions) { 15405 console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`); 15406 } 15407 extension.options = callOrReturn(getExtensionField(extension, "addOptions", { 15408 name: extension.name 15409 })); 15410 extension.storage = callOrReturn(getExtensionField(extension, "addStorage", { 15411 name: extension.name, 15412 options: extension.options 15413 })); 15414 return extension; 15415 } 15416 static handleExit({ editor, mark }) { 15417 const { tr: tr2 } = editor.state; 15418 const currentPos = editor.state.selection.$from; 15419 const isAtEnd = currentPos.pos === currentPos.end(); 15420 if (isAtEnd) { 15421 const currentMarks = currentPos.marks(); 15422 const isInMark = !!currentMarks.find((m) => (m === null || m === void 0 ? void 0 : m.type.name) === mark.name); 15423 if (!isInMark) { 15424 return false;
15425 } 15426 const removeMark2 = currentMarks.find((m) => (m === null || m === void 0 ? void 0 : m.type.name) === mark.name); 15427 if (removeMark2) { 15428 tr2.removeStoredMark(removeMark2); 15429 } 15430 tr2.insertText(" ", currentPos.pos); 15431 editor.view.dispatch(tr2); 15432 return true; 15433 } 15434 return false; 15435 } 15436} 15437class Node2 { 15438 constructor(config = {}) { 15439 this.type = "node"; 15440 this.name = "node"; 15441 this.parent = null; 15442 this.child = null; 15443 this.config = { 15444 name: this.name, 15445 defaultOptions: {} 15446 }; 15447 this.config = { 15448 ...this.config, 15449 ...config 15450 }; 15451 this.name = this.config.name; 15452 if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) { 15453 console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`); 15454 } 15455 this.options = this.config.defaultOptions; 15456 if (this.config.addOptions) { 15457 this.options = callOrReturn(getExtensionField(this, "addOptions", { 15458 name: this.name 15459 })); 15460 } 15461 this.storage = callOrReturn(getExtensionField(this, "addStorage", { 15462 name: this.name, 15463 options: this.options 15464 })) || {}; 15465 } 15466 static create(config = {}) { 15467 return new Node2(config); 15468 } 15469 configure(options = {}) { 15470 const extension = this.extend(); 15471 extension.options = mergeDeep(this.options, options); 15472 extension.storage = callOrReturn(getExtensionField(extension, "addStorage", { 15473 name: extension.name, 15474 options: extension.options 15475 })); 15476 return extension; 15477 } 15478 extend(extendedConfig = {}) { 15479 const extension = new Node2({ ...this.config, ...extendedConfig }); 15480 extension.parent = this; 15481 this.child = extension; 15482 extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name; 15483 if (extendedConfig.defaultOptions) { 15484 console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`); 15485 } 15486 extension.options = callOrReturn(getExtensionField(extension, "addOptions", { 15487 name: extension.name 15488 })); 15489 extension.storage = callOrReturn(getExtensionField(extension, "addStorage", { 15490 name: extension.name, 15491 options: extension.options 15492 })); 15493 return extension; 15494 } 15495} 15496function markPasteRule(config) { 15497 return new PasteRule({ 15498 find: config.find, 15499 handler: ({ state, range, match, pasteEvent }) => { 15500 const attributes = callOrReturn(config.getAttributes, void 0, match, pasteEvent); 15501 if (attributes === false || attributes === null) { 15502 return null; 15503 } 15504 const { tr: tr2 } = state; 15505 const captureGroup = match[match.length - 1]; 15506 const fullMatch = match[0]; 15507 let markEnd = range.to; 15508 if (captureGroup) { 15509 const startSpaces = fullMatch.search(/\S/); 15510 const textStart = range.from + fullMatch.indexOf(captureGroup); 15511 const textEnd = textStart + captureGroup.length; 15512 const excludedMarks = getMarksBetween(range.from, range.to, state.doc).filter((item) => { 15513 const excluded = item.mark.type.excluded; 15514 return excluded.find((type) => type === config.type && type !== item.mark.type); 15515 }).filter((item) => item.to > textStart); 15516 if (excludedMarks.length) { 15517 return null; 15518 } 15519 if (textEnd < range.to) { 15520 tr2.delete(textEnd, range.to); 15521 } 15522 if (textStart > range.from) { 15523 tr2.delete(range.from + startSpaces, textStart); 15524 } 15525 markEnd = range.from + startSpaces + captureGroup.length; 15526 tr2.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {})); 15527 tr2.removeStoredMark(config.type); 15528 } 15529 } 15530 }); 15531} 15532var top = "top"; 15533var bottom = "bottom"; 15534var right = "right"; 15535var left = "left"; 15536var auto = "auto"; 15537var basePlacements = [top, bottom, right, left]; 15538var start = "start"; 15539var end = "end"; 15540var clippingParents = "clippingParents"; 15541var viewport = "viewport"; 15542var popper = "popper"; 15543var reference = "reference"; 15544var variationPlacements = /* @__PURE__ */ basePlacements.reduce(function(acc, placement) { 15545 return acc.concat([placement + "-" + start, placement + "-" + end]); 15546}, []); 15547var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) { 15548 return acc.concat([placement, placement + "-" + start, placement + "-" + end]); 15549}, []); 15550var beforeRead = "beforeRead"; 15551var read = "read"; 15552var afterRead = "afterRead"; 15553var beforeMain = "beforeMain"; 15554var main = "main"; 15555var afterMain = "afterMain"; 15556var beforeWrite = "beforeWrite"; 15557var write = "write"; 15558var afterWrite = "afterWrite"; 15559var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; 15560function getNodeName(element) { 15561 return element ? (element.nodeName || "").toLowerCase() : null; 15562} 15563function getWindow(node) { 15564 if (node == null) { 15565 return window; 15566 } 15567 if (node.toString() !== "[object Window]") { 15568 var ownerDocument = node.ownerDocument; 15569 return ownerDocument ? ownerDocument.defaultView || window : window; 15570 } 15571 return node; 15572} 15573function isElement$1(node) { 15574 var OwnElement = getWindow(node).Element; 15575 return node instanceof OwnElement || node instanceof Element; 15576} 15577function isHTMLElement(node) { 15578 var OwnElement = getWindow(node).HTMLElement; 15579 return node instanceof OwnElement || node instanceof HTMLElement; 15580} 15581function isShadowRoot(node) { 15582 if (typeof ShadowRoot === "undefined") { 15583 return false;
vendor: 4,524 bytes, lines 15584-15733
15584 } 15585 var OwnElement = getWindow(node).ShadowRoot; 15586 return node instanceof OwnElement || node instanceof ShadowRoot; 15587} 15588function applyStyles(_ref) { 15589 var state = _ref.state; 15590 Object.keys(state.elements).forEach(function(name) { 15591 var style2 = state.styles[name] || {}; 15592 var attributes = state.attributes[name] || {}; 15593 var element = state.elements[name]; 15594 if (!isHTMLElement(element) || !getNodeName(element)) { 15595 return; 15596 } 15597 Object.assign(element.style, style2); 15598 Object.keys(attributes).forEach(function(name2) { 15599 var value = attributes[name2]; 15600 if (value === false) { 15601 element.removeAttribute(name2); 15602 } else { 15603 element.setAttribute(name2, value === true ? "" : value); 15604 } 15605 }); 15606 }); 15607} 15608function effect$2(_ref2) { 15609 var state = _ref2.state; 15610 var initialStyles = { 15611 popper: { 15612 position: state.options.strategy, 15613 left: "0", 15614 top: "0", 15615 margin: "0" 15616 }, 15617 arrow: { 15618 position: "absolute" 15619 }, 15620 reference: {} 15621 }; 15622 Object.assign(state.elements.popper.style, initialStyles.popper); 15623 state.styles = initialStyles; 15624 if (state.elements.arrow) { 15625 Object.assign(state.elements.arrow.style, initialStyles.arrow); 15626 } 15627 return function() { 15628 Object.keys(state.elements).forEach(function(name) { 15629 var element = state.elements[name]; 15630 var attributes = state.attributes[name] || {}; 15631 var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); 15632 var style2 = styleProperties.reduce(function(style3, property) { 15633 style3[property] = ""; 15634 return style3; 15635 }, {}); 15636 if (!isHTMLElement(element) || !getNodeName(element)) { 15637 return; 15638 } 15639 Object.assign(element.style, style2); 15640 Object.keys(attributes).forEach(function(attribute) { 15641 element.removeAttribute(attribute); 15642 }); 15643 }); 15644 }; 15645} 15646const applyStyles$1 = { 15647 name: "applyStyles", 15648 enabled: true, 15649 phase: "write", 15650 fn: applyStyles, 15651 effect: effect$2, 15652 requires: ["computeStyles"] 15653}; 15654function getBasePlacement$1(placement) { 15655 return placement.split("-")[0]; 15656} 15657var max = Math.max; 15658var min = Math.min; 15659var round = Math.round; 15660function getUAString() { 15661 var uaData = navigator.userAgentData; 15662 if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) { 15663 return uaData.brands.map(function(item) { 15664 return item.brand + "/" + item.version; 15665 }).join(" "); 15666 } 15667 return navigator.userAgent; 15668} 15669function isLayoutViewport() { 15670 return !/^((?!chrome|android).)*safari/i.test(getUAString()); 15671} 15672function getBoundingClientRect(element, includeScale, isFixedStrategy) { 15673 if (includeScale === void 0) { 15674 includeScale = false; 15675 } 15676 if (isFixedStrategy === void 0) { 15677 isFixedStrategy = false; 15678 } 15679 var clientRect2 = element.getBoundingClientRect(); 15680 var scaleX = 1; 15681 var scaleY = 1; 15682 if (includeScale && isHTMLElement(element)) { 15683 scaleX = element.offsetWidth > 0 ? round(clientRect2.width) / element.offsetWidth || 1 : 1; 15684 scaleY = element.offsetHeight > 0 ? round(clientRect2.height) / element.offsetHeight || 1 : 1; 15685 } 15686 var _ref = isElement$1(element) ? getWindow(element) : window, visualViewport = _ref.visualViewport; 15687 var addVisualOffsets = !isLayoutViewport() && isFixedStrategy; 15688 var x = (clientRect2.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX; 15689 var y = (clientRect2.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY; 15690 var width = clientRect2.width / scaleX; 15691 var height = clientRect2.height / scaleY; 15692 return { 15693 width, 15694 height, 15695 top: y, 15696 right: x + width, 15697 bottom: y + height, 15698 left: x, 15699 x, 15700 y 15701 }; 15702} 15703function getLayoutRect(element) { 15704 var clientRect2 = getBoundingClientRect(element); 15705 var width = element.offsetWidth; 15706 var height = element.offsetHeight; 15707 if (Math.abs(clientRect2.width - width) <= 1) { 15708 width = clientRect2.width; 15709 } 15710 if (Math.abs(clientRect2.height - height) <= 1) { 15711 height = clientRect2.height; 15712 } 15713 return { 15714 x: element.offsetLeft, 15715 y: element.offsetTop, 15716 width, 15717 height 15718 }; 15719} 15720function contains(parent, child) { 15721 var rootNode = child.getRootNode && child.getRootNode(); 15722 if (parent.contains(child)) { 15723 return true; 15724 } else if (rootNode && isShadowRoot(rootNode)) { 15725 var next = child; 15726 do { 15727 if (next && parent.isSameNode(next)) { 15728 return true; 15729 } 15730 next = next.parentNode || next.host; 15731 } while (next); 15732 } 15733 return false;
vendor: 4,171 bytes, lines 15734-15847
15734} 15735function getComputedStyle$1(element) { 15736 return getWindow(element).getComputedStyle(element); 15737} 15738function isTableElement(element) { 15739 return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0; 15740} 15741function getDocumentElement(element) { 15742 return ((isElement$1(element) ? element.ownerDocument : ( 15743 // $FlowFixMe[prop-missing] 15744 element.document 15745 )) || window.document).documentElement; 15746} 15747function getParentNode(element) { 15748 if (getNodeName(element) === "html") { 15749 return element; 15750 } 15751 return ( 15752 // this is a quicker (but less type safe) way to save quite some bytes from the bundle 15753 // $FlowFixMe[incompatible-return] 15754 // $FlowFixMe[prop-missing] 15755 element.assignedSlot || // step into the shadow DOM of the parent of a slotted node 15756 element.parentNode || // DOM Element detected 15757 (isShadowRoot(element) ? element.host : null) || // ShadowRoot detected 15758 // $FlowFixMe[incompatible-call]: HTMLElement is a Node 15759 getDocumentElement(element) 15760 ); 15761} 15762function getTrueOffsetParent(element) { 15763 if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 15764 getComputedStyle$1(element).position === "fixed") { 15765 return null; 15766 } 15767 return element.offsetParent; 15768} 15769function getContainingBlock(element) { 15770 var isFirefox = /firefox/i.test(getUAString()); 15771 var isIE = /Trident/i.test(getUAString()); 15772 if (isIE && isHTMLElement(element)) { 15773 var elementCss = getComputedStyle$1(element); 15774 if (elementCss.position === "fixed") { 15775 return null; 15776 } 15777 } 15778 var currentNode = getParentNode(element); 15779 if (isShadowRoot(currentNode)) { 15780 currentNode = currentNode.host; 15781 } 15782 while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) { 15783 var css = getComputedStyle$1(currentNode); 15784 if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") { 15785 return currentNode; 15786 } else { 15787 currentNode = currentNode.parentNode; 15788 } 15789 } 15790 return null; 15791} 15792function getOffsetParent(element) { 15793 var window2 = getWindow(element); 15794 var offsetParent = getTrueOffsetParent(element); 15795 while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === "static") { 15796 offsetParent = getTrueOffsetParent(offsetParent); 15797 } 15798 if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle$1(offsetParent).position === "static")) { 15799 return window2; 15800 } 15801 return offsetParent || getContainingBlock(element) || window2; 15802} 15803function getMainAxisFromPlacement(placement) { 15804 return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y"; 15805} 15806function within(min$1, value, max$1) { 15807 return max(min$1, min(value, max$1)); 15808} 15809function withinMaxClamp(min2, value, max2) { 15810 var v = within(min2, value, max2); 15811 return v > max2 ? max2 : v; 15812} 15813function getFreshSideObject() { 15814 return { 15815 top: 0, 15816 right: 0, 15817 bottom: 0, 15818 left: 0 15819 }; 15820} 15821function mergePaddingObject(paddingObject) { 15822 return Object.assign({}, getFreshSideObject(), paddingObject); 15823} 15824function expandToHashMap(value, keys2) { 15825 return keys2.reduce(function(hashMap, key) { 15826 hashMap[key] = value; 15827 return hashMap; 15828 }, {}); 15829} 15830var toPaddingObject = function toPaddingObject2(padding, state) { 15831 padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, { 15832 placement: state.placement 15833 })) : padding; 15834 return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); 15835}; 15836function arrow$2(_ref) { 15837 var _state$modifiersData$; 15838 var state = _ref.state, name = _ref.name, options = _ref.options; 15839 var arrowElement = state.elements.arrow; 15840 var popperOffsets2 = state.modifiersData.popperOffsets; 15841 var basePlacement = getBasePlacement$1(state.placement); 15842 var axis = getMainAxisFromPlacement(basePlacement); 15843 var isVertical = [left, right].indexOf(basePlacement) >= 0; 15844 var len = isVertical ? "height" : "width"; 15845 if (!arrowElement || !popperOffsets2) { 15846 return; 15847 }
vendor: 4,771 bytes, lines 15848-15972
15848 var paddingObject = toPaddingObject(options.padding, state); 15849 var arrowRect = getLayoutRect(arrowElement); 15850 var minProp = axis === "y" ? top : left; 15851 var maxProp = axis === "y" ? bottom : right; 15852 var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets2[axis] - state.rects.popper[len]; 15853 var startDiff = popperOffsets2[axis] - state.rects.reference[axis]; 15854 var arrowOffsetParent = getOffsetParent(arrowElement); 15855 var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; 15856 var centerToReference = endDiff / 2 - startDiff / 2; 15857 var min2 = paddingObject[minProp]; 15858 var max2 = clientSize - arrowRect[len] - paddingObject[maxProp]; 15859 var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; 15860 var offset2 = within(min2, center, max2); 15861 var axisProp = axis; 15862 state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset2, _state$modifiersData$.centerOffset = offset2 - center, _state$modifiersData$); 15863} 15864function effect$1(_ref2) { 15865 var state = _ref2.state, options = _ref2.options; 15866 var _options$element = options.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element; 15867 if (arrowElement == null) { 15868 return; 15869 } 15870 if (typeof arrowElement === "string") { 15871 arrowElement = state.elements.popper.querySelector(arrowElement); 15872 if (!arrowElement) { 15873 return; 15874 } 15875 } 15876 if (!contains(state.elements.popper, arrowElement)) { 15877 return; 15878 } 15879 state.elements.arrow = arrowElement; 15880} 15881const arrow$3 = { 15882 name: "arrow", 15883 enabled: true, 15884 phase: "main", 15885 fn: arrow$2, 15886 effect: effect$1, 15887 requires: ["popperOffsets"], 15888 requiresIfExists: ["preventOverflow"] 15889}; 15890function getVariation(placement) { 15891 return placement.split("-")[1]; 15892} 15893var unsetSides = { 15894 top: "auto", 15895 right: "auto", 15896 bottom: "auto", 15897 left: "auto" 15898}; 15899function roundOffsetsByDPR(_ref, win) { 15900 var x = _ref.x, y = _ref.y; 15901 var dpr = win.devicePixelRatio || 1; 15902 return { 15903 x: round(x * dpr) / dpr || 0, 15904 y: round(y * dpr) / dpr || 0 15905 }; 15906} 15907function mapToStyles(_ref2) { 15908 var _Object$assign2; 15909 var popper2 = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed; 15910 var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y; 15911 var _ref3 = typeof roundOffsets === "function" ? roundOffsets({ 15912 x, 15913 y 15914 }) : { 15915 x, 15916 y 15917 }; 15918 x = _ref3.x; 15919 y = _ref3.y; 15920 var hasX = offsets.hasOwnProperty("x"); 15921 var hasY = offsets.hasOwnProperty("y"); 15922 var sideX = left; 15923 var sideY = top; 15924 var win = window; 15925 if (adaptive) { 15926 var offsetParent = getOffsetParent(popper2); 15927 var heightProp = "clientHeight"; 15928 var widthProp = "clientWidth"; 15929 if (offsetParent === getWindow(popper2)) { 15930 offsetParent = getDocumentElement(popper2); 15931 if (getComputedStyle$1(offsetParent).position !== "static" && position === "absolute") { 15932 heightProp = "scrollHeight"; 15933 widthProp = "scrollWidth"; 15934 } 15935 } 15936 offsetParent = offsetParent; 15937 if (placement === top || (placement === left || placement === right) && variation === end) { 15938 sideY = bottom; 15939 var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : ( 15940 // $FlowFixMe[prop-missing] 15941 offsetParent[heightProp] 15942 ); 15943 y -= offsetY - popperRect.height; 15944 y *= gpuAcceleration ? 1 : -1; 15945 } 15946 if (placement === left || (placement === top || placement === bottom) && variation === end) { 15947 sideX = right; 15948 var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : ( 15949 // $FlowFixMe[prop-missing] 15950 offsetParent[widthProp] 15951 ); 15952 x -= offsetX - popperRect.width; 15953 x *= gpuAcceleration ? 1 : -1; 15954 } 15955 } 15956 var commonStyles = Object.assign({ 15957 position 15958 }, adaptive && unsetSides); 15959 var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ 15960 x, 15961 y 15962 }, getWindow(popper2)) : { 15963 x, 15964 y 15965 }; 15966 x = _ref4.x; 15967 y = _ref4.y; 15968 if (gpuAcceleration) { 15969 var _Object$assign; 15970 return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); 15971 } 15972 return Object.assign({}, commonStyles, (_Object$assign2 = {}
vendor: 3,911 bytes, lines 15972-16089
15972, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2)); 15973} 15974function computeStyles(_ref5) { 15975 var state = _ref5.state, options = _ref5.options; 15976 var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; 15977 var commonStyles = { 15978 placement: getBasePlacement$1(state.placement), 15979 variation: getVariation(state.placement), 15980 popper: state.elements.popper, 15981 popperRect: state.rects.popper, 15982 gpuAcceleration, 15983 isFixed: state.options.strategy === "fixed" 15984 }; 15985 if (state.modifiersData.popperOffsets != null) { 15986 state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { 15987 offsets: state.modifiersData.popperOffsets, 15988 position: state.options.strategy, 15989 adaptive, 15990 roundOffsets 15991 }))); 15992 } 15993 if (state.modifiersData.arrow != null) { 15994 state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { 15995 offsets: state.modifiersData.arrow, 15996 position: "absolute", 15997 adaptive: false, 15998 roundOffsets 15999 }))); 16000 } 16001 state.attributes.popper = Object.assign({}, state.attributes.popper, { 16002 "data-popper-placement": state.placement 16003 }); 16004} 16005const computeStyles$1 = { 16006 name: "computeStyles", 16007 enabled: true, 16008 phase: "beforeWrite", 16009 fn: computeStyles, 16010 data: {} 16011}; 16012var passive = { 16013 passive: true 16014}; 16015function effect(_ref) { 16016 var state = _ref.state, instance = _ref.instance, options = _ref.options; 16017 var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize; 16018 var window2 = getWindow(state.elements.popper); 16019 var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); 16020 if (scroll) { 16021 scrollParents.forEach(function(scrollParent) { 16022 scrollParent.addEventListener("scroll", instance.update, passive); 16023 }); 16024 } 16025 if (resize) { 16026 window2.addEventListener("resize", instance.update, passive); 16027 } 16028 return function() { 16029 if (scroll) { 16030 scrollParents.forEach(function(scrollParent) { 16031 scrollParent.removeEventListener("scroll", instance.update, passive); 16032 }); 16033 } 16034 if (resize) { 16035 window2.removeEventListener("resize", instance.update, passive); 16036 } 16037 }; 16038} 16039const eventListeners = { 16040 name: "eventListeners", 16041 enabled: true, 16042 phase: "write", 16043 fn: function fn() { 16044 }, 16045 effect, 16046 data: {} 16047}; 16048var hash$1 = { 16049 left: "right", 16050 right: "left", 16051 bottom: "top", 16052 top: "bottom" 16053}; 16054function getOppositePlacement(placement) { 16055 return placement.replace(/left|right|bottom|top/g, function(matched) { 16056 return hash$1[matched]; 16057 }); 16058} 16059var hash = { 16060 start: "end", 16061 end: "start" 16062}; 16063function getOppositeVariationPlacement(placement) { 16064 return placement.replace(/start|end/g, function(matched) { 16065 return hash[matched]; 16066 }); 16067} 16068function getWindowScroll(node) { 16069 var win = getWindow(node); 16070 var scrollLeft = win.pageXOffset; 16071 var scrollTop = win.pageYOffset; 16072 return { 16073 scrollLeft, 16074 scrollTop 16075 }; 16076} 16077function getWindowScrollBarX(element) { 16078 return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; 16079} 16080function getViewportRect(element, strategy) { 16081 var win = getWindow(element); 16082 var html = getDocumentElement(element); 16083 var visualViewport = win.visualViewport; 16084 var width = html.clientWidth; 16085 var height = html.clientHeight; 16086 var x = 0; 16087 var y = 0; 16088 if (visualViewport) { 16089 width = visualViewport.width;
vendor: 20,216 bytes, lines 16090-16581
16090 height = visualViewport.height; 16091 var layoutViewport = isLayoutViewport(); 16092 if (layoutViewport || !layoutViewport && strategy === "fixed") { 16093 x = visualViewport.offsetLeft; 16094 y = visualViewport.offsetTop; 16095 } 16096 } 16097 return { 16098 width, 16099 height, 16100 x: x + getWindowScrollBarX(element), 16101 y 16102 }; 16103} 16104function getDocumentRect(element) { 16105 var _element$ownerDocumen; 16106 var html = getDocumentElement(element); 16107 var winScroll = getWindowScroll(element); 16108 var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; 16109 var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); 16110 var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); 16111 var x = -winScroll.scrollLeft + getWindowScrollBarX(element); 16112 var y = -winScroll.scrollTop; 16113 if (getComputedStyle$1(body || html).direction === "rtl") { 16114 x += max(html.clientWidth, body ? body.clientWidth : 0) - width; 16115 } 16116 return { 16117 width, 16118 height, 16119 x, 16120 y 16121 }; 16122} 16123function isScrollParent(element) { 16124 var _getComputedStyle = getComputedStyle$1(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY; 16125 return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); 16126} 16127function getScrollParent(node) { 16128 if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) { 16129 return node.ownerDocument.body; 16130 } 16131 if (isHTMLElement(node) && isScrollParent(node)) { 16132 return node; 16133 } 16134 return getScrollParent(getParentNode(node)); 16135} 16136function listScrollParents(element, list) { 16137 var _element$ownerDocumen; 16138 if (list === void 0) { 16139 list = []; 16140 } 16141 var scrollParent = getScrollParent(element); 16142 var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); 16143 var win = getWindow(scrollParent); 16144 var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; 16145 var updatedList = list.concat(target); 16146 return isBody ? updatedList : ( 16147 // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here 16148 updatedList.concat(listScrollParents(getParentNode(target))) 16149 ); 16150} 16151function rectToClientRect(rect) { 16152 return Object.assign({}, rect, { 16153 left: rect.x, 16154 top: rect.y, 16155 right: rect.x + rect.width, 16156 bottom: rect.y + rect.height 16157 }); 16158} 16159function getInnerBoundingClientRect(element, strategy) { 16160 var rect = getBoundingClientRect(element, false, strategy === "fixed"); 16161 rect.top = rect.top + element.clientTop; 16162 rect.left = rect.left + element.clientLeft; 16163 rect.bottom = rect.top + element.clientHeight; 16164 rect.right = rect.left + element.clientWidth; 16165 rect.width = element.clientWidth; 16166 rect.height = element.clientHeight; 16167 rect.x = rect.left; 16168 rect.y = rect.top; 16169 return rect; 16170} 16171function getClientRectFromMixedType(element, clippingParent, strategy) { 16172 return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement$1(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element))); 16173} 16174function getClippingParents(element) { 16175 var clippingParents2 = listScrollParents(getParentNode(element)); 16176 var canEscapeClipping = ["absolute", "fixed"].indexOf(getComputedStyle$1(element).position) >= 0; 16177 var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; 16178 if (!isElement$1(clipperElement)) { 16179 return []; 16180 } 16181 return clippingParents2.filter(function(clippingParent) { 16182 return isElement$1(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== "body"; 16183 }); 16184} 16185function getClippingRect(element, boundary, rootBoundary, strategy) { 16186 var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary); 16187 var clippingParents2 = [].concat(mainClippingParents, [rootBoundary]); 16188 var firstClippingParent = clippingParents2[0]; 16189 var clippingRect = clippingParents2.reduce(function(accRect, clippingParent) { 16190 var rect = getClientRectFromMixedType(element, clippingParent, strategy); 16191 accRect.top = max(rect.top, accRect.top); 16192 accRect.right = min(rect.right, accRect.right); 16193 accRect.bottom = min(rect.bottom, accRect.bottom); 16194 accRect.left = max(rect.left, accRect.left); 16195 return accRect; 16196 }, getClientRectFromMixedType(element, firstClippingParent, strategy)); 16197 clippingRect.width = clippingRect.right - clippingRect.left; 16198 clippingRect.height = clippingRect.bottom - clippingRect.top; 16199 clippingRect.x = clippingRect.left; 16200 clippingRect.y = clippingRect.top; 16201 return clippingRect; 16202} 16203function computeOffsets(_ref) { 16204 var reference2 = _ref.reference, element = _ref.element, placement = _ref.placement; 16205 var basePlacement = placement ? getBasePlacement$1(placement) : null; 16206 var variation = placement ? getVariation(placement) : null; 16207 var commonX = reference2.x + reference2.width / 2 - element.width / 2; 16208 var commonY = reference2.y + reference2.height / 2 - element.height / 2; 16209 var offsets; 16210 switch (basePlacement) { 16211 case top: 16212 offsets = { 16213 x: commonX, 16214 y: reference2.y - element.height 16215 }; 16216 break; 16217 case bottom: 16218 offsets = { 16219 x: commonX, 16220 y: reference2.y + reference2.height 16221 }; 16222 break; 16223 case right: 16224 offsets = { 16225 x: reference2.x + reference2.width, 16226 y: commonY 16227 }; 16228 break; 16229 case left: 16230 offsets = { 16231 x: reference2.x - element.width, 16232 y: commonY 16233 }; 16234 break; 16235 default: 16236 offsets = { 16237 x: reference2.x, 16238 y: reference2.y 16239 }; 16240 } 16241 var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; 16242 if (mainAxis != null) { 16243 var len = mainAxis === "y" ? "height" : "width"; 16244 switch (variation) { 16245 case start: 16246 offsets[mainAxis] = offsets[mainAxis] - (reference2[len] / 2 - element[len] / 2); 16247 break; 16248 case end: 16249 offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2); 16250 break; 16251 } 16252 } 16253 return offsets; 16254} 16255function detectOverflow(state, options) { 16256 if (options === void 0) { 16257 options = {}; 16258 } 16259 var _options = options, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$strategy = _options.strategy, strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding; 16260 var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); 16261 var altContext = elementContext === popper ? reference : popper; 16262 var popperRect = state.rects.popper; 16263 var element = state.elements[altBoundary ? altContext : elementContext]; 16264 var clippingClientRect = getClippingRect(isElement$1(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy); 16265 var referenceClientRect = getBoundingClientRect(state.elements.reference); 16266 var popperOffsets2 = computeOffsets({ 16267 reference: referenceClientRect, 16268 element: popperRect, 16269 strategy: "absolute", 16270 placement 16271 }); 16272 var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2)); 16273 var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; 16274 var overflowOffsets = { 16275 top: clippingClientRect.top - elementClientRect.top + paddingObject.top, 16276 bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, 16277 left: clippingClientRect.left - elementClientRect.left + paddingObject.left, 16278 right: elementClientRect.right - clippingClientRect.right + paddingObject.right 16279 }; 16280 var offsetData = state.modifiersData.offset; 16281 if (elementContext === popper && offsetData) { 16282 var offset2 = offsetData[placement]; 16283 Object.keys(overflowOffsets).forEach(function(key) { 16284 var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; 16285 var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x"; 16286 overflowOffsets[key] += offset2[axis] * multiply; 16287 }); 16288 } 16289 return overflowOffsets; 16290} 16291function computeAutoPlacement(state, options) { 16292 if (options === void 0) { 16293 options = {}; 16294 } 16295 var _options = options, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; 16296 var variation = getVariation(placement); 16297 var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function(placement2) { 16298 return getVariation(placement2) === variation; 16299 }) : basePlacements; 16300 var allowedPlacements = placements$1.filter(function(placement2) { 16301 return allowedAutoPlacements.indexOf(placement2) >= 0; 16302 }); 16303 if (allowedPlacements.length === 0) { 16304 allowedPlacements = placements$1; 16305 } 16306 var overflows = allowedPlacements.reduce(function(acc, placement2) { 16307 acc[placement2] = detectOverflow(state, { 16308 placement: placement2, 16309 boundary, 16310 rootBoundary, 16311 padding 16312 })[getBasePlacement$1(placement2)]; 16313 return acc; 16314 }, {}); 16315 return Object.keys(overflows).sort(function(a, b) { 16316 return overflows[a] - overflows[b]; 16317 }); 16318} 16319function getExpandedFallbackPlacements(placement) { 16320 if (getBasePlacement$1(placement) === auto) { 16321 return []; 16322 } 16323 var oppositePlacement = getOppositePlacement(placement); 16324 return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; 16325} 16326function flip(_ref) { 16327 var state = _ref.state, options = _ref.options, name = _ref.name; 16328 if (state.modifiersData[name]._skip) { 16329 return; 16330 } 16331 var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options.fallbackPlacements, padding = options.padding, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, _options$flipVariatio = options.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options.allowedAutoPlacements; 16332 var preferredPlacement = state.options.placement; 16333 var basePlacement = getBasePlacement$1(preferredPlacement); 16334 var isBasePlacement = basePlacement === preferredPlacement; 16335 var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); 16336 var placements2 = [preferredPlacement].concat(fallbackPlacements).reduce(function(acc, placement2) { 16337 return acc.concat(getBasePlacement$1(placement2) === auto ? computeAutoPlacement(state, { 16338 placement: placement2, 16339 boundary, 16340 rootBoundary, 16341 padding, 16342 flipVariations, 16343 allowedAutoPlacements 16344 }) : placement2); 16345 }, []); 16346 var referenceRect = state.rects.reference; 16347 var popperRect = state.rects.popper; 16348 var checksMap = /* @__PURE__ */ new Map(); 16349 var makeFallbackChecks = true; 16350 var firstFittingPlacement = placements2[0]; 16351 for (var i = 0; i < placements2.length; i++) { 16352 var placement = placements2[i]; 16353 var _basePlacement = getBasePlacement$1(placement); 16354 var isStartVariation = getVariation(placement) === start; 16355 var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; 16356 var len = isVertical ? "width" : "height"; 16357 var overflow = detectOverflow(state, { 16358 placement, 16359 boundary, 16360 rootBoundary, 16361 altBoundary, 16362 padding 16363 }); 16364 var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; 16365 if (referenceRect[len] > popperRect[len]) { 16366 mainVariationSide = getOppositePlacement(mainVariationSide); 16367 } 16368 var altVariationSide = getOppositePlacement(mainVariationSide); 16369 var checks = []; 16370 if (checkMainAxis) { 16371 checks.push(overflow[_basePlacement] <= 0); 16372 } 16373 if (checkAltAxis) { 16374 checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); 16375 } 16376 if (checks.every(function(check) { 16377 return check; 16378 })) { 16379 firstFittingPlacement = placement; 16380 makeFallbackChecks = false; 16381 break; 16382 } 16383 checksMap.set(placement, checks); 16384 } 16385 if (makeFallbackChecks) { 16386 var numberOfChecks = flipVariations ? 3 : 1; 16387 var _loop = function _loop2(_i2) { 16388 var fittingPlacement = placements2.find(function(placement2) { 16389 var checks2 = checksMap.get(placement2); 16390 if (checks2) { 16391 return checks2.slice(0, _i2).every(function(check) { 16392 return check; 16393 }); 16394 } 16395 }); 16396 if (fittingPlacement) { 16397 firstFittingPlacement = fittingPlacement; 16398 return "break"; 16399 } 16400 }; 16401 for (var _i = numberOfChecks; _i > 0; _i--) { 16402 var _ret = _loop(_i); 16403 if (_ret === "break") 16404 break; 16405 } 16406 } 16407 if (state.placement !== firstFittingPlacement) { 16408 state.modifiersData[name]._skip = true; 16409 state.placement = firstFittingPlacement; 16410 state.reset = true; 16411 } 16412} 16413const flip$1 = { 16414 name: "flip", 16415 enabled: true, 16416 phase: "main", 16417 fn: flip, 16418 requiresIfExists: ["offset"], 16419 data: { 16420 _skip: false 16421 } 16422}; 16423function getSideOffsets(overflow, rect, preventedOffsets) { 16424 if (preventedOffsets === void 0) { 16425 preventedOffsets = { 16426 x: 0, 16427 y: 0 16428 }; 16429 } 16430 return { 16431 top: overflow.top - rect.height - preventedOffsets.y, 16432 right: overflow.right - rect.width + preventedOffsets.x, 16433 bottom: overflow.bottom - rect.height + preventedOffsets.y, 16434 left: overflow.left - rect.width - preventedOffsets.x 16435 }; 16436} 16437function isAnySideFullyClipped(overflow) { 16438 return [top, right, bottom, left].some(function(side) { 16439 return overflow[side] >= 0; 16440 }); 16441} 16442function hide(_ref) { 16443 var state = _ref.state, name = _ref.name; 16444 var referenceRect = state.rects.reference; 16445 var popperRect = state.rects.popper; 16446 var preventedOffsets = state.modifiersData.preventOverflow; 16447 var referenceOverflow = detectOverflow(state, { 16448 elementContext: "reference" 16449 }); 16450 var popperAltOverflow = detectOverflow(state, { 16451 altBoundary: true 16452 }); 16453 var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); 16454 var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); 16455 var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); 16456 var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); 16457 state.modifiersData[name] = { 16458 referenceClippingOffsets, 16459 popperEscapeOffsets, 16460 isReferenceHidden, 16461 hasPopperEscaped 16462 }; 16463 state.attributes.popper = Object.assign({}, state.attributes.popper, { 16464 "data-popper-reference-hidden": isReferenceHidden, 16465 "data-popper-escaped": hasPopperEscaped 16466 }); 16467} 16468const hide$1 = { 16469 name: "hide", 16470 enabled: true, 16471 phase: "main", 16472 requiresIfExists: ["preventOverflow"], 16473 fn: hide 16474}; 16475function distanceAndSkiddingToXY(placement, rects, offset2) { 16476 var basePlacement = getBasePlacement$1(placement); 16477 var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; 16478 var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, { 16479 placement 16480 })) : offset2, skidding = _ref[0], distance = _ref[1]; 16481 skidding = skidding || 0; 16482 distance = (distance || 0) * invertDistance; 16483 return [left, right].indexOf(basePlacement) >= 0 ? { 16484 x: distance, 16485 y: skidding 16486 } : { 16487 x: skidding, 16488 y: distance 16489 }; 16490} 16491function offset(_ref2) { 16492 var state = _ref2.state, options = _ref2.options, name = _ref2.name; 16493 var _options$offset = options.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset; 16494 var data = placements.reduce(function(acc, placement) { 16495 acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2); 16496 return acc; 16497 }, {}); 16498 var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y; 16499 if (state.modifiersData.popperOffsets != null) { 16500 state.modifiersData.popperOffsets.x += x; 16501 state.modifiersData.popperOffsets.y += y; 16502 } 16503 state.modifiersData[name] = data; 16504} 16505const offset$1 = { 16506 name: "offset", 16507 enabled: true, 16508 phase: "main", 16509 requires: ["popperOffsets"], 16510 fn: offset 16511}; 16512function popperOffsets(_ref) { 16513 var state = _ref.state, name = _ref.name; 16514 state.modifiersData[name] = computeOffsets({ 16515 reference: state.rects.reference, 16516 element: state.rects.popper, 16517 strategy: "absolute", 16518 placement: state.placement 16519 }); 16520} 16521const popperOffsets$1 = { 16522 name: "popperOffsets", 16523 enabled: true, 16524 phase: "read", 16525 fn: popperOffsets, 16526 data: {} 16527}; 16528function getAltAxis(axis) { 16529 return axis === "x" ? "y" : "x"; 16530} 16531function preventOverflow(_ref) { 16532 var state = _ref.state, options = _ref.options, name = _ref.name; 16533 var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, padding = options.padding, _options$tether = options.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; 16534 var overflow = detectOverflow(state, { 16535 boundary, 16536 rootBoundary, 16537 padding, 16538 altBoundary 16539 }); 16540 var basePlacement = getBasePlacement$1(state.placement); 16541 var variation = getVariation(state.placement); 16542 var isBasePlacement = !variation; 16543 var mainAxis = getMainAxisFromPlacement(basePlacement); 16544 var altAxis = getAltAxis(mainAxis); 16545 var popperOffsets2 = state.modifiersData.popperOffsets; 16546 var referenceRect = state.rects.reference; 16547 var popperRect = state.rects.popper; 16548 var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, { 16549 placement: state.placement 16550 })) : tetherOffset; 16551 var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? { 16552 mainAxis: tetherOffsetValue, 16553 altAxis: tetherOffsetValue 16554 } : Object.assign({ 16555 mainAxis: 0, 16556 altAxis: 0 16557 }, tetherOffsetValue); 16558 var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; 16559 var data = { 16560 x: 0, 16561 y: 0 16562 }; 16563 if (!popperOffsets2) { 16564 return; 16565 } 16566 if (checkMainAxis) { 16567 var _offsetModifierState$; 16568 var mainSide = mainAxis === "y" ? top : left; 16569 var altSide = mainAxis === "y" ? bottom : right; 16570 var len = mainAxis === "y" ? "height" : "width"; 16571 var offset2 = popperOffsets2[mainAxis]; 16572 var min$1 = offset2 + overflow[mainSide]; 16573 var max$1 = offset2 - overflow[altSide]; 16574 var additive = tether ? -popperRect[len] / 2 : 0; 16575 var minLen = variation === start ? referenceRect[len] : popperRect[len]; 16576 var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; 16577 var arrowElement = state.elements.arrow; 16578 var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { 16579 width: 0, 16580 height: 0 16581 };
vendor: 4,824 bytes, lines 16582-16681
16582 var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject(); 16583 var arrowPaddingMin = arrowPaddingObject[mainSide]; 16584 var arrowPaddingMax = arrowPaddingObject[altSide]; 16585 var arrowLen = within(0, referenceRect[len], arrowRect[len]); 16586 var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; 16587 var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; 16588 var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); 16589 var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; 16590 var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; 16591 var tetherMin = offset2 + minOffset - offsetModifierValue - clientOffset; 16592 var tetherMax = offset2 + maxOffset - offsetModifierValue; 16593 var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset2, tether ? max(max$1, tetherMax) : max$1); 16594 popperOffsets2[mainAxis] = preventedOffset; 16595 data[mainAxis] = preventedOffset - offset2; 16596 } 16597 if (checkAltAxis) { 16598 var _offsetModifierState$2; 16599 var _mainSide = mainAxis === "x" ? top : left; 16600 var _altSide = mainAxis === "x" ? bottom : right; 16601 var _offset = popperOffsets2[altAxis]; 16602 var _len = altAxis === "y" ? "height" : "width"; 16603 var _min = _offset + overflow[_mainSide]; 16604 var _max = _offset - overflow[_altSide]; 16605 var isOriginSide = [top, left].indexOf(basePlacement) !== -1; 16606 var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; 16607 var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; 16608 var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; 16609 var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); 16610 popperOffsets2[altAxis] = _preventedOffset; 16611 data[altAxis] = _preventedOffset - _offset; 16612 } 16613 state.modifiersData[name] = data; 16614} 16615const preventOverflow$1 = { 16616 name: "preventOverflow", 16617 enabled: true, 16618 phase: "main", 16619 fn: preventOverflow, 16620 requiresIfExists: ["offset"] 16621}; 16622function getHTMLElementScroll(element) { 16623 return { 16624 scrollLeft: element.scrollLeft, 16625 scrollTop: element.scrollTop 16626 }; 16627} 16628function getNodeScroll(node) { 16629 if (node === getWindow(node) || !isHTMLElement(node)) { 16630 return getWindowScroll(node); 16631 } else { 16632 return getHTMLElementScroll(node); 16633 } 16634} 16635function isElementScaled(element) { 16636 var rect = element.getBoundingClientRect(); 16637 var scaleX = round(rect.width) / element.offsetWidth || 1; 16638 var scaleY = round(rect.height) / element.offsetHeight || 1; 16639 return scaleX !== 1 || scaleY !== 1; 16640} 16641function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { 16642 if (isFixed === void 0) { 16643 isFixed = false; 16644 } 16645 var isOffsetParentAnElement = isHTMLElement(offsetParent); 16646 var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); 16647 var documentElement = getDocumentElement(offsetParent); 16648 var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed); 16649 var scroll = { 16650 scrollLeft: 0, 16651 scrollTop: 0 16652 }; 16653 var offsets = { 16654 x: 0, 16655 y: 0 16656 }; 16657 if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { 16658 if (getNodeName(offsetParent) !== "body" || // https://github.com/popperjs/popper-core/issues/1078 16659 isScrollParent(documentElement)) { 16660 scroll = getNodeScroll(offsetParent); 16661 } 16662 if (isHTMLElement(offsetParent)) { 16663 offsets = getBoundingClientRect(offsetParent, true); 16664 offsets.x += offsetParent.clientLeft; 16665 offsets.y += offsetParent.clientTop; 16666 } else if (documentElement) { 16667 offsets.x = getWindowScrollBarX(documentElement); 16668 } 16669 } 16670 return { 16671 x: rect.left + scroll.scrollLeft - offsets.x, 16672 y: rect.top + scroll.scrollTop - offsets.y, 16673 width: rect.width, 16674 height: rect.height 16675 }; 16676} 16677function order(modifiers2) { 16678 var map2 = /* @__PURE__ */ new Map(); 16679 var visited = /* @__PURE__ */ new Set(); 16680 var result = []; 16681 modifiers2.forEach(function(modifier) {
vendor: 4,062 bytes, lines 16682-16796
16682 map2.set(modifier.name, modifier); 16683 }); 16684 function sort(modifier) { 16685 visited.add(modifier.name); 16686 var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); 16687 requires.forEach(function(dep) { 16688 if (!visited.has(dep)) { 16689 var depModifier = map2.get(dep); 16690 if (depModifier) { 16691 sort(depModifier); 16692 } 16693 } 16694 }); 16695 result.push(modifier); 16696 } 16697 modifiers2.forEach(function(modifier) { 16698 if (!visited.has(modifier.name)) { 16699 sort(modifier); 16700 } 16701 }); 16702 return result; 16703} 16704function orderModifiers(modifiers2) { 16705 var orderedModifiers = order(modifiers2); 16706 return modifierPhases.reduce(function(acc, phase) { 16707 return acc.concat(orderedModifiers.filter(function(modifier) { 16708 return modifier.phase === phase; 16709 })); 16710 }, []); 16711} 16712function debounce$1(fn2) { 16713 var pending; 16714 return function() { 16715 if (!pending) { 16716 pending = new Promise(function(resolve) { 16717 Promise.resolve().then(function() { 16718 pending = void 0; 16719 resolve(fn2()); 16720 }); 16721 }); 16722 } 16723 return pending; 16724 }; 16725} 16726function mergeByName(modifiers2) { 16727 var merged = modifiers2.reduce(function(merged2, current) { 16728 var existing = merged2[current.name]; 16729 merged2[current.name] = existing ? Object.assign({}, existing, current, { 16730 options: Object.assign({}, existing.options, current.options), 16731 data: Object.assign({}, existing.data, current.data) 16732 }) : current; 16733 return merged2; 16734 }, {}); 16735 return Object.keys(merged).map(function(key) { 16736 return merged[key]; 16737 }); 16738} 16739var DEFAULT_OPTIONS = { 16740 placement: "bottom", 16741 modifiers: [], 16742 strategy: "absolute" 16743}; 16744function areValidElements() { 16745 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 16746 args[_key] = arguments[_key]; 16747 } 16748 return !args.some(function(element) { 16749 return !(element && typeof element.getBoundingClientRect === "function"); 16750 }); 16751} 16752function popperGenerator(generatorOptions) { 16753 if (generatorOptions === void 0) { 16754 generatorOptions = {}; 16755 } 16756 var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers2 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; 16757 return function createPopper2(reference2, popper2, options) { 16758 if (options === void 0) { 16759 options = defaultOptions; 16760 } 16761 var state = { 16762 placement: "bottom", 16763 orderedModifiers: [], 16764 options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), 16765 modifiersData: {}, 16766 elements: { 16767 reference: reference2, 16768 popper: popper2 16769 }, 16770 attributes: {}, 16771 styles: {} 16772 }; 16773 var effectCleanupFns = []; 16774 var isDestroyed = false; 16775 var instance = { 16776 state, 16777 setOptions: function setOptions(setOptionsAction) { 16778 var options2 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction; 16779 cleanupModifierEffects(); 16780 state.options = Object.assign({}, defaultOptions, state.options, options2); 16781 state.scrollParents = { 16782 reference: isElement$1(reference2) ? listScrollParents(reference2) : reference2.contextElement ? listScrollParents(reference2.contextElement) : [], 16783 popper: listScrollParents(popper2) 16784 }; 16785 var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers2, state.options.modifiers))); 16786 state.orderedModifiers = orderedModifiers.filter(function(m) { 16787 return m.enabled; 16788 }); 16789 runModifierEffects(); 16790 return instance.update(); 16791 }, 16792 // Sync update â it will always be executed, even if not necessary. This 16793 // is useful for low frequency updates where sync behavior simplifies the 16794 // logic. 16795 // For high frequency updates (e.g. `resize` and `scroll` events), always 16796 // prefer the async Popper#update method
16797 forceUpdate: function forceUpdate() { 16798 if (isDestroyed) { 16799 return; 16800 } 16801 var _state$elements = state.elements, reference3 = _state$elements.reference, popper3 = _state$elements.popper; 16802 if (!areValidElements(reference3, popper3)) { 16803 return; 16804 } 16805 state.rects = { 16806 reference: getCompositeRect(reference3, getOffsetParent(popper3), state.options.strategy === "fixed"), 16807 popper: getLayoutRect(popper3) 16808 }; 16809 state.reset = false; 16810 state.placement = state.options.placement; 16811 state.orderedModifiers.forEach(function(modifier) { 16812 return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); 16813 }); 16814 for (var index = 0; index < state.orderedModifiers.length; index++) { 16815 if (state.reset === true) { 16816 state.reset = false; 16817 index = -1; 16818 continue; 16819 } 16820 var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name; 16821 if (typeof fn2 === "function") { 16822 state = fn2({ 16823 state, 16824 options: _options, 16825 name, 16826 instance 16827 }) || state; 16828 } 16829 } 16830 }, 16831 // Async and optimistically optimized update â it will not be executed if 16832 // not necessary (debounced to run at most once-per-tick) 16833 update: debounce$1(function() { 16834 return new Promise(function(resolve) { 16835 instance.forceUpdate(); 16836 resolve(state); 16837 }); 16838 }), 16839 destroy: function destroy() { 16840 cleanupModifierEffects(); 16841 isDestroyed = true; 16842 } 16843 }; 16844 if (!areValidElements(reference2, popper2)) { 16845 return instance; 16846 } 16847 instance.setOptions(options).then(function(state2) { 16848 if (!isDestroyed && options.onFirstUpdate) { 16849 options.onFirstUpdate(state2); 16850 } 16851 }); 16852 function runModifierEffects() { 16853 state.orderedModifiers.forEach(function(_ref) { 16854 var name = _ref.name, _ref$options = _ref.options, options2 = _ref$options === void 0 ? {} : _ref$options, effect3 = _ref.effect; 16855 if (typeof effect3 === "function") { 16856 var cleanupFn = effect3({ 16857 state, 16858 name, 16859 instance, 16860 options: options2 16861 }); 16862 var noopFn = function noopFn2() { 16863 }; 16864 effectCleanupFns.push(cleanupFn || noopFn); 16865 } 16866 }); 16867 } 16868 function cleanupModifierEffects() { 16869 effectCleanupFns.forEach(function(fn2) { 16870 return fn2(); 16871 }); 16872 effectCleanupFns = []; 16873 } 16874 return instance; 16875 }; 16876} 16877var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$3, hide$1]; 16878var createPopper = /* @__PURE__ */ popperGenerator({ 16879 defaultModifiers 16880}); 16881var BOX_CLASS = "tippy-box"; 16882var CONTENT_CLASS = "tippy-content"; 16883var BACKDROP_CLASS = "tippy-backdrop"; 16884var ARROW_CLASS = "tippy-arrow"; 16885var SVG_ARROW_CLASS = "tippy-svg-arrow"; 16886var TOUCH_OPTIONS = { 16887 passive: true, 16888 capture: true 16889}; 16890var TIPPY_DEFAULT_APPEND_TO = function TIPPY_DEFAULT_APPEND_TO2() { 16891 return document.body; 16892}; 16893function getValueAtIndexOrReturn(value, index, defaultValue) { 16894 if (Array.isArray(value)) { 16895 var v = value[index]; 16896 return v == null ? Array.isArray(defaultValue) ? defaultValue[index] : defaultValue : v; 16897 } 16898 return value; 16899} 16900function isType(value, type) { 16901 var str = {}.toString.call(value); 16902 return str.indexOf("[object") === 0 && str.indexOf(type + "]") > -1; 16903} 16904function invokeWithArgsOrReturn(value, args) { 16905 return typeof value === "function" ? value.apply(void 0, args) : value; 16906} 16907function debounce(fn2, ms) { 16908 if (ms === 0) { 16909 return fn2; 16910 } 16911 var timeout; 16912 return function(arg) { 16913 clearTimeout(timeout); 16914 timeout = setTimeout(function() { 16915 fn2(arg); 16916 }, ms); 16917 }; 16918} 16919function splitBySpaces(value) {
vendor: 1,374 bytes, lines 16920-16978
16920 return value.split(/\s+/).filter(Boolean); 16921} 16922function normalizeToArray(value) { 16923 return [].concat(value); 16924} 16925function pushIfUnique(arr, value) { 16926 if (arr.indexOf(value) === -1) { 16927 arr.push(value); 16928 } 16929} 16930function unique(arr) { 16931 return arr.filter(function(item, index) { 16932 return arr.indexOf(item) === index; 16933 }); 16934} 16935function getBasePlacement(placement) { 16936 return placement.split("-")[0]; 16937} 16938function arrayFrom(value) { 16939 return [].slice.call(value); 16940} 16941function removeUndefinedProps(obj) { 16942 return Object.keys(obj).reduce(function(acc, key) { 16943 if (obj[key] !== void 0) { 16944 acc[key] = obj[key]; 16945 } 16946 return acc; 16947 }, {}); 16948} 16949function div() { 16950 return document.createElement("div"); 16951} 16952function isElement(value) { 16953 return ["Element", "Fragment"].some(function(type) { 16954 return isType(value, type); 16955 }); 16956} 16957function isNodeList(value) { 16958 return isType(value, "NodeList"); 16959} 16960function isMouseEvent(value) { 16961 return isType(value, "MouseEvent"); 16962} 16963function isReferenceElement(value) { 16964 return !!(value && value._tippy && value._tippy.reference === value); 16965} 16966function getArrayOfElements(value) { 16967 if (isElement(value)) { 16968 return [value]; 16969 } 16970 if (isNodeList(value)) { 16971 return arrayFrom(value); 16972 } 16973 if (Array.isArray(value)) { 16974 return value; 16975 } 16976 return arrayFrom(document.querySelectorAll(value)); 16977} 16978function setTransitionDuration(els, value) {
vendor: 19,267 bytes, lines 16979-17591
16979 els.forEach(function(el) { 16980 if (el) { 16981 el.style.transitionDuration = value + "ms"; 16982 } 16983 }); 16984} 16985function setVisibilityState(els, state) { 16986 els.forEach(function(el) { 16987 if (el) { 16988 el.setAttribute("data-state", state); 16989 } 16990 }); 16991} 16992function getOwnerDocument(elementOrElements) { 16993 var _element$ownerDocumen; 16994 var _normalizeToArray = normalizeToArray(elementOrElements), element = _normalizeToArray[0]; 16995 return element != null && (_element$ownerDocumen = element.ownerDocument) != null && _element$ownerDocumen.body ? element.ownerDocument : document; 16996} 16997function isCursorOutsideInteractiveBorder(popperTreeData, event) { 16998 var clientX = event.clientX, clientY = event.clientY; 16999 return popperTreeData.every(function(_ref) { 17000 var popperRect = _ref.popperRect, popperState = _ref.popperState, props = _ref.props; 17001 var interactiveBorder = props.interactiveBorder; 17002 var basePlacement = getBasePlacement(popperState.placement); 17003 var offsetData = popperState.modifiersData.offset; 17004 if (!offsetData) { 17005 return true; 17006 } 17007 var topDistance = basePlacement === "bottom" ? offsetData.top.y : 0; 17008 var bottomDistance = basePlacement === "top" ? offsetData.bottom.y : 0; 17009 var leftDistance = basePlacement === "right" ? offsetData.left.x : 0; 17010 var rightDistance = basePlacement === "left" ? offsetData.right.x : 0; 17011 var exceedsTop = popperRect.top - clientY + topDistance > interactiveBorder; 17012 var exceedsBottom = clientY - popperRect.bottom - bottomDistance > interactiveBorder; 17013 var exceedsLeft = popperRect.left - clientX + leftDistance > interactiveBorder; 17014 var exceedsRight = clientX - popperRect.right - rightDistance > interactiveBorder; 17015 return exceedsTop || exceedsBottom || exceedsLeft || exceedsRight; 17016 }); 17017} 17018function updateTransitionEndListener(box, action, listener) { 17019 var method = action + "EventListener"; 17020 ["transitionend", "webkitTransitionEnd"].forEach(function(event) { 17021 box[method](event, listener); 17022 }); 17023} 17024function actualContains(parent, child) { 17025 var target = child; 17026 while (target) { 17027 var _target$getRootNode; 17028 if (parent.contains(target)) { 17029 return true; 17030 } 17031 target = target.getRootNode == null ? void 0 : (_target$getRootNode = target.getRootNode()) == null ? void 0 : _target$getRootNode.host; 17032 } 17033 return false; 17034} 17035var currentInput = { 17036 isTouch: false 17037}; 17038var lastMouseMoveTime = 0; 17039function onDocumentTouchStart() { 17040 if (currentInput.isTouch) { 17041 return; 17042 } 17043 currentInput.isTouch = true; 17044 if (window.performance) { 17045 document.addEventListener("mousemove", onDocumentMouseMove); 17046 } 17047} 17048function onDocumentMouseMove() { 17049 var now = performance.now(); 17050 if (now - lastMouseMoveTime < 20) { 17051 currentInput.isTouch = false; 17052 document.removeEventListener("mousemove", onDocumentMouseMove); 17053 } 17054 lastMouseMoveTime = now; 17055} 17056function onWindowBlur() { 17057 var activeElement = document.activeElement; 17058 if (isReferenceElement(activeElement)) { 17059 var instance = activeElement._tippy; 17060 if (activeElement.blur && !instance.state.isVisible) { 17061 activeElement.blur(); 17062 } 17063 } 17064} 17065function bindGlobalEventListeners() { 17066 document.addEventListener("touchstart", onDocumentTouchStart, TOUCH_OPTIONS); 17067 window.addEventListener("blur", onWindowBlur); 17068} 17069var isBrowser = typeof window !== "undefined" && typeof document !== "undefined"; 17070var isIE11 = isBrowser ? ( 17071 // @ts-ignore 17072 !!window.msCrypto 17073) : false; 17074var pluginProps = { 17075 animateFill: false, 17076 followCursor: false, 17077 inlinePositioning: false, 17078 sticky: false 17079}; 17080var renderProps = { 17081 allowHTML: false, 17082 animation: "fade", 17083 arrow: true, 17084 content: "", 17085 inertia: false, 17086 maxWidth: 350, 17087 role: "tooltip", 17088 theme: "", 17089 zIndex: 9999 17090}; 17091var defaultProps = Object.assign({ 17092 appendTo: TIPPY_DEFAULT_APPEND_TO, 17093 aria: { 17094 content: "auto", 17095 expanded: "auto" 17096 }, 17097 delay: 0, 17098 duration: [300, 250], 17099 getReferenceClientRect: null, 17100 hideOnClick: true, 17101 ignoreAttributes: false, 17102 interactive: false, 17103 interactiveBorder: 2, 17104 interactiveDebounce: 0, 17105 moveTransition: "", 17106 offset: [0, 10], 17107 onAfterUpdate: function onAfterUpdate() { 17108 }, 17109 onBeforeUpdate: function onBeforeUpdate() { 17110 }, 17111 onCreate: function onCreate() { 17112 }, 17113 onDestroy: function onDestroy() { 17114 }, 17115 onHidden: function onHidden() { 17116 }, 17117 onHide: function onHide() { 17118 }, 17119 onMount: function onMount() { 17120 }, 17121 onShow: function onShow() { 17122 }, 17123 onShown: function onShown() { 17124 }, 17125 onTrigger: function onTrigger() { 17126 }, 17127 onUntrigger: function onUntrigger() { 17128 }, 17129 onClickOutside: function onClickOutside() { 17130 }, 17131 placement: "top", 17132 plugins: [], 17133 popperOptions: {}, 17134 render: null, 17135 showOnCreate: false, 17136 touch: true, 17137 trigger: "mouseenter focus", 17138 triggerTarget: null 17139}, pluginProps, renderProps); 17140var defaultKeys = Object.keys(defaultProps); 17141var setDefaultProps = function setDefaultProps2(partialProps) { 17142 var keys2 = Object.keys(partialProps); 17143 keys2.forEach(function(key) { 17144 defaultProps[key] = partialProps[key]; 17145 }); 17146}; 17147function getExtendedPassedProps(passedProps) { 17148 var plugins = passedProps.plugins || []; 17149 var pluginProps2 = plugins.reduce(function(acc, plugin) { 17150 var name = plugin.name, defaultValue = plugin.defaultValue; 17151 if (name) { 17152 var _name; 17153 acc[name] = passedProps[name] !== void 0 ? passedProps[name] : (_name = defaultProps[name]) != null ? _name : defaultValue; 17154 } 17155 return acc; 17156 }, {}); 17157 return Object.assign({}, passedProps, pluginProps2); 17158} 17159function getDataAttributeProps(reference2, plugins) { 17160 var propKeys = plugins ? Object.keys(getExtendedPassedProps(Object.assign({}, defaultProps, { 17161 plugins 17162 }))) : defaultKeys; 17163 var props = propKeys.reduce(function(acc, key) { 17164 var valueAsString = (reference2.getAttribute("data-tippy-" + key) || "").trim(); 17165 if (!valueAsString) { 17166 return acc; 17167 } 17168 if (key === "content") { 17169 acc[key] = valueAsString; 17170 } else { 17171 try { 17172 acc[key] = JSON.parse(valueAsString); 17173 } catch (e) { 17174 acc[key] = valueAsString; 17175 } 17176 } 17177 return acc; 17178 }, {}); 17179 return props; 17180} 17181function evaluateProps(reference2, props) { 17182 var out = Object.assign({}, props, { 17183 content: invokeWithArgsOrReturn(props.content, [reference2]) 17184 }, props.ignoreAttributes ? {} : getDataAttributeProps(reference2, props.plugins)); 17185 out.aria = Object.assign({}, defaultProps.aria, out.aria); 17186 out.aria = { 17187 expanded: out.aria.expanded === "auto" ? props.interactive : out.aria.expanded, 17188 content: out.aria.content === "auto" ? props.interactive ? null : "describedby" : out.aria.content 17189 }; 17190 return out; 17191} 17192var innerHTML = function innerHTML2() { 17193 return "innerHTML"; 17194}; 17195function dangerouslySetInnerHTML(element, html) { 17196 element[innerHTML()] = html; 17197} 17198function createArrowElement(value) { 17199 var arrow2 = div(); 17200 if (value === true) { 17201 arrow2.className = ARROW_CLASS; 17202 } else { 17203 arrow2.className = SVG_ARROW_CLASS; 17204 if (isElement(value)) { 17205 arrow2.appendChild(value); 17206 } else { 17207 dangerouslySetInnerHTML(arrow2, value); 17208 } 17209 } 17210 return arrow2; 17211} 17212function setContent(content, props) { 17213 if (isElement(props.content)) { 17214 dangerouslySetInnerHTML(content, ""); 17215 content.appendChild(props.content); 17216 } else if (typeof props.content !== "function") { 17217 if (props.allowHTML) { 17218 dangerouslySetInnerHTML(content, props.content); 17219 } else { 17220 content.textContent = props.content; 17221 } 17222 } 17223} 17224function getChildren(popper2) { 17225 var box = popper2.firstElementChild; 17226 var boxChildren = arrayFrom(box.children); 17227 return { 17228 box, 17229 content: boxChildren.find(function(node) { 17230 return node.classList.contains(CONTENT_CLASS); 17231 }), 17232 arrow: boxChildren.find(function(node) { 17233 return node.classList.contains(ARROW_CLASS) || node.classList.contains(SVG_ARROW_CLASS); 17234 }), 17235 backdrop: boxChildren.find(function(node) { 17236 return node.classList.contains(BACKDROP_CLASS); 17237 }) 17238 }; 17239} 17240function render(instance) { 17241 var popper2 = div(); 17242 var box = div(); 17243 box.className = BOX_CLASS; 17244 box.setAttribute("data-state", "hidden"); 17245 box.setAttribute("tabindex", "-1"); 17246 var content = div(); 17247 content.className = CONTENT_CLASS; 17248 content.setAttribute("data-state", "hidden"); 17249 setContent(content, instance.props); 17250 popper2.appendChild(box); 17251 box.appendChild(content); 17252 onUpdate(instance.props, instance.props); 17253 function onUpdate(prevProps, nextProps) { 17254 var _getChildren = getChildren(popper2), box2 = _getChildren.box, content2 = _getChildren.content, arrow2 = _getChildren.arrow; 17255 if (nextProps.theme) { 17256 box2.setAttribute("data-theme", nextProps.theme); 17257 } else { 17258 box2.removeAttribute("data-theme"); 17259 } 17260 if (typeof nextProps.animation === "string") { 17261 box2.setAttribute("data-animation", nextProps.animation); 17262 } else { 17263 box2.removeAttribute("data-animation"); 17264 } 17265 if (nextProps.inertia) { 17266 box2.setAttribute("data-inertia", ""); 17267 } else { 17268 box2.removeAttribute("data-inertia"); 17269 } 17270 box2.style.maxWidth = typeof nextProps.maxWidth === "number" ? nextProps.maxWidth + "px" : nextProps.maxWidth; 17271 if (nextProps.role) { 17272 box2.setAttribute("role", nextProps.role); 17273 } else { 17274 box2.removeAttribute("role"); 17275 } 17276 if (prevProps.content !== nextProps.content || prevProps.allowHTML !== nextProps.allowHTML) { 17277 setContent(content2, instance.props); 17278 } 17279 if (nextProps.arrow) { 17280 if (!arrow2) { 17281 box2.appendChild(createArrowElement(nextProps.arrow)); 17282 } else if (prevProps.arrow !== nextProps.arrow) { 17283 box2.removeChild(arrow2); 17284 box2.appendChild(createArrowElement(nextProps.arrow)); 17285 } 17286 } else if (arrow2) { 17287 box2.removeChild(arrow2); 17288 } 17289 } 17290 return { 17291 popper: popper2, 17292 onUpdate 17293 }; 17294} 17295render.$$tippy = true; 17296var idCounter = 1; 17297var mouseMoveListeners = []; 17298var mountedInstances = []; 17299function createTippy(reference2, passedProps) { 17300 var props = evaluateProps(reference2, Object.assign({}, defaultProps, getExtendedPassedProps(removeUndefinedProps(passedProps)))); 17301 var showTimeout; 17302 var hideTimeout; 17303 var scheduleHideAnimationFrame; 17304 var isVisibleFromClick = false; 17305 var didHideDueToDocumentMouseDown = false; 17306 var didTouchMove = false; 17307 var ignoreOnFirstUpdate = false; 17308 var lastTriggerEvent; 17309 var currentTransitionEndListener; 17310 var onFirstUpdate; 17311 var listeners = []; 17312 var debouncedOnMouseMove = debounce(onMouseMove, props.interactiveDebounce); 17313 var currentTarget; 17314 var id = idCounter++; 17315 var popperInstance = null; 17316 var plugins = unique(props.plugins); 17317 var state = { 17318 // Is the instance currently enabled? 17319 isEnabled: true, 17320 // Is the tippy currently showing and not transitioning out? 17321 isVisible: false, 17322 // Has the instance been destroyed? 17323 isDestroyed: false, 17324 // Is the tippy currently mounted to the DOM? 17325 isMounted: false, 17326 // Has the tippy finished transitioning in? 17327 isShown: false 17328 }; 17329 var instance = { 17330 // properties 17331 id, 17332 reference: reference2, 17333 popper: div(), 17334 popperInstance, 17335 props, 17336 state, 17337 plugins, 17338 // methods 17339 clearDelayTimeouts, 17340 setProps, 17341 setContent: setContent2, 17342 show, 17343 hide: hide2, 17344 hideWithInteractivity, 17345 enable, 17346 disable, 17347 unmount, 17348 destroy 17349 }; 17350 if (!props.render) { 17351 return instance; 17352 } 17353 var _props$render = props.render(instance), popper2 = _props$render.popper, onUpdate = _props$render.onUpdate; 17354 popper2.setAttribute("data-tippy-root", ""); 17355 popper2.id = "tippy-" + instance.id; 17356 instance.popper = popper2; 17357 reference2._tippy = instance; 17358 popper2._tippy = instance; 17359 var pluginsHooks = plugins.map(function(plugin) { 17360 return plugin.fn(instance); 17361 }); 17362 var hasAriaExpanded = reference2.hasAttribute("aria-expanded"); 17363 addListeners(); 17364 handleAriaExpandedAttribute(); 17365 handleStyles(); 17366 invokeHook("onCreate", [instance]); 17367 if (props.showOnCreate) { 17368 scheduleShow(); 17369 } 17370 popper2.addEventListener("mouseenter", function() { 17371 if (instance.props.interactive && instance.state.isVisible) { 17372 instance.clearDelayTimeouts(); 17373 } 17374 }); 17375 popper2.addEventListener("mouseleave", function() { 17376 if (instance.props.interactive && instance.props.trigger.indexOf("mouseenter") >= 0) { 17377 getDocument().addEventListener("mousemove", debouncedOnMouseMove); 17378 } 17379 }); 17380 return instance; 17381 function getNormalizedTouchSettings() { 17382 var touch = instance.props.touch; 17383 return Array.isArray(touch) ? touch : [touch, 0]; 17384 } 17385 function getIsCustomTouchBehavior() { 17386 return getNormalizedTouchSettings()[0] === "hold"; 17387 } 17388 function getIsDefaultRenderFn() { 17389 var _instance$props$rende; 17390 return !!((_instance$props$rende = instance.props.render) != null && _instance$props$rende.$$tippy); 17391 } 17392 function getCurrentTarget() { 17393 return currentTarget || reference2; 17394 } 17395 function getDocument() { 17396 var parent = getCurrentTarget().parentNode; 17397 return parent ? getOwnerDocument(parent) : document; 17398 } 17399 function getDefaultTemplateChildren() { 17400 return getChildren(popper2); 17401 } 17402 function getDelay(isShow) { 17403 if (instance.state.isMounted && !instance.state.isVisible || currentInput.isTouch || lastTriggerEvent && lastTriggerEvent.type === "focus") { 17404 return 0; 17405 } 17406 return getValueAtIndexOrReturn(instance.props.delay, isShow ? 0 : 1, defaultProps.delay); 17407 } 17408 function handleStyles(fromHide) { 17409 if (fromHide === void 0) { 17410 fromHide = false; 17411 } 17412 popper2.style.pointerEvents = instance.props.interactive && !fromHide ? "" : "none"; 17413 popper2.style.zIndex = "" + instance.props.zIndex; 17414 } 17415 function invokeHook(hook, args, shouldInvokePropsHook) { 17416 if (shouldInvokePropsHook === void 0) { 17417 shouldInvokePropsHook = true; 17418 } 17419 pluginsHooks.forEach(function(pluginHooks) { 17420 if (pluginHooks[hook]) { 17421 pluginHooks[hook].apply(pluginHooks, args); 17422 } 17423 }); 17424 if (shouldInvokePropsHook) { 17425 var _instance$props; 17426 (_instance$props = instance.props)[hook].apply(_instance$props, args); 17427 } 17428 } 17429 function handleAriaContentAttribute() { 17430 var aria = instance.props.aria; 17431 if (!aria.content) { 17432 return; 17433 } 17434 var attr = "aria-" + aria.content; 17435 var id2 = popper2.id; 17436 var nodes = normalizeToArray(instance.props.triggerTarget || reference2); 17437 nodes.forEach(function(node) { 17438 var currentValue = node.getAttribute(attr); 17439 if (instance.state.isVisible) { 17440 node.setAttribute(attr, currentValue ? currentValue + " " + id2 : id2); 17441 } else { 17442 var nextValue = currentValue && currentValue.replace(id2, "").trim(); 17443 if (nextValue) { 17444 node.setAttribute(attr, nextValue); 17445 } else { 17446 node.removeAttribute(attr); 17447 } 17448 } 17449 }); 17450 } 17451 function handleAriaExpandedAttribute() { 17452 if (hasAriaExpanded || !instance.props.aria.expanded) { 17453 return; 17454 } 17455 var nodes = normalizeToArray(instance.props.triggerTarget || reference2); 17456 nodes.forEach(function(node) { 17457 if (instance.props.interactive) { 17458 node.setAttribute("aria-expanded", instance.state.isVisible && node === getCurrentTarget() ? "true" : "false"); 17459 } else { 17460 node.removeAttribute("aria-expanded"); 17461 } 17462 }); 17463 } 17464 function cleanupInteractiveMouseListeners() { 17465 getDocument().removeEventListener("mousemove", debouncedOnMouseMove); 17466 mouseMoveListeners = mouseMoveListeners.filter(function(listener) { 17467 return listener !== debouncedOnMouseMove; 17468 }); 17469 } 17470 function onDocumentPress(event) { 17471 if (currentInput.isTouch) { 17472 if (didTouchMove || event.type === "mousedown") { 17473 return; 17474 } 17475 } 17476 var actualTarget = event.composedPath && event.composedPath()[0] || event.target; 17477 if (instance.props.interactive && actualContains(popper2, actualTarget)) { 17478 return; 17479 } 17480 if (normalizeToArray(instance.props.triggerTarget || reference2).some(function(el) { 17481 return actualContains(el, actualTarget); 17482 })) { 17483 if (currentInput.isTouch) { 17484 return; 17485 } 17486 if (instance.state.isVisible && instance.props.trigger.indexOf("click") >= 0) { 17487 return; 17488 } 17489 } else { 17490 invokeHook("onClickOutside", [instance, event]); 17491 } 17492 if (instance.props.hideOnClick === true) { 17493 instance.clearDelayTimeouts(); 17494 instance.hide(); 17495 didHideDueToDocumentMouseDown = true; 17496 setTimeout(function() { 17497 didHideDueToDocumentMouseDown = false; 17498 }); 17499 if (!instance.state.isMounted) { 17500 removeDocumentPress(); 17501 } 17502 } 17503 } 17504 function onTouchMove() { 17505 didTouchMove = true; 17506 } 17507 function onTouchStart() { 17508 didTouchMove = false; 17509 } 17510 function addDocumentPress() { 17511 var doc2 = getDocument(); 17512 doc2.addEventListener("mousedown", onDocumentPress, true); 17513 doc2.addEventListener("touchend", onDocumentPress, TOUCH_OPTIONS); 17514 doc2.addEventListener("touchstart", onTouchStart, TOUCH_OPTIONS); 17515 doc2.addEventListener("touchmove", onTouchMove, TOUCH_OPTIONS); 17516 } 17517 function removeDocumentPress() { 17518 var doc2 = getDocument(); 17519 doc2.removeEventListener("mousedown", onDocumentPress, true); 17520 doc2.removeEventListener("touchend", onDocumentPress, TOUCH_OPTIONS); 17521 doc2.removeEventListener("touchstart", onTouchStart, TOUCH_OPTIONS); 17522 doc2.removeEventListener("touchmove", onTouchMove, TOUCH_OPTIONS); 17523 } 17524 function onTransitionedOut(duration, callback) { 17525 onTransitionEnd(duration, function() { 17526 if (!instance.state.isVisible && popper2.parentNode && popper2.parentNode.contains(popper2)) { 17527 callback(); 17528 } 17529 }); 17530 } 17531 function onTransitionedIn(duration, callback) { 17532 onTransitionEnd(duration, callback); 17533 } 17534 function onTransitionEnd(duration, callback) { 17535 var box = getDefaultTemplateChildren().box; 17536 function listener(event) { 17537 if (event.target === box) { 17538 updateTransitionEndListener(box, "remove", listener); 17539 callback(); 17540 } 17541 } 17542 if (duration === 0) { 17543 return callback(); 17544 } 17545 updateTransitionEndListener(box, "remove", currentTransitionEndListener); 17546 updateTransitionEndListener(box, "add", listener); 17547 currentTransitionEndListener = listener; 17548 } 17549 function on(eventType, handler, options) { 17550 if (options === void 0) { 17551 options = false; 17552 } 17553 var nodes = normalizeToArray(instance.props.triggerTarget || reference2); 17554 nodes.forEach(function(node) { 17555 node.addEventListener(eventType, handler, options); 17556 listeners.push({ 17557 node, 17558 eventType, 17559 handler, 17560 options 17561 }); 17562 }); 17563 } 17564 function addListeners() { 17565 if (getIsCustomTouchBehavior()) { 17566 on("touchstart", onTrigger2, { 17567 passive: true 17568 }); 17569 on("touchend", onMouseLeave, { 17570 passive: true 17571 }); 17572 } 17573 splitBySpaces(instance.props.trigger).forEach(function(eventType) { 17574 if (eventType === "manual") { 17575 return; 17576 } 17577 on(eventType, onTrigger2); 17578 switch (eventType) { 17579 case "mouseenter": 17580 on("mouseleave", onMouseLeave); 17581 break; 17582 case "focus": 17583 on(isIE11 ? "focusout" : "blur", onBlurOrFocusOut); 17584 break; 17585 case "focusin": 17586 on("focusout", onBlurOrFocusOut); 17587 break; 17588 } 17589 }); 17590 } 17591 function removeListeners() {
vendor: 4,135 bytes, lines 17592-17692
17592 listeners.forEach(function(_ref) { 17593 var node = _ref.node, eventType = _ref.eventType, handler = _ref.handler, options = _ref.options; 17594 node.removeEventListener(eventType, handler, options); 17595 }); 17596 listeners = []; 17597 } 17598 function onTrigger2(event) { 17599 var _lastTriggerEvent; 17600 var shouldScheduleClickHide = false; 17601 if (!instance.state.isEnabled || isEventListenerStopped(event) || didHideDueToDocumentMouseDown) { 17602 return; 17603 } 17604 var wasFocused = ((_lastTriggerEvent = lastTriggerEvent) == null ? void 0 : _lastTriggerEvent.type) === "focus"; 17605 lastTriggerEvent = event; 17606 currentTarget = event.currentTarget; 17607 handleAriaExpandedAttribute(); 17608 if (!instance.state.isVisible && isMouseEvent(event)) { 17609 mouseMoveListeners.forEach(function(listener) { 17610 return listener(event); 17611 }); 17612 } 17613 if (event.type === "click" && (instance.props.trigger.indexOf("mouseenter") < 0 || isVisibleFromClick) && instance.props.hideOnClick !== false && instance.state.isVisible) { 17614 shouldScheduleClickHide = true; 17615 } else { 17616 scheduleShow(event); 17617 } 17618 if (event.type === "click") { 17619 isVisibleFromClick = !shouldScheduleClickHide; 17620 } 17621 if (shouldScheduleClickHide && !wasFocused) { 17622 scheduleHide(event); 17623 } 17624 } 17625 function onMouseMove(event) { 17626 var target = event.target; 17627 var isCursorOverReferenceOrPopper = getCurrentTarget().contains(target) || popper2.contains(target); 17628 if (event.type === "mousemove" && isCursorOverReferenceOrPopper) { 17629 return; 17630 } 17631 var popperTreeData = getNestedPopperTree().concat(popper2).map(function(popper3) { 17632 var _instance$popperInsta; 17633 var instance2 = popper3._tippy; 17634 var state2 = (_instance$popperInsta = instance2.popperInstance) == null ? void 0 : _instance$popperInsta.state; 17635 if (state2) { 17636 return { 17637 popperRect: popper3.getBoundingClientRect(), 17638 popperState: state2, 17639 props 17640 }; 17641 } 17642 return null; 17643 }).filter(Boolean); 17644 if (isCursorOutsideInteractiveBorder(popperTreeData, event)) { 17645 cleanupInteractiveMouseListeners(); 17646 scheduleHide(event); 17647 } 17648 } 17649 function onMouseLeave(event) { 17650 var shouldBail = isEventListenerStopped(event) || instance.props.trigger.indexOf("click") >= 0 && isVisibleFromClick; 17651 if (shouldBail) { 17652 return; 17653 } 17654 if (instance.props.interactive) { 17655 instance.hideWithInteractivity(event); 17656 return; 17657 } 17658 scheduleHide(event); 17659 } 17660 function onBlurOrFocusOut(event) { 17661 if (instance.props.trigger.indexOf("focusin") < 0 && event.target !== getCurrentTarget()) { 17662 return; 17663 } 17664 if (instance.props.interactive && event.relatedTarget && popper2.contains(event.relatedTarget)) { 17665 return; 17666 } 17667 scheduleHide(event); 17668 } 17669 function isEventListenerStopped(event) { 17670 return currentInput.isTouch ? getIsCustomTouchBehavior() !== event.type.indexOf("touch") >= 0 : false; 17671 } 17672 function createPopperInstance() { 17673 destroyPopperInstance(); 17674 var _instance$props2 = instance.props, popperOptions = _instance$props2.popperOptions, placement = _instance$props2.placement, offset2 = _instance$props2.offset, getReferenceClientRect = _instance$props2.getReferenceClientRect, moveTransition = _instance$props2.moveTransition; 17675 var arrow2 = getIsDefaultRenderFn() ? getChildren(popper2).arrow : null; 17676 var computedReference = getReferenceClientRect ? { 17677 getBoundingClientRect: getReferenceClientRect, 17678 contextElement: getReferenceClientRect.contextElement || getCurrentTarget() 17679 } : reference2; 17680 var tippyModifier = { 17681 name: "$$tippy", 17682 enabled: true, 17683 phase: "beforeWrite", 17684 requires: ["computeStyles"], 17685 fn: function fn2(_ref2) { 17686 var state2 = _ref2.state; 17687 if (getIsDefaultRenderFn()) { 17688 var _getDefaultTemplateCh = getDefaultTemplateChildren(), box = _getDefaultTemplateCh.box; 17689 ["placement", "reference-hidden", "escaped"].forEach(function(attr) { 17690 if (attr === "placement") { 17691 box.setAttribute("data-placement", state2.placement); 17692 } else {
vendor: 4,727 bytes, lines 17693-17853
17693 if (state2.attributes.popper["data-popper-" + attr]) { 17694 box.setAttribute("data-" + attr, ""); 17695 } else { 17696 box.removeAttribute("data-" + attr); 17697 } 17698 } 17699 }); 17700 state2.attributes.popper = {}; 17701 } 17702 } 17703 }; 17704 var modifiers2 = [{ 17705 name: "offset", 17706 options: { 17707 offset: offset2 17708 } 17709 }, { 17710 name: "preventOverflow", 17711 options: { 17712 padding: { 17713 top: 2, 17714 bottom: 2, 17715 left: 5, 17716 right: 5 17717 } 17718 } 17719 }, { 17720 name: "flip", 17721 options: { 17722 padding: 5 17723 } 17724 }, { 17725 name: "computeStyles", 17726 options: { 17727 adaptive: !moveTransition 17728 } 17729 }, tippyModifier]; 17730 if (getIsDefaultRenderFn() && arrow2) { 17731 modifiers2.push({ 17732 name: "arrow", 17733 options: { 17734 element: arrow2, 17735 padding: 3 17736 } 17737 }); 17738 } 17739 modifiers2.push.apply(modifiers2, (popperOptions == null ? void 0 : popperOptions.modifiers) || []); 17740 instance.popperInstance = createPopper(computedReference, popper2, Object.assign({}, popperOptions, { 17741 placement, 17742 onFirstUpdate, 17743 modifiers: modifiers2 17744 })); 17745 } 17746 function destroyPopperInstance() { 17747 if (instance.popperInstance) { 17748 instance.popperInstance.destroy(); 17749 instance.popperInstance = null; 17750 } 17751 } 17752 function mount() { 17753 var appendTo = instance.props.appendTo; 17754 var parentNode2; 17755 var node = getCurrentTarget(); 17756 if (instance.props.interactive && appendTo === TIPPY_DEFAULT_APPEND_TO || appendTo === "parent") { 17757 parentNode2 = node.parentNode; 17758 } else { 17759 parentNode2 = invokeWithArgsOrReturn(appendTo, [node]); 17760 } 17761 if (!parentNode2.contains(popper2)) { 17762 parentNode2.appendChild(popper2); 17763 } 17764 instance.state.isMounted = true; 17765 createPopperInstance(); 17766 } 17767 function getNestedPopperTree() { 17768 return arrayFrom(popper2.querySelectorAll("[data-tippy-root]")); 17769 } 17770 function scheduleShow(event) { 17771 instance.clearDelayTimeouts(); 17772 if (event) { 17773 invokeHook("onTrigger", [instance, event]); 17774 } 17775 addDocumentPress(); 17776 var delay = getDelay(true); 17777 var _getNormalizedTouchSe = getNormalizedTouchSettings(), touchValue = _getNormalizedTouchSe[0], touchDelay = _getNormalizedTouchSe[1]; 17778 if (currentInput.isTouch && touchValue === "hold" && touchDelay) { 17779 delay = touchDelay; 17780 } 17781 if (delay) { 17782 showTimeout = setTimeout(function() { 17783 instance.show(); 17784 }, delay); 17785 } else { 17786 instance.show(); 17787 } 17788 } 17789 function scheduleHide(event) { 17790 instance.clearDelayTimeouts(); 17791 invokeHook("onUntrigger", [instance, event]); 17792 if (!instance.state.isVisible) { 17793 removeDocumentPress(); 17794 return; 17795 } 17796 if (instance.props.trigger.indexOf("mouseenter") >= 0 && instance.props.trigger.indexOf("click") >= 0 && ["mouseleave", "mousemove"].indexOf(event.type) >= 0 && isVisibleFromClick) { 17797 return; 17798 } 17799 var delay = getDelay(false); 17800 if (delay) { 17801 hideTimeout = setTimeout(function() { 17802 if (instance.state.isVisible) { 17803 instance.hide(); 17804 } 17805 }, delay); 17806 } else { 17807 scheduleHideAnimationFrame = requestAnimationFrame(function() { 17808 instance.hide(); 17809 }); 17810 } 17811 } 17812 function enable() { 17813 instance.state.isEnabled = true; 17814 } 17815 function disable() { 17816 instance.hide(); 17817 instance.state.isEnabled = false; 17818 } 17819 function clearDelayTimeouts() { 17820 clearTimeout(showTimeout); 17821 clearTimeout(hideTimeout); 17822 cancelAnimationFrame(scheduleHideAnimationFrame); 17823 } 17824 function setProps(partialProps) { 17825 if (instance.state.isDestroyed) { 17826 return; 17827 } 17828 invokeHook("onBeforeUpdate", [instance, partialProps]); 17829 removeListeners(); 17830 var prevProps = instance.props; 17831 var nextProps = evaluateProps(reference2, Object.assign({}, prevProps, removeUndefinedProps(partialProps), { 17832 ignoreAttributes: true 17833 })); 17834 instance.props = nextProps; 17835 addListeners(); 17836 if (prevProps.interactiveDebounce !== nextProps.interactiveDebounce) { 17837 cleanupInteractiveMouseListeners(); 17838 debouncedOnMouseMove = debounce(onMouseMove, nextProps.interactiveDebounce); 17839 } 17840 if (prevProps.triggerTarget && !nextProps.triggerTarget) { 17841 normalizeToArray(prevProps.triggerTarget).forEach(function(node) { 17842 node.removeAttribute("aria-expanded"); 17843 }); 17844 } else if (nextProps.triggerTarget) { 17845 reference2.removeAttribute("aria-expanded"); 17846 } 17847 handleAriaExpandedAttribute(); 17848 handleStyles(); 17849 if (onUpdate) { 17850 onUpdate(prevProps, nextProps); 17851 } 17852 if (instance.popperInstance) { 17853 createPopperInstance();
vendor: 4,324 bytes, lines 17854-17972
17854 getNestedPopperTree().forEach(function(nestedPopper) { 17855 requestAnimationFrame(nestedPopper._tippy.popperInstance.forceUpdate); 17856 }); 17857 } 17858 invokeHook("onAfterUpdate", [instance, partialProps]); 17859 } 17860 function setContent2(content) { 17861 instance.setProps({ 17862 content 17863 }); 17864 } 17865 function show() { 17866 var isAlreadyVisible = instance.state.isVisible; 17867 var isDestroyed = instance.state.isDestroyed; 17868 var isDisabled = !instance.state.isEnabled; 17869 var isTouchAndTouchDisabled = currentInput.isTouch && !instance.props.touch; 17870 var duration = getValueAtIndexOrReturn(instance.props.duration, 0, defaultProps.duration); 17871 if (isAlreadyVisible || isDestroyed || isDisabled || isTouchAndTouchDisabled) { 17872 return; 17873 } 17874 if (getCurrentTarget().hasAttribute("disabled")) { 17875 return; 17876 } 17877 invokeHook("onShow", [instance], false); 17878 if (instance.props.onShow(instance) === false) { 17879 return; 17880 } 17881 instance.state.isVisible = true; 17882 if (getIsDefaultRenderFn()) { 17883 popper2.style.visibility = "visible"; 17884 } 17885 handleStyles(); 17886 addDocumentPress(); 17887 if (!instance.state.isMounted) { 17888 popper2.style.transition = "none"; 17889 } 17890 if (getIsDefaultRenderFn()) { 17891 var _getDefaultTemplateCh2 = getDefaultTemplateChildren(), box = _getDefaultTemplateCh2.box, content = _getDefaultTemplateCh2.content; 17892 setTransitionDuration([box, content], 0); 17893 } 17894 onFirstUpdate = function onFirstUpdate2() { 17895 var _instance$popperInsta2; 17896 if (!instance.state.isVisible || ignoreOnFirstUpdate) { 17897 return; 17898 } 17899 ignoreOnFirstUpdate = true; 17900 void popper2.offsetHeight; 17901 popper2.style.transition = instance.props.moveTransition; 17902 if (getIsDefaultRenderFn() && instance.props.animation) { 17903 var _getDefaultTemplateCh3 = getDefaultTemplateChildren(), _box = _getDefaultTemplateCh3.box, _content = _getDefaultTemplateCh3.content; 17904 setTransitionDuration([_box, _content], duration); 17905 setVisibilityState([_box, _content], "visible"); 17906 } 17907 handleAriaContentAttribute(); 17908 handleAriaExpandedAttribute(); 17909 pushIfUnique(mountedInstances, instance); 17910 (_instance$popperInsta2 = instance.popperInstance) == null ? void 0 : _instance$popperInsta2.forceUpdate(); 17911 invokeHook("onMount", [instance]); 17912 if (instance.props.animation && getIsDefaultRenderFn()) { 17913 onTransitionedIn(duration, function() { 17914 instance.state.isShown = true; 17915 invokeHook("onShown", [instance]); 17916 }); 17917 } 17918 }; 17919 mount(); 17920 } 17921 function hide2() { 17922 var isAlreadyHidden = !instance.state.isVisible; 17923 var isDestroyed = instance.state.isDestroyed; 17924 var isDisabled = !instance.state.isEnabled; 17925 var duration = getValueAtIndexOrReturn(instance.props.duration, 1, defaultProps.duration); 17926 if (isAlreadyHidden || isDestroyed || isDisabled) { 17927 return; 17928 } 17929 invokeHook("onHide", [instance], false); 17930 if (instance.props.onHide(instance) === false) { 17931 return; 17932 } 17933 instance.state.isVisible = false; 17934 instance.state.isShown = false; 17935 ignoreOnFirstUpdate = false; 17936 isVisibleFromClick = false; 17937 if (getIsDefaultRenderFn()) { 17938 popper2.style.visibility = "hidden"; 17939 } 17940 cleanupInteractiveMouseListeners(); 17941 removeDocumentPress(); 17942 handleStyles(true); 17943 if (getIsDefaultRenderFn()) { 17944 var _getDefaultTemplateCh4 = getDefaultTemplateChildren(), box = _getDefaultTemplateCh4.box, content = _getDefaultTemplateCh4.content; 17945 if (instance.props.animation) { 17946 setTransitionDuration([box, content], duration); 17947 setVisibilityState([box, content], "hidden"); 17948 } 17949 } 17950 handleAriaContentAttribute(); 17951 handleAriaExpandedAttribute(); 17952 if (instance.props.animation) { 17953 if (getIsDefaultRenderFn()) { 17954 onTransitionedOut(duration, instance.unmount); 17955 } 17956 } else { 17957 instance.unmount(); 17958 } 17959 } 17960 function hideWithInteractivity(event) { 17961 getDocument().addEventListener("mousemove", debouncedOnMouseMove); 17962 pushIfUnique(mouseMoveListeners, debouncedOnMouseMove); 17963 debouncedOnMouseMove(event); 17964 } 17965 function unmount() { 17966 if (instance.state.isVisible) { 17967 instance.hide(); 17968 } 17969 if (!instance.state.isMounted) { 17970 return; 17971 } 17972 destroyPopperInstance();
17973 getNestedPopperTree().forEach(function(nestedPopper) { 17974 nestedPopper._tippy.unmount(); 17975 }); 17976 if (popper2.parentNode) { 17977 popper2.parentNode.removeChild(popper2); 17978 } 17979 mountedInstances = mountedInstances.filter(function(i) { 17980 return i !== instance; 17981 }); 17982 instance.state.isMounted = false; 17983 invokeHook("onHidden", [instance]); 17984 } 17985 function destroy() { 17986 if (instance.state.isDestroyed) { 17987 return; 17988 } 17989 instance.clearDelayTimeouts(); 17990 instance.unmount(); 17991 removeListeners(); 17992 delete reference2._tippy; 17993 instance.state.isDestroyed = true; 17994 invokeHook("onDestroy", [instance]); 17995 } 17996} 17997function tippy(targets, optionalProps) { 17998 if (optionalProps === void 0) { 17999 optionalProps = {}; 18000 } 18001 var plugins = defaultProps.plugins.concat(optionalProps.plugins || []); 18002 bindGlobalEventListeners(); 18003 var passedProps = Object.assign({}, optionalProps, { 18004 plugins 18005 }); 18006 var elements = getArrayOfElements(targets); 18007 var instances = elements.reduce(function(acc, reference2) { 18008 var instance = reference2 && createTippy(reference2, passedProps); 18009 if (instance) { 18010 acc.push(instance); 18011 } 18012 return acc; 18013 }, []); 18014 return isElement(targets) ? instances[0] : instances; 18015} 18016tippy.defaultProps = defaultProps; 18017tippy.setDefaultProps = setDefaultProps; 18018tippy.currentInput = currentInput; 18019Object.assign({}, applyStyles$1, { 18020 effect: function effect2(_ref) { 18021 var state = _ref.state; 18022 var initialStyles = { 18023 popper: { 18024 position: state.options.strategy, 18025 left: "0", 18026 top: "0", 18027 margin: "0" 18028 }, 18029 arrow: { 18030 position: "absolute" 18031 }, 18032 reference: {} 18033 }; 18034 Object.assign(state.elements.popper.style, initialStyles.popper); 18035 state.styles = initialStyles; 18036 if (state.elements.arrow) { 18037 Object.assign(state.elements.arrow.style, initialStyles.arrow); 18038 } 18039 } 18040}); 18041tippy.setDefaultProps({ 18042 render 18043}); 18044class BubbleMenuView { 18045 constructor({ editor, element, view, tippyOptions = {}, updateDelay = 250, shouldShow }) { 18046 this.preventHide = false;
18047 this.shouldShow = ({ view: view2, state, from: from2, to }) => { 18048 const { doc: doc2, selection } = state; 18049 const { empty: empty2 } = selection; 18050 const isEmptyTextBlock = !doc2.textBetween(from2, to).length && isTextSelection(state.selection); 18051 const isChildOfMenu = this.element.contains(document.activeElement); 18052 const hasEditorFocus = view2.hasFocus() || isChildOfMenu; 18053 if (!hasEditorFocus || empty2 || isEmptyTextBlock || !this.editor.isEditable) { 18054 return false; 18055 } 18056 return true; 18057 }; 18058 this.mousedownHandler = () => { 18059 this.preventHide = true; 18060 }; 18061 this.dragstartHandler = () => { 18062 this.hide(); 18063 }; 18064 this.focusHandler = () => { 18065 setTimeout(() => this.update(this.editor.view)); 18066 }; 18067 this.blurHandler = ({ event }) => { 18068 var _a; 18069 if (this.preventHide) { 18070 this.preventHide = false; 18071 return; 18072 } 18073 if ((event === null || event === void 0 ? void 0 : event.relatedTarget) && ((_a = this.element.parentNode) === null || _a === void 0 ? void 0 : _a.contains(event.relatedTarget))) { 18074 return; 18075 } 18076 this.hide(); 18077 }; 18078 this.tippyBlurHandler = (event) => { 18079 this.blurHandler({ event }); 18080 }; 18081 this.handleDebouncedUpdate = (view2, oldState) => { 18082 const selectionChanged = !(oldState === null || oldState === void 0 ? void 0 : oldState.selection.eq(view2.state.selection)); 18083 const docChanged = !(oldState === null || oldState === void 0 ? void 0 : oldState.doc.eq(view2.state.doc)); 18084 if (!selectionChanged && !docChanged) { 18085 return; 18086 } 18087 if (this.updateDebounceTimer) { 18088 clearTimeout(this.updateDebounceTimer); 18089 } 18090 this.updateDebounceTimer = window.setTimeout(() => { 18091 this.updateHandler(view2, selectionChanged, docChanged, oldState); 18092 }, this.updateDelay); 18093 }; 18094 this.updateHandler = (view2, selectionChanged, docChanged, oldState) => { 18095 var _a, _b, _c; 18096 const { state, composing } = view2; 18097 const { selection } = state; 18098 const isSame = !selectionChanged && !docChanged; 18099 if (composing || isSame) { 18100 return; 18101 } 18102 this.createTooltip(); 18103 const { ranges } = selection; 18104 const from2 = Math.min(...ranges.map((range) => range.$from.pos)); 18105 const to = Math.max(...ranges.map((range) => range.$to.pos)); 18106 const shouldShow2 = (_a = this.shouldShow) === null || _a === void 0 ? void 0 : _a.call(this, { 18107 editor: this.editor, 18108 view: view2, 18109 state, 18110 oldState, 18111 from: from2, 18112 to 18113 }); 18114 if (!shouldShow2) { 18115 this.hide(); 18116 return; 18117 } 18118 (_b = this.tippy) === null || _b === void 0 ? void 0 : _b.setProps({ 18119 getReferenceClientRect: ((_c = this.tippyOptions) === null || _c === void 0 ? void 0 : _c.getReferenceClientRect) || (() => { 18120 if (isNodeSelection(state.selection)) { 18121 let node = view2.nodeDOM(from2); 18122 const nodeViewWrapper = node.dataset.nodeViewWrapper ? node : node.querySelector("[data-node-view-wrapper]"); 18123 if (nodeViewWrapper) { 18124 node = nodeViewWrapper.firstChild; 18125 } 18126 if (node) { 18127 return node.getBoundingClientRect(); 18128 } 18129 } 18130 return posToDOMRect(view2, from2, to); 18131 }) 18132 }); 18133 this.show(); 18134 }; 18135 this.editor = editor; 18136 this.element = element; 18137 this.view = view; 18138 this.updateDelay = updateDelay; 18139 if (shouldShow) { 18140 this.shouldShow = shouldShow; 18141 } 18142 this.element.addEventListener("mousedown", this.mousedownHandler, { capture: true }); 18143 this.view.dom.addEventListener("dragstart", this.dragstartHandler); 18144 this.editor.on("focus", this.focusHandler); 18145 this.editor.on("blur", this.blurHandler); 18146 this.tippyOptions = tippyOptions; 18147 this.element.remove(); 18148 this.element.style.visibility = "visible"; 18149 } 18150 createTooltip() { 18151 const { element: editorElement } = this.editor.options; 18152 const editorIsAttached = !!editorElement.parentElement; 18153 if (this.tippy || !editorIsAttached) { 18154 return; 18155 } 18156 this.tippy = tippy(editorElement, { 18157 duration: 0, 18158 getReferenceClientRect: null, 18159 content: this.element, 18160 interactive: true, 18161 trigger: "manual", 18162 placement: "top", 18163 hideOnClick: "toggle", 18164 ...this.tippyOptions 18165 }); 18166 if (this.tippy.popper.firstChild) { 18167 this.tippy.popper.firstChild.addEventListener("blur", this.tippyBlurHandler); 18168 } 18169 } 18170 update(view, oldState) { 18171 const { state } = view; 18172 const hasValidSelection = state.selection.$from.pos !== state.selection.$to.pos; 18173 if (this.updateDelay > 0 && hasValidSelection) { 18174 this.handleDebouncedUpdate(view, oldState); 18175 return; 18176 } 18177 const selectionChanged = !(oldState === null || oldState === void 0 ? void 0 : oldState.selection.eq(view.state.selection)); 18178 const docChanged = !(oldState === null || oldState === void 0 ? void 0 : oldState.doc.eq(view.state.doc)); 18179 this.updateHandler(view, selectionChanged, docChanged, oldState); 18180 } 18181 show() { 18182 var _a; 18183 (_a = this.tippy) === null || _a === void 0 ? void 0 : _a.show(); 18184 } 18185 hide() { 18186 var _a; 18187 (_a = this.tippy) === null || _a === void 0 ? void 0 : _a.hide(); 18188 } 18189 destroy() { 18190 var _a, _b; 18191 if ((_a = this.tippy) === null || _a === void 0 ? void 0 : _a.popper.firstChild) { 18192 this.tippy.popper.firstChild.removeEventListener("blur", this.tippyBlurHandler); 18193 } 18194 (_b = this.tippy) === null || _b === void 0 ? void 0 : _b.destroy(); 18195 this.element.removeEventListener("mousedown", this.mousedownHandler, { capture: true }); 18196 this.view.dom.removeEventListener("dragstart", this.dragstartHandler); 18197 this.editor.off("focus", this.focusHandler); 18198 this.editor.off("blur", this.blurHandler); 18199 } 18200} 18201const BubbleMenuPlugin = (options) => { 18202 return new Plugin({
18203 key: typeof options.pluginKey === "string" ? new PluginKey(options.pluginKey) : options.pluginKey, 18204 view: (view) => new BubbleMenuView({ view, ...options }) 18205 }); 18206}; 18207Extension.create({ 18208 name: "bubbleMenu", 18209 addOptions() { 18210 return { 18211 element: null, 18212 tippyOptions: {}, 18213 pluginKey: "bubbleMenu", 18214 updateDelay: void 0, 18215 shouldShow: null 18216 }; 18217 }, 18218 addProseMirrorPlugins() { 18219 if (!this.options.element) { 18220 return []; 18221 } 18222 return [ 18223 BubbleMenuPlugin({ 18224 pluginKey: this.options.pluginKey, 18225 editor: this.editor, 18226 element: this.options.element, 18227 tippyOptions: this.options.tippyOptions, 18228 updateDelay: this.options.updateDelay, 18229 shouldShow: this.options.shouldShow 18230 }) 18231 ]; 18232 } 18233}); 18234class FloatingMenuView { 18235 constructor({ editor, element, view, tippyOptions = {}, shouldShow }) { 18236 this.preventHide = false; 18237 this.shouldShow = ({ view: view2, state }) => { 18238 const { selection } = state; 18239 const { $anchor, empty: empty2 } = selection; 18240 const isRootDepth = $anchor.depth === 1; 18241 const isEmptyTextBlock = $anchor.parent.isTextblock && !$anchor.parent.type.spec.code && !$anchor.parent.textContent; 18242 if (!view2.hasFocus() || !empty2 || !isRootDepth || !isEmptyTextBlock || !this.editor.isEditable) { 18243 return false; 18244 } 18245 return true; 18246 }; 18247 this.mousedownHandler = () => { 18248 this.preventHide = true; 18249 }; 18250 this.focusHandler = () => { 18251 setTimeout(() => this.update(this.editor.view)); 18252 }; 18253 this.blurHandler = ({ event }) => { 18254 var _a; 18255 if (this.preventHide) { 18256 this.preventHide = false;
18257 return; 18258 } 18259 if ((event === null || event === void 0 ? void 0 : event.relatedTarget) && ((_a = this.element.parentNode) === null || _a === void 0 ? void 0 : _a.contains(event.relatedTarget))) { 18260 return; 18261 } 18262 this.hide(); 18263 }; 18264 this.tippyBlurHandler = (event) => { 18265 this.blurHandler({ event }); 18266 }; 18267 this.editor = editor; 18268 this.element = element; 18269 this.view = view; 18270 if (shouldShow) { 18271 this.shouldShow = shouldShow; 18272 } 18273 this.element.addEventListener("mousedown", this.mousedownHandler, { capture: true }); 18274 this.editor.on("focus", this.focusHandler); 18275 this.editor.on("blur", this.blurHandler); 18276 this.tippyOptions = tippyOptions; 18277 this.element.remove(); 18278 this.element.style.visibility = "visible"; 18279 } 18280 createTooltip() { 18281 const { element: editorElement } = this.editor.options; 18282 const editorIsAttached = !!editorElement.parentElement; 18283 if (this.tippy || !editorIsAttached) { 18284 return; 18285 } 18286 this.tippy = tippy(editorElement, { 18287 duration: 0, 18288 getReferenceClientRect: null, 18289 content: this.element, 18290 interactive: true, 18291 trigger: "manual", 18292 placement: "right", 18293 hideOnClick: "toggle", 18294 ...this.tippyOptions 18295 }); 18296 if (this.tippy.popper.firstChild) { 18297 this.tippy.popper.firstChild.addEventListener("blur", this.tippyBlurHandler); 18298 } 18299 } 18300 update(view, oldState) { 18301 var _a, _b, _c; 18302 const { state } = view; 18303 const { doc: doc2, selection } = state; 18304 const { from: from2, to } = selection; 18305 const isSame = oldState && oldState.doc.eq(doc2) && oldState.selection.eq(selection); 18306 if (isSame) { 18307 return; 18308 } 18309 this.createTooltip(); 18310 const shouldShow = (_a = this.shouldShow) === null || _a === void 0 ? void 0 : _a.call(this, { 18311 editor: this.editor, 18312 view, 18313 state, 18314 oldState 18315 }); 18316 if (!shouldShow) { 18317 this.hide(); 18318 return; 18319 } 18320 (_b = this.tippy) === null || _b === void 0 ? void 0 : _b.setProps({ 18321 getReferenceClientRect: ((_c = this.tippyOptions) === null || _c === void 0 ? void 0 : _c.getReferenceClientRect) || (() => posToDOMRect(view, from2, to)) 18322 }); 18323 this.show(); 18324 } 18325 show() { 18326 var _a; 18327 (_a = this.tippy) === null || _a === void 0 ? void 0 : _a.show(); 18328 } 18329 hide() { 18330 var _a; 18331 (_a = this.tippy) === null || _a === void 0 ? void 0 : _a.hide(); 18332 } 18333 destroy() { 18334 var _a, _b; 18335 if ((_a = this.tippy) === null || _a === void 0 ? void 0 : _a.popper.firstChild) { 18336 this.tippy.popper.firstChild.removeEventListener("blur", this.tippyBlurHandler); 18337 } 18338 (_b = this.tippy) === null || _b === void 0 ? void 0 : _b.destroy(); 18339 this.element.removeEventListener("mousedown", this.mousedownHandler, { capture: true }); 18340 this.editor.off("focus", this.focusHandler); 18341 this.editor.off("blur", this.blurHandler); 18342 } 18343} 18344const FloatingMenuPlugin = (options) => { 18345 return new Plugin({ 18346 key: typeof options.pluginKey === "string" ? new PluginKey(options.pluginKey) : options.pluginKey, 18347 view: (view) => new FloatingMenuView({ view, ...options }) 18348 }); 18349}; 18350Extension.create({ 18351 name: "floatingMenu", 18352 addOptions() { 18353 return { 18354 element: null, 18355 tippyOptions: {}, 18356 pluginKey: "floatingMenu", 18357 shouldShow: null 18358 }; 18359 }, 18360 addProseMirrorPlugins() { 18361 if (!this.options.element) { 18362 return []; 18363 } 18364 return [ 18365 FloatingMenuPlugin({ 18366 pluginKey: this.options.pluginKey, 18367 editor: this.editor, 18368 element: this.options.element, 18369 tippyOptions: this.options.tippyOptions, 18370 shouldShow: this.options.shouldShow 18371 }) 18372 ]; 18373 } 18374}); 18375defineComponent({ 18376 name: "BubbleMenu", 18377 props: { 18378 pluginKey: { 18379 type: [String, Object], 18380 default: "bubbleMenu" 18381 }, 18382 editor: { 18383 type: Object, 18384 required: true 18385 }, 18386 updateDelay: { 18387 type: Number, 18388 default: void 0 18389 }, 18390 tippyOptions: { 18391 type: Object, 18392 default: () => ({}) 18393 }, 18394 shouldShow: { 18395 type: Function, 18396 default: null 18397 } 18398 }, 18399 setup(props, { slots }) { 18400 const root = ref(null); 18401 onMounted(() => { 18402 const { updateDelay, editor, pluginKey, shouldShow, tippyOptions } = props; 18403 editor.registerPlugin(BubbleMenuPlugin({ 18404 updateDelay, 18405 editor, 18406 element: root.value, 18407 pluginKey, 18408 shouldShow, 18409 tippyOptions 18410 })); 18411 }); 18412 onBeforeUnmount(() => { 18413 const { pluginKey, editor } = props; 18414 editor.unregisterPlugin(pluginKey); 18415 }); 18416 return () => { 18417 var _a; 18418 return h("div", { ref: root }, (_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots)); 18419 }; 18420 } 18421}); 18422function useDebouncedRef(value) { 18423 return customRef((track, trigger) => { 18424 return { 18425 get() { 18426 track(); 18427 return value; 18428 }, 18429 set(newValue) { 18430 value = newValue; 18431 requestAnimationFrame(() => { 18432 requestAnimationFrame(() => { 18433 trigger(); 18434 }); 18435 }); 18436 } 18437 }; 18438 }); 18439}
18440class Editor2 extends Editor$1 { 18441 constructor(options = {}) { 18442 super(options); 18443 this.vueRenderers = reactive(/* @__PURE__ */ new Map()); 18444 this.contentComponent = null; 18445 this.reactiveState = useDebouncedRef(this.view.state); 18446 this.reactiveExtensionStorage = useDebouncedRef(this.extensionStorage); 18447 this.on("transaction", () => { 18448 this.reactiveState.value = this.view.state; 18449 this.reactiveExtensionStorage.value = this.extensionStorage; 18450 }); 18451 return markRaw(this); 18452 } 18453 get state() { 18454 return this.reactiveState ? this.reactiveState.value : this.view.state; 18455 } 18456 get storage() { 18457 return this.reactiveExtensionStorage ? this.reactiveExtensionStorage.value : super.storage; 18458 } 18459 /** 18460 * Register a ProseMirror plugin. 18461 */ 18462 registerPlugin(plugin, handlePlugins) { 18463 super.registerPlugin(plugin, handlePlugins); 18464 this.reactiveState.value = this.view.state; 18465 } 18466 /** 18467 * Unregister a ProseMirror plugin. 18468 */ 18469 unregisterPlugin(nameOrPluginKey) { 18470 super.unregisterPlugin(nameOrPluginKey); 18471 this.reactiveState.value = this.view.state; 18472 } 18473} 18474const EditorContent = defineComponent({ 18475 name: "EditorContent", 18476 props: { 18477 editor: { 18478 default: null, 18479 type: Object 18480 } 18481 }, 18482 setup(props) { 18483 const rootEl = ref(); 18484 const instance = getCurrentInstance(); 18485 watchEffect(() => { 18486 const editor = props.editor; 18487 if (editor && editor.options.element && rootEl.value) { 18488 nextTick(() => { 18489 if (!rootEl.value || !editor.options.element.firstChild) { 18490 return; 18491 } 18492 const element = unref(rootEl.value); 18493 rootEl.value.append(...editor.options.element.childNodes); 18494 editor.contentComponent = instance.ctx._; 18495 editor.setOptions({ 18496 element 18497 }); 18498 editor.createNodeViews(); 18499 }); 18500 } 18501 }); 18502 onBeforeUnmount(() => { 18503 const editor = props.editor; 18504 if (!editor) { 18505 return; 18506 } 18507 if (!editor.isDestroyed) { 18508 editor.view.setProps({ 18509 nodeViews: {} 18510 }); 18511 } 18512 editor.contentComponent = null; 18513 if (!editor.options.element.firstChild) { 18514 return; 18515 } 18516 const newElement = document.createElement("div"); 18517 newElement.append(...editor.options.element.childNodes); 18518 editor.setOptions({ 18519 element: newElement 18520 }); 18521 }); 18522 return { rootEl }; 18523 }, 18524 render() { 18525 const vueRenderers = []; 18526 if (this.editor) { 18527 this.editor.vueRenderers.forEach((vueRenderer) => { 18528 const node = h(Teleport, { 18529 to: vueRenderer.teleportElement, 18530 key: vueRenderer.id 18531 }, h(vueRenderer.component, { 18532 ref: vueRenderer.id, 18533 ...vueRenderer.props 18534 })); 18535 vueRenderers.push(node); 18536 }); 18537 } 18538 return h("div", { 18539 ref: (el) => { 18540 this.rootEl = el; 18541 } 18542 }, ...vueRenderers); 18543 } 18544}); 18545defineComponent({ 18546 name: "FloatingMenu", 18547 props: { 18548 pluginKey: { 18549 // TODO: TypeScript breaks :( 18550 // type: [String, Object as PropType<Exclude<FloatingMenuPluginProps['pluginKey'], string>>], 18551 type: null, 18552 default: "floatingMenu" 18553 }, 18554 editor: { 18555 type: Object, 18556 required: true 18557 }, 18558 tippyOptions: { 18559 type: Object, 18560 default: () => ({}) 18561 }, 18562 shouldShow: { 18563 type: Function, 18564 default: null 18565 } 18566 }, 18567 setup(props, { slots }) { 18568 const root = ref(null); 18569 onMounted(() => { 18570 const { pluginKey, editor, tippyOptions, shouldShow } = props; 18571 editor.registerPlugin(FloatingMenuPlugin({ 18572 pluginKey, 18573 editor, 18574 element: root.value, 18575 tippyOptions, 18576 shouldShow 18577 })); 18578 }); 18579 onBeforeUnmount(() => { 18580 const { pluginKey, editor } = props; 18581 editor.unregisterPlugin(pluginKey); 18582 }); 18583 return () => { 18584 var _a; 18585 return h("div", { ref: root }, (_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots)); 18586 }; 18587 } 18588}); 18589defineComponent({ 18590 name: "NodeViewContent", 18591 props: { 18592 as: { 18593 type: String, 18594 default: "div" 18595 } 18596 }, 18597 render() { 18598 return h(this.as, { 18599 style: { 18600 whiteSpace: "pre-wrap" 18601 }, 18602 "data-node-view-content": "" 18603 }); 18604 } 18605}); 18606defineComponent({ 18607 name: "NodeViewWrapper", 18608 props: { 18609 as: { 18610 type: String, 18611 default: "div" 18612 } 18613 }, 18614 inject: ["onDragStart", "decorationClasses"], 18615 render() { 18616 var _a, _b; 18617 return h(this.as, { 18618 // @ts-ignore 18619 class: this.decorationClasses, 18620 style: { 18621 whiteSpace: "normal" 18622 }, 18623 "data-node-view-wrapper": "", 18624 // @ts-ignore (https://github.com/vuejs/vue-next/issues/3031) 18625 onDragstart: this.onDragStart 18626 }, (_b = (_a = this.$slots).default) === null || _b === void 0 ? void 0 : _b.call(_a)); 18627 } 18628}); 18629const useEditor = (options = {}) => { 18630 const editor = shallowRef(); 18631 onMounted(() => { 18632 editor.value = new Editor2(options); 18633 }); 18634 onBeforeUnmount(() => { 18635 var _a; 18636 (_a = editor.value) === null || _a === void 0 ? void 0 : _a.destroy(); 18637 }); 18638 return editor; 18639}; 18640const starInputRegex$1 = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))$/; 18641const starPasteRegex$1 = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))/g; 18642const underscoreInputRegex$1 = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))$/; 18643const underscorePasteRegex$1 = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))/g;
18644const Bold = Mark2.create({ 18645 name: "bold", 18646 addOptions() { 18647 return { 18648 HTMLAttributes: {} 18649 }; 18650 }, 18651 parseHTML() { 18652 return [ 18653 { 18654 tag: "strong" 18655 }, 18656 { 18657 tag: "b", 18658 getAttrs: (node) => node.style.fontWeight !== "normal" && null 18659 }, 18660 { 18661 style: "font-weight", 18662 getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null 18663 } 18664 ]; 18665 }, 18666 renderHTML({ HTMLAttributes }) { 18667 return ["strong", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 18668 }, 18669 addCommands() { 18670 return { 18671 setBold: () => ({ commands: commands2 }) => { 18672 return commands2.setMark(this.name); 18673 }, 18674 toggleBold: () => ({ commands: commands2 }) => { 18675 return commands2.toggleMark(this.name); 18676 }, 18677 unsetBold: () => ({ commands: commands2 }) => { 18678 return commands2.unsetMark(this.name); 18679 } 18680 }; 18681 }, 18682 addKeyboardShortcuts() { 18683 return { 18684 "Mod-b": () => this.editor.commands.toggleBold(), 18685 "Mod-B": () => this.editor.commands.toggleBold() 18686 }; 18687 }, 18688 addInputRules() { 18689 return [ 18690 markInputRule({ 18691 find: starInputRegex$1, 18692 type: this.type 18693 }), 18694 markInputRule({ 18695 find: underscoreInputRegex$1, 18696 type: this.type 18697 }) 18698 ]; 18699 }, 18700 addPasteRules() { 18701 return [ 18702 markPasteRule({ 18703 find: starPasteRegex$1, 18704 type: this.type 18705 }), 18706 markPasteRule({ 18707 find: underscorePasteRegex$1, 18708 type: this.type 18709 }) 18710 ]; 18711 } 18712}); 18713const starInputRegex = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))$/; 18714const starPasteRegex = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))/g; 18715const underscoreInputRegex = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))$/; 18716const underscorePasteRegex = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))/g;
18717const Italic = Mark2.create({ 18718 name: "italic", 18719 addOptions() { 18720 return { 18721 HTMLAttributes: {} 18722 }; 18723 }, 18724 parseHTML() { 18725 return [ 18726 { 18727 tag: "em" 18728 }, 18729 { 18730 tag: "i", 18731 getAttrs: (node) => node.style.fontStyle !== "normal" && null 18732 }, 18733 { 18734 style: "font-style=italic" 18735 } 18736 ]; 18737 }, 18738 renderHTML({ HTMLAttributes }) { 18739 return ["em", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 18740 }, 18741 addCommands() { 18742 return { 18743 setItalic: () => ({ commands: commands2 }) => { 18744 return commands2.setMark(this.name); 18745 }, 18746 toggleItalic: () => ({ commands: commands2 }) => { 18747 return commands2.toggleMark(this.name); 18748 }, 18749 unsetItalic: () => ({ commands: commands2 }) => { 18750 return commands2.unsetMark(this.name); 18751 } 18752 }; 18753 }, 18754 addKeyboardShortcuts() { 18755 return { 18756 "Mod-i": () => this.editor.commands.toggleItalic(), 18757 "Mod-I": () => this.editor.commands.toggleItalic() 18758 }; 18759 }, 18760 addInputRules() { 18761 return [ 18762 markInputRule({ 18763 find: starInputRegex, 18764 type: this.type 18765 }), 18766 markInputRule({ 18767 find: underscoreInputRegex, 18768 type: this.type 18769 }) 18770 ]; 18771 }, 18772 addPasteRules() { 18773 return [ 18774 markPasteRule({ 18775 find: starPasteRegex, 18776 type: this.type 18777 }), 18778 markPasteRule({ 18779 find: underscorePasteRegex, 18780 type: this.type 18781 }) 18782 ]; 18783 } 18784}); 18785const Underline = Mark2.create({ 18786 name: "underline", 18787 addOptions() { 18788 return { 18789 HTMLAttributes: {} 18790 }; 18791 }, 18792 parseHTML() { 18793 return [ 18794 { 18795 tag: "u" 18796 }, 18797 { 18798 style: "text-decoration", 18799 consuming: false, 18800 getAttrs: (style2) => style2.includes("underline") ? {} : false 18801 } 18802 ]; 18803 }, 18804 renderHTML({ HTMLAttributes }) { 18805 return ["u", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 18806 }, 18807 addCommands() { 18808 return { 18809 setUnderline: () => ({ commands: commands2 }) => { 18810 return commands2.setMark(this.name); 18811 }, 18812 toggleUnderline: () => ({ commands: commands2 }) => { 18813 return commands2.toggleMark(this.name); 18814 }, 18815 unsetUnderline: () => ({ commands: commands2 }) => { 18816 return commands2.unsetMark(this.name); 18817 } 18818 }; 18819 }, 18820 addKeyboardShortcuts() { 18821 return { 18822 "Mod-u": () => this.editor.commands.toggleUnderline(), 18823 "Mod-U": () => this.editor.commands.toggleUnderline() 18824 }; 18825 } 18826}); 18827const encodedTlds = "aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4vianca6w0s2x0a2z0ure5ba0by2idu3namex3narepublic11d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2ntley5rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0cast4mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dabur3d1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3nlop4pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2o0dyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0ardian6cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6logistics9properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3ncaster6d0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2psy3ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rckmsd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2tura4vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9dnavy5lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2
18827ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0america6xi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0stone5umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0a1b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp2w2ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2olterskluwer11odside6rk0s2ld3w2s1tc1f3xbox3erox4finity6ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2"; 18828const encodedUtlds = "ελ1Ï 2бг1ел3деÑи4еÑ2каÑолик6ом3мÐ
18828ºÐ´2он1Ñква6онлайн5Ñг3ÑÑÑ2Ñ2ÑайÑ3Ñб3ÑкÑ3Òаз3Õ°Õ¡Õµ3×שר××5×§××3Ø§Ø¨ÙØ¸Ø¨Ù5را٠ÙÙ5ÙØ§Ø±Ø¯Ù4Ø¨ØØ±ÙÙ5جزائر5Ø³Ø¹ÙØ¯ÙØ©6عÙÙØ§Ù5٠غرب5٠ارات5ÛØ±Ø§Ù5بارت2زار4ÙØªÙ3ھارت5تÙÙØ³4Ø³ÙØ¯Ø§Ù3Ø±ÙØ©5Ø´Ø¨ÙØ©4عراÙ2ب2٠اÙ4ÙÙØ³Ø·ÙÙ6ÙØ·Ø±3ÙØ§Ø«ÙÙÙÙ6ÙÙ 3٠صر2ÙÙØ³Ùا5ÙØ±ÙتاÙÙØ§7ÙØ¹4Ù٠راÙ5پاکستاÙ7ÚØ§Ø±Øª4à¤à¥à¤®3नà¥à¤3à¤à¤¾à¤°à¤¤0मà¥3à¥à¤¤5सà¤à¤à¤ न5বাà¦à¦²à¦¾5à¦à¦¾à¦°à¦¤2ৰত4à¨à¨¾à¨°à¨¤4àªàª¾àª°àª¤4à¬à¬¾à¬°à¬¤4à®à®¨à¯à®¤à®¿à®¯à®¾6லà®à¯à®à¯6à®à®¿à®à¯à®à®ªà¯à®ªà¯à®°à¯11à°à°¾à°°à°¤à±5à²à²¾à²°à²¤4à´à´¾à´°à´¤à´5à¶½à¶à¶à·4à¸à¸à¸¡3à¹à¸à¸¢3ລາວ3áá2ã¿ããª3ã¢ãã¾ã³4ã¯ã©ã¦ã4ã°ã¼ã°ã«4ã³ã 2ã¹ãã¢3ã»ã¼ã«3ãã¡ãã·ã§ã³6ãã¤ã³ã4ä¸ç2ä¸ä¿¡1å½1å1æç½3äºé©¬é3ä¼ä¸2ä½å±±2ä¿¡æ¯2å¥åº·2å «å¦2å ¬å¸1ç2å°æ¹¾1ç£2åå1åº1æ 2åé0大é åº5å¨çº¿2大æ¿2天主æ3娱ä¹2å®¶é»2广ä¸2å¾®å2æ å2æç±ä½ 3ææº2æè2æ¿å¡1åº2æ°å å¡2é»2æ¶å°2æ¸ç±2æºæ2淡马é¡3游æ2æ¾³é2ç¹ç2ç§»å¨2ç»ç»æºæ4ç½å1åº1ç«1ç»2èé2è°·æ2è´ç©2é販2éå¢2é»è¨çç§4é£å©æµ¦3é£å2é¤å 2馿 ¼éæ3港2ë·ë·1ì»´2ì¼ì±2íêµ2"; 18829const assign = (target, properties) => { 18830 for (const key in properties) { 18831 target[key] = properties[key]; 18832 } 18833 return target; 18834}; 18835const numeric = "numeric"; 18836const ascii = "ascii";
vendor: 7,730 bytes, lines 18837-19082
18837const alpha = "alpha"; 18838const asciinumeric = "asciinumeric"; 18839const alphanumeric = "alphanumeric"; 18840const domain = "domain"; 18841const emoji = "emoji"; 18842const scheme = "scheme"; 18843const slashscheme = "slashscheme"; 18844const whitespace = "whitespace"; 18845function registerGroup(name, groups) { 18846 if (!(name in groups)) { 18847 groups[name] = []; 18848 } 18849 return groups[name]; 18850} 18851function addToGroups(t, flags, groups) { 18852 if (flags[numeric]) { 18853 flags[asciinumeric] = true; 18854 flags[alphanumeric] = true; 18855 } 18856 if (flags[ascii]) { 18857 flags[asciinumeric] = true; 18858 flags[alpha] = true; 18859 } 18860 if (flags[asciinumeric]) { 18861 flags[alphanumeric] = true; 18862 } 18863 if (flags[alpha]) { 18864 flags[alphanumeric] = true; 18865 } 18866 if (flags[alphanumeric]) { 18867 flags[domain] = true; 18868 } 18869 if (flags[emoji]) { 18870 flags[domain] = true; 18871 } 18872 for (const k in flags) { 18873 const group = registerGroup(k, groups); 18874 if (group.indexOf(t) < 0) { 18875 group.push(t); 18876 } 18877 } 18878} 18879function flagsForToken(t, groups) { 18880 const result = {}; 18881 for (const c in groups) { 18882 if (groups[c].indexOf(t) >= 0) { 18883 result[c] = true; 18884 } 18885 } 18886 return result; 18887} 18888function State(token) { 18889 if (token === void 0) { 18890 token = null; 18891 } 18892 this.j = {}; 18893 this.jr = []; 18894 this.jd = null; 18895 this.t = token; 18896} 18897State.groups = {}; 18898State.prototype = { 18899 accepts() { 18900 return !!this.t; 18901 }, 18902 /** 18903 * Follow an existing transition from the given input to the next state. 18904 * Does not mutate. 18905 * @param {string} input character or token type to transition on 18906 * @returns {?State<T>} the next state, if any 18907 */ 18908 go(input) { 18909 const state = this; 18910 const nextState = state.j[input]; 18911 if (nextState) { 18912 return nextState; 18913 } 18914 for (let i = 0; i < state.jr.length; i++) { 18915 const regex = state.jr[i][0]; 18916 const nextState2 = state.jr[i][1]; 18917 if (nextState2 && regex.test(input)) { 18918 return nextState2; 18919 } 18920 } 18921 return state.jd; 18922 }, 18923 /** 18924 * Whether the state has a transition for the given input. Set the second 18925 * argument to true to only look for an exact match (and not a default or 18926 * regular-expression-based transition) 18927 * @param {string} input 18928 * @param {boolean} exactOnly 18929 */ 18930 has(input, exactOnly) { 18931 if (exactOnly === void 0) { 18932 exactOnly = false; 18933 } 18934 return exactOnly ? input in this.j : !!this.go(input); 18935 }, 18936 /** 18937 * Short for "transition all"; create a transition from the array of items 18938 * in the given list to the same final resulting state. 18939 * @param {string | string[]} inputs Group of inputs to transition on 18940 * @param {Transition<T> | State<T>} [next] Transition options 18941 * @param {Flags} [flags] Collections flags to add token to 18942 * @param {Collections<T>} [groups] Master list of token groups 18943 */ 18944 ta(inputs, next, flags, groups) { 18945 for (let i = 0; i < inputs.length; i++) { 18946 this.tt(inputs[i], next, flags, groups); 18947 } 18948 }, 18949 /** 18950 * Short for "take regexp transition"; defines a transition for this state 18951 * when it encounters a token which matches the given regular expression 18952 * @param {RegExp} regexp Regular expression transition (populate first) 18953 * @param {T | State<T>} [next] Transition options 18954 * @param {Flags} [flags] Collections flags to add token to 18955 * @param {Collections<T>} [groups] Master list of token groups 18956 * @returns {State<T>} taken after the given input 18957 */ 18958 tr(regexp, next, flags, groups) { 18959 groups = groups || State.groups; 18960 let nextState; 18961 if (next && next.j) { 18962 nextState = next; 18963 } else { 18964 nextState = new State(next); 18965 if (flags && groups) { 18966 addToGroups(next, flags, groups); 18967 } 18968 } 18969 this.jr.push([regexp, nextState]); 18970 return nextState; 18971 }, 18972 /** 18973 * Short for "take transitions", will take as many sequential transitions as 18974 * the length of the given input and returns the 18975 * resulting final state. 18976 * @param {string | string[]} input 18977 * @param {T | State<T>} [next] Transition options 18978 * @param {Flags} [flags] Collections flags to add token to 18979 * @param {Collections<T>} [groups] Master list of token groups 18980 * @returns {State<T>} taken after the given input 18981 */ 18982 ts(input, next, flags, groups) { 18983 let state = this; 18984 const len = input.length; 18985 if (!len) { 18986 return state; 18987 } 18988 for (let i = 0; i < len - 1; i++) { 18989 state = state.tt(input[i]); 18990 } 18991 return state.tt(input[len - 1], next, flags, groups); 18992 }, 18993 /** 18994 * Short for "take transition", this is a method for building/working with 18995 * state machines. 18996 * 18997 * If a state already exists for the given input, returns it. 18998 * 18999 * If a token is specified, that state will emit that token when reached by 19000 * the linkify engine. 19001 * 19002 * If no state exists, it will be initialized with some default transitions 19003 * that resemble existing default transitions. 19004 * 19005 * If a state is given for the second argument, that state will be 19006 * transitioned to on the given input regardless of what that input 19007 * previously did. 19008 * 19009 * Specify a token group flags to define groups that this token belongs to. 19010 * The token will be added to corresponding entires in the given groups 19011 * object. 19012 * 19013 * @param {string} input character, token type to transition on 19014 * @param {T | State<T>} [next] Transition options 19015 * @param {Flags} [flags] Collections flags to add token to 19016 * @param {Collections<T>} [groups] Master list of groups 19017 * @returns {State<T>} taken after the given input 19018 */ 19019 tt(input, next, flags, groups) { 19020 groups = groups || State.groups; 19021 const state = this; 19022 if (next && next.j) { 19023 state.j[input] = next; 19024 return next; 19025 } 19026 const t = next; 19027 let nextState, templateState = state.go(input); 19028 if (templateState) { 19029 nextState = new State(); 19030 assign(nextState.j, templateState.j); 19031 nextState.jr.push.apply(nextState.jr, templateState.jr); 19032 nextState.jd = templateState.jd; 19033 nextState.t = templateState.t; 19034 } else { 19035 nextState = new State(); 19036 } 19037 if (t) { 19038 if (groups) { 19039 if (nextState.t && typeof nextState.t === "string") { 19040 const allFlags = assign(flagsForToken(nextState.t, groups), flags); 19041 addToGroups(t, allFlags, groups); 19042 } else if (flags) { 19043 addToGroups(t, flags, groups); 19044 } 19045 } 19046 nextState.t = t; 19047 } 19048 state.j[input] = nextState; 19049 return nextState; 19050 } 19051}; 19052const ta = (state, input, next, flags, groups) => state.ta(input, next, flags, groups); 19053const tr = (state, regexp, next, flags, groups) => state.tr(regexp, next, flags, groups); 19054const ts = (state, input, next, flags, groups) => state.ts(input, next, flags, groups); 19055const tt = (state, input, next, flags, groups) => state.tt(input, next, flags, groups); 19056const WORD = "WORD"; 19057const UWORD = "UWORD"; 19058const LOCALHOST = "LOCALHOST"; 19059const TLD = "TLD"; 19060const UTLD = "UTLD"; 19061const SCHEME = "SCHEME"; 19062const SLASH_SCHEME = "SLASH_SCHEME"; 19063const NUM = "NUM"; 19064const WS = "WS"; 19065const NL$1 = "NL"; 19066const OPENBRACE = "OPENBRACE"; 19067const CLOSEBRACE = "CLOSEBRACE"; 19068const OPENBRACKET = "OPENBRACKET"; 19069const CLOSEBRACKET = "CLOSEBRACKET"; 19070const OPENPAREN = "OPENPAREN"; 19071const CLOSEPAREN = "CLOSEPAREN"; 19072const OPENANGLEBRACKET = "OPENANGLEBRACKET"; 19073const CLOSEANGLEBRACKET = "CLOSEANGLEBRACKET"; 19074const FULLWIDTHLEFTPAREN = "FULLWIDTHLEFTPAREN"; 19075const FULLWIDTHRIGHTPAREN = "FULLWIDTHRIGHTPAREN"; 19076const LEFTCORNERBRACKET = "LEFTCORNERBRACKET"; 19077const RIGHTCORNERBRACKET = "RIGHTCORNERBRACKET"; 19078const LEFTWHITECORNERBRACKET = "LEFTWHITECORNERBRACKET"; 19079const RIGHTWHITECORNERBRACKET = "RIGHTWHITECORNERBRACKET"; 19080const FULLWIDTHLESSTHAN = "FULLWIDTHLESSTHAN"; 19081const FULLWIDTHGREATERTHAN = "FULLWIDTHGREATERTHAN"; 19082const AMPERSAND = "AMPERSAND";
19083const APOSTROPHE = "APOSTROPHE"; 19084const ASTERISK = "ASTERISK"; 19085const AT = "AT"; 19086const BACKSLASH = "BACKSLASH"; 19087const BACKTICK = "BACKTICK"; 19088const CARET = "CARET"; 19089const COLON = "COLON"; 19090const COMMA = "COMMA"; 19091const DOLLAR = "DOLLAR"; 19092const DOT = "DOT"; 19093const EQUALS = "EQUALS"; 19094const EXCLAMATION = "EXCLAMATION"; 19095const HYPHEN = "HYPHEN"; 19096const PERCENT = "PERCENT"; 19097const PIPE = "PIPE"; 19098const PLUS = "PLUS"; 19099const POUND = "POUND"; 19100const QUERY = "QUERY"; 19101const QUOTE = "QUOTE"; 19102const SEMI = "SEMI"; 19103const SLASH = "SLASH"; 19104const TILDE = "TILDE"; 19105const UNDERSCORE = "UNDERSCORE"; 19106const EMOJI$1 = "EMOJI"; 19107const SYM = "SYM"; 19108var tk = /* @__PURE__ */ Object.freeze({ 19109 __proto__: null, 19110 WORD, 19111 UWORD, 19112 LOCALHOST, 19113 TLD, 19114 UTLD, 19115 SCHEME, 19116 SLASH_SCHEME, 19117 NUM, 19118 WS, 19119 NL: NL$1, 19120 OPENBRACE, 19121 CLOSEBRACE, 19122 OPENBRACKET, 19123 CLOSEBRACKET, 19124 OPENPAREN, 19125 CLOSEPAREN, 19126 OPENANGLEBRACKET, 19127 CLOSEANGLEBRACKET, 19128 FULLWIDTHLEFTPAREN, 19129 FULLWIDTHRIGHTPAREN, 19130 LEFTCORNERBRACKET, 19131 RIGHTCORNERBRACKET, 19132 LEFTWHITECORNERBRACKET, 19133 RIGHTWHITECORNERBRACKET, 19134 FULLWIDTHLESSTHAN, 19135 FULLWIDTHGREATERTHAN, 19136 AMPERSAND, 19137 APOSTROPHE, 19138 ASTERISK, 19139 AT, 19140 BACKSLASH, 19141 BACKTICK, 19142 CARET, 19143 COLON, 19144 COMMA, 19145 DOLLAR, 19146 DOT, 19147 EQUALS, 19148 EXCLAMATION, 19149 HYPHEN, 19150 PERCENT, 19151 PIPE, 19152 PLUS, 19153 POUND, 19154 QUERY, 19155 QUOTE, 19156 SEMI, 19157 SLASH, 19158 TILDE, 19159 UNDERSCORE, 19160 EMOJI: EMOJI$1, 19161 SYM 19162}); 19163const ASCII_LETTER = /[a-z]/; 19164const LETTER = /\p{L}/u; 19165const EMOJI = /\p{Emoji}/u; 19166const DIGIT = /\d/; 19167const SPACE = /\s/; 19168const NL = "\n"; 19169const EMOJI_VARIATION = "ï¸"; 19170const EMOJI_JOINER = "â"; 19171let tlds = null, utlds = null; 19172function init$2(customSchemes) { 19173 if (customSchemes === void 0) { 19174 customSchemes = []; 19175 } 19176 const groups = {}; 19177 State.groups = groups; 19178 const Start = new State(); 19179 if (tlds == null) { 19180 tlds = decodeTlds(encodedTlds); 19181 } 19182 if (utlds == null) { 19183 utlds = decodeTlds(encodedUtlds); 19184 } 19185 tt(Start, "'", APOSTROPHE); 19186 tt(Start, "{", OPENBRACE); 19187 tt(Start, "}", CLOSEBRACE); 19188 tt(Start, "[", OPENBRACKET); 19189 tt(Start, "]", CLOSEBRACKET); 19190 tt(Start, "(", OPENPAREN); 19191 tt(Start, ")", CLOSEPAREN); 19192 tt(Start, "<", OPENANGLEBRACKET); 19193 tt(Start, ">", CLOSEANGLEBRACKET); 19194 tt(Start, "ï¼", FULLWIDTHLEFTPAREN); 19195 tt(Start, "ï¼", FULLWIDTHRIGHTPAREN); 19196 tt(Start, "ã", LEFTCORNERBRACKET); 19197 tt(Start, "ã", RIGHTCORNERBRACKET); 19198 tt(Start, "ã", LEFTWHITECORNERBRACKET); 19199 tt(Start, "ã", RIGHTWHITECORNERBRACKET); 19200 tt(Start, "ï¼", FULLWIDTHLESSTHAN); 19201 tt(Start, "ï¼", FULLWIDTHGREATERTHAN); 19202 tt(Start, "&", AMPERSAND); 19203 tt(Start, "*", ASTERISK); 19204 tt(Start, "@", AT); 19205 tt(Start, "`", BACKTICK); 19206 tt(Start, "^", CARET); 19207 tt(Start, ":", COLON); 19208 tt(Start, ",", COMMA); 19209 tt(Start, "$", DOLLAR); 19210 tt(Start, ".", DOT); 19211 tt(Start, "=", EQUALS); 19212 tt(Start, "!", EXCLAMATION); 19213 tt(Start, "-", HYPHEN); 19214 tt(Start, "%", PERCENT); 19215 tt(Start, "|", PIPE); 19216 tt(Start, "+", PLUS); 19217 tt(Start, "#", POUND); 19218 tt(Start, "?", QUERY); 19219 tt(Start, '"', QUOTE); 19220 tt(Start, "/", SLASH); 19221 tt(Start, ";", SEMI); 19222 tt(Start, "~", TILDE); 19223 tt(Start, "_", UNDERSCORE); 19224 tt(Start, "\\", BACKSLASH); 19225 const Num = tr(Start, DIGIT, NUM, { 19226 [numeric]: true 19227 }); 19228 tr(Num, DIGIT, Num); 19229 const Word = tr(Start, ASCII_LETTER, WORD, { 19230 [ascii]: true 19231 }); 19232 tr(Word, ASCII_LETTER, Word); 19233 const UWord = tr(Start, LETTER, UWORD, { 19234 [alpha]: true 19235 }); 19236 tr(UWord, ASCII_LETTER); 19237 tr(UWord, LETTER, UWord); 19238 const Ws = tr(Start, SPACE, WS, { 19239 [whitespace]: true 19240 }); 19241 tt(Start, NL, NL$1, { 19242 [whitespace]: true 19243 }); 19244 tt(Ws, NL); 19245 tr(Ws, SPACE, Ws); 19246 const Emoji = tr(Start, EMOJI, EMOJI$1, { 19247 [emoji]: true 19248 }); 19249 tr(Emoji, EMOJI, Emoji); 19250 tt(Emoji, EMOJI_VARIATION, Emoji); 19251 const EmojiJoiner = tt(Emoji, EMOJI_JOINER); 19252 tr(EmojiJoiner, EMOJI, Emoji); 19253 const wordjr = [[ASCII_LETTER, Word]]; 19254 const uwordjr = [[ASCII_LETTER, null], [LETTER, UWord]]; 19255 for (let i = 0; i < tlds.length; i++) { 19256 fastts(Start, tlds[i], TLD, WORD, wordjr); 19257 } 19258 for (let i = 0; i < utlds.length; i++) { 19259 fastts(Start, utlds[i], UTLD, UWORD, uwordjr); 19260 } 19261 addToGroups(TLD, { 19262 tld: true, 19263 ascii: true 19264 }, groups); 19265 addToGroups(UTLD, { 19266 utld: true,
vendor: 6,868 bytes, lines 19267-19515
19267 alpha: true 19268 }, groups); 19269 fastts(Start, "file", SCHEME, WORD, wordjr); 19270 fastts(Start, "mailto", SCHEME, WORD, wordjr); 19271 fastts(Start, "http", SLASH_SCHEME, WORD, wordjr); 19272 fastts(Start, "https", SLASH_SCHEME, WORD, wordjr); 19273 fastts(Start, "ftp", SLASH_SCHEME, WORD, wordjr); 19274 fastts(Start, "ftps", SLASH_SCHEME, WORD, wordjr); 19275 addToGroups(SCHEME, { 19276 scheme: true, 19277 ascii: true 19278 }, groups); 19279 addToGroups(SLASH_SCHEME, { 19280 slashscheme: true, 19281 ascii: true 19282 }, groups); 19283 customSchemes = customSchemes.sort((a, b) => a[0] > b[0] ? 1 : -1); 19284 for (let i = 0; i < customSchemes.length; i++) { 19285 const sch = customSchemes[i][0]; 19286 const optionalSlashSlash = customSchemes[i][1]; 19287 const flags = optionalSlashSlash ? { 19288 [scheme]: true 19289 } : { 19290 [slashscheme]: true 19291 }; 19292 if (sch.indexOf("-") >= 0) { 19293 flags[domain] = true; 19294 } else if (!ASCII_LETTER.test(sch)) { 19295 flags[numeric] = true; 19296 } else if (DIGIT.test(sch)) { 19297 flags[asciinumeric] = true; 19298 } else { 19299 flags[ascii] = true; 19300 } 19301 ts(Start, sch, sch, flags); 19302 } 19303 ts(Start, "localhost", LOCALHOST, { 19304 ascii: true 19305 }); 19306 Start.jd = new State(SYM); 19307 return { 19308 start: Start, 19309 tokens: assign({ 19310 groups 19311 }, tk) 19312 }; 19313} 19314function run$1(start2, str) { 19315 const iterable = stringToArray(str.replace(/[A-Z]/g, (c) => c.toLowerCase())); 19316 const charCount = iterable.length; 19317 const tokens = []; 19318 let cursor = 0; 19319 let charCursor = 0; 19320 while (charCursor < charCount) { 19321 let state = start2; 19322 let nextState = null; 19323 let tokenLength = 0; 19324 let latestAccepting = null; 19325 let sinceAccepts = -1; 19326 let charsSinceAccepts = -1; 19327 while (charCursor < charCount && (nextState = state.go(iterable[charCursor]))) { 19328 state = nextState; 19329 if (state.accepts()) { 19330 sinceAccepts = 0; 19331 charsSinceAccepts = 0; 19332 latestAccepting = state; 19333 } else if (sinceAccepts >= 0) { 19334 sinceAccepts += iterable[charCursor].length; 19335 charsSinceAccepts++; 19336 } 19337 tokenLength += iterable[charCursor].length; 19338 cursor += iterable[charCursor].length; 19339 charCursor++; 19340 } 19341 cursor -= sinceAccepts; 19342 charCursor -= charsSinceAccepts; 19343 tokenLength -= sinceAccepts; 19344 tokens.push({ 19345 t: latestAccepting.t, 19346 // token type/name 19347 v: str.slice(cursor - tokenLength, cursor), 19348 // string value 19349 s: cursor - tokenLength, 19350 // start index 19351 e: cursor 19352 // end index (excluding) 19353 }); 19354 } 19355 return tokens; 19356} 19357function stringToArray(str) { 19358 const result = []; 19359 const len = str.length; 19360 let index = 0; 19361 while (index < len) { 19362 let first2 = str.charCodeAt(index); 19363 let second; 19364 let char = first2 < 55296 || first2 > 56319 || index + 1 === len || (second = str.charCodeAt(index + 1)) < 56320 || second > 57343 ? str[index] : str.slice(index, index + 2); 19365 result.push(char); 19366 index += char.length; 19367 } 19368 return result; 19369} 19370function fastts(state, input, t, defaultt, jr) { 19371 let next; 19372 const len = input.length; 19373 for (let i = 0; i < len - 1; i++) { 19374 const char = input[i]; 19375 if (state.j[char]) { 19376 next = state.j[char]; 19377 } else { 19378 next = new State(defaultt); 19379 next.jr = jr.slice(); 19380 state.j[char] = next; 19381 } 19382 state = next; 19383 } 19384 next = new State(t); 19385 next.jr = jr.slice(); 19386 state.j[input[len - 1]] = next; 19387 return next; 19388} 19389function decodeTlds(encoded) { 19390 const words = []; 19391 const stack = []; 19392 let i = 0; 19393 let digits = "0123456789"; 19394 while (i < encoded.length) { 19395 let popDigitCount = 0; 19396 while (digits.indexOf(encoded[i + popDigitCount]) >= 0) { 19397 popDigitCount++; 19398 } 19399 if (popDigitCount > 0) { 19400 words.push(stack.join("")); 19401 for (let popCount = parseInt(encoded.substring(i, i + popDigitCount), 10); popCount > 0; popCount--) { 19402 stack.pop(); 19403 } 19404 i += popDigitCount; 19405 } else { 19406 stack.push(encoded[i]); 19407 i++; 19408 } 19409 } 19410 return words; 19411} 19412const defaults = { 19413 defaultProtocol: "http", 19414 events: null, 19415 format: noop, 19416 formatHref: noop, 19417 nl2br: false, 19418 tagName: "a", 19419 target: null, 19420 rel: null, 19421 validate: true, 19422 truncate: Infinity, 19423 className: null, 19424 attributes: null, 19425 ignoreTags: [], 19426 render: null 19427}; 19428function Options(opts, defaultRender) { 19429 if (defaultRender === void 0) { 19430 defaultRender = null; 19431 } 19432 let o = assign({}, defaults); 19433 if (opts) { 19434 o = assign(o, opts instanceof Options ? opts.o : opts); 19435 } 19436 const ignoredTags = o.ignoreTags; 19437 const uppercaseIgnoredTags = []; 19438 for (let i = 0; i < ignoredTags.length; i++) { 19439 uppercaseIgnoredTags.push(ignoredTags[i].toUpperCase()); 19440 } 19441 this.o = o; 19442 if (defaultRender) { 19443 this.defaultRender = defaultRender; 19444 } 19445 this.ignoreTags = uppercaseIgnoredTags; 19446} 19447Options.prototype = { 19448 o: defaults, 19449 /** 19450 * @type string[] 19451 */ 19452 ignoreTags: [], 19453 /** 19454 * @param {IntermediateRepresentation} ir 19455 * @returns {any} 19456 */ 19457 defaultRender(ir) { 19458 return ir; 19459 }, 19460 /** 19461 * Returns true or false based on whether a token should be displayed as a 19462 * link based on the user options. 19463 * @param {MultiToken} token 19464 * @returns {boolean} 19465 */ 19466 check(token) { 19467 return this.get("validate", token.toString(), token); 19468 }, 19469 // Private methods 19470 /** 19471 * Resolve an option's value based on the value of the option and the given 19472 * params. If operator and token are specified and the target option is 19473 * callable, automatically calls the function with the given argument. 19474 * @template {keyof Opts} K 19475 * @param {K} key Name of option to use 19476 * @param {string} [operator] will be passed to the target option if it's a 19477 * function. If not specified, RAW function value gets returned 19478 * @param {MultiToken} [token] The token from linkify.tokenize 19479 * @returns {Opts[K] | any} 19480 */ 19481 get(key, operator, token) { 19482 const isCallable = operator != null; 19483 let option = this.o[key]; 19484 if (!option) { 19485 return option; 19486 } 19487 if (typeof option === "object") { 19488 option = token.t in option ? option[token.t] : defaults[key]; 19489 if (typeof option === "function" && isCallable) { 19490 option = option(operator, token); 19491 } 19492 } else if (typeof option === "function" && isCallable) { 19493 option = option(operator, token.t, token); 19494 } 19495 return option; 19496 }, 19497 /** 19498 * @template {keyof Opts} L 19499 * @param {L} key Name of options object to use 19500 * @param {string} [operator] 19501 * @param {MultiToken} [token] 19502 * @returns {Opts[L] | any} 19503 */ 19504 getObj(key, operator, token) { 19505 let obj = this.o[key]; 19506 if (typeof obj === "function" && operator != null) { 19507 obj = obj(operator, token.t, token); 19508 } 19509 return obj; 19510 }, 19511 /** 19512 * Convert the given token to a rendered element that may be added to the 19513 * calling-interface's DOM 19514 * @param {MultiToken} token Token to render to an HTML element 19515 * @returns {any} Render result;
19515 e.g., HTML string, DOM element, React 19516 * Component, etc. 19517 */ 19518 render(token) { 19519 const ir = token.render(this); 19520 const renderFn = this.get("render", null, token) || this.defaultRender; 19521 return renderFn(ir, token.t, token); 19522 } 19523}; 19524function noop(val) { 19525 return val; 19526} 19527function MultiToken(value, tokens) { 19528 this.t = "token"; 19529 this.v = value; 19530 this.tk = tokens; 19531} 19532MultiToken.prototype = { 19533 isLink: false, 19534 /** 19535 * Return the string this token represents. 19536 * @return {string} 19537 */ 19538 toString() { 19539 return this.v; 19540 }, 19541 /** 19542 * What should the value for this token be in the `href` HTML attribute? 19543 * Returns the `.toString` value by default. 19544 * @param {string} [scheme] 19545 * @return {string} 19546 */ 19547 toHref(scheme2) { 19548 return this.toString(); 19549 }, 19550 /** 19551 * @param {Options} options Formatting options 19552 * @returns {string} 19553 */ 19554 toFormattedString(options) { 19555 const val = this.toString(); 19556 const truncate = options.get("truncate", val, this); 19557 const formatted = options.get("format", val, this); 19558 return truncate && formatted.length > truncate ? formatted.substring(0, truncate) + "â¦" : formatted; 19559 }, 19560 /** 19561 * 19562 * @param {Options} options 19563 * @returns {string} 19564 */ 19565 toFormattedHref(options) { 19566 return options.get("formatHref", this.toHref(options.get("defaultProtocol")), this); 19567 }, 19568 /** 19569 * The start index of this token in the original input string 19570 * @returns {number} 19571 */ 19572 startIndex() { 19573 return this.tk[0].s; 19574 }, 19575 /** 19576 * The end index of this token in the original input string (up to this 19577 * index but not including it) 19578 * @returns {number} 19579 */ 19580 endIndex() { 19581 return this.tk[this.tk.length - 1].e; 19582 }, 19583 /** 19584 Returns an object of relevant values for this token, which includes keys 19585 * type - Kind of token ('url', 'email', etc.) 19586 * value - Original text 19587 * href - The value that should be added to the anchor tag's href 19588 attribute 19589 @method toObject 19590 @param {string} [protocol] `'http'` by default 19591 */ 19592 toObject(protocol) { 19593 if (protocol === void 0) { 19594 protocol = defaults.defaultProtocol; 19595 } 19596 return { 19597 type: this.t, 19598 value: this.toString(), 19599 isLink: this.isLink, 19600 href: this.toHref(protocol), 19601 start: this.startIndex(), 19602 end: this.endIndex() 19603 }; 19604 }, 19605 /** 19606 * 19607 * @param {Options} options Formatting option 19608 */ 19609 toFormattedObject(options) { 19610 return { 19611 type: this.t, 19612 value: this.toFormattedString(options), 19613 isLink: this.isLink, 19614 href: this.toFormattedHref(options), 19615 start: this.startIndex(), 19616 end: this.endIndex() 19617 }; 19618 }, 19619 /** 19620 * Whether this token should be rendered as a link according to the given options 19621 * @param {Options} options 19622 * @returns {boolean} 19623 */ 19624 validate(options) { 19625 return options.get("validate", this.toString(), this); 19626 }, 19627 /** 19628 * Return an object that represents how this link should be rendered. 19629 * @param {Options} options Formattinng options 19630 */ 19631 render(options) { 19632 const token = this; 19633 const href = this.toHref(options.get("defaultProtocol")); 19634 const formattedHref = options.get("formatHref", href, this); 19635 const tagName = options.get("tagName", href, token); 19636 const content = this.toFormattedString(options); 19637 const attributes = {}; 19638 const className = options.get("className", href, token); 19639 const target = options.get("target", href, token); 19640 const rel = options.get("rel", href, token); 19641 const attrs = options.getObj("attributes", href, token); 19642 const eventListeners2 = options.getObj("events", href, token); 19643 attributes.href = formattedHref; 19644 if (className) { 19645 attributes.class = className; 19646 } 19647 if (target) { 19648 attributes.target = target; 19649 } 19650 if (rel) { 19651 attributes.rel = rel; 19652 } 19653 if (attrs) { 19654 assign(attributes, attrs); 19655 } 19656 return { 19657 tagName, 19658 attributes, 19659 content, 19660 eventListeners: eventListeners2 19661 }; 19662 } 19663}; 19664function createTokenClass(type, props) { 19665 class Token extends MultiToken { 19666 constructor(value, tokens) { 19667 super(value, tokens); 19668 this.t = type; 19669 } 19670 } 19671 for (const p in props) { 19672 Token.prototype[p] = props[p]; 19673 } 19674 Token.t = type; 19675 return Token; 19676} 19677const Email = createTokenClass("email", { 19678 isLink: true, 19679 toHref() { 19680 return "mailto:" + this.toString(); 19681 } 19682}); 19683const Text$1 = createTokenClass("text"); 19684const Nl = createTokenClass("nl"); 19685const Url = createTokenClass("url", { 19686 isLink: true, 19687 /** 19688 Lowercases relevant parts of the domain and adds the protocol if 19689 required. Note that this will not escape unsafe HTML characters in the 19690 URL. 19691 @param {string} [scheme] default scheme (e.g., 'https') 19692 @return {string} the full href 19693 */ 19694 toHref(scheme2) { 19695 if (scheme2 === void 0) { 19696 scheme2 = defaults.defaultProtocol; 19697 } 19698 return this.hasProtocol() ? this.v : `${scheme2}://${this.v}`; 19699 }, 19700 /** 19701 * Check whether this URL token has a protocol 19702 * @return {boolean} 19703 */ 19704 hasProtocol() { 19705 const tokens = this.tk; 19706 return tokens.length >= 2 && tokens[0].t !== LOCALHOST && tokens[1].t === COLON; 19707 } 19708}); 19709const makeState = (arg) => new State(arg); 19710function init$1(_ref) { 19711 let { 19712 groups 19713 } = _ref; 19714 const qsAccepting = groups.domain.concat([AMPERSAND, ASTERISK, AT, BACKSLASH, BACKTICK, CARET, DOLLAR, EQUALS, HYPHEN, NUM, PERCENT, PIPE, PLUS, POUND, SLASH, SYM, TILDE, UNDERSCORE]); 19715 const qsNonAccepting = [APOSTROPHE, COLON, COMMA, DOT, EXCLAMATION, QUERY, QUOTE, SEMI, OPENANGLEBRACKET, CLOSEANGLEBRACKET, OPENBRACE, CLOSEBRACE, CLOSEBRACKET, OPENBRACKET, OPENPAREN, CLOSEPAREN, FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN, LEFTCORNERBRACKET, RIGHTCORNERBRACKET, LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET, FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN]; 19716 const localpartAccepting = [AMPERSAND, APOSTROPHE, ASTERISK, BACKSLASH, BACKTICK, CARET, DOLLAR, EQUALS, HYPHEN, OPENBRACE, CLOSEBRACE, PERCENT, PIPE, PLUS, POUND, QUERY, SLASH, SYM, TILDE, UNDERSCORE]; 19717 const Start = makeState(); 19718 const Localpart = tt(Start, TILDE); 19719 ta(Localpart, localpartAccepting, Localpart); 19720 ta(Localpart, groups.domain, Localpart); 19721 const Domain = makeState(), Scheme = makeState(), SlashScheme = makeState(); 19722 ta(Start, groups.domain, Domain); 19723 ta(Start, groups.scheme, Scheme); 19724 ta(Start, groups.slashscheme, SlashScheme); 19725 ta(Domain, localpartAccepting, Localpart); 19726 ta(Domain, groups.domain, Domain); 19727 const LocalpartAt = tt(Domain, AT); 19728 tt(Localpart, AT, LocalpartAt); 19729 tt(Scheme, AT, LocalpartAt); 19730 tt(SlashScheme, AT, LocalpartAt); 19731 const LocalpartDot = tt(Localpart, DOT); 19732 ta(LocalpartDot, localpartAccepting, Localpart); 19733 ta(LocalpartDot, groups.domain, Localpart); 19734 const EmailDomain = makeState(); 19735 ta(LocalpartAt, groups.domain, EmailDomain); 19736 ta(EmailDomain, groups.domain, EmailDomain); 19737 const EmailDomainDot = tt(EmailDomain, DOT); 19738 ta(EmailDomainDot, groups.domain, EmailDomain); 19739 const Email$1 = makeState(Email); 19740 ta(EmailDomainDot, groups.tld, Email$1); 19741 ta(EmailDomainDot, groups.utld, Email$1); 19742 tt(LocalpartAt, LOCALHOST, Email$1); 19743 const EmailDomainHyphen = tt(EmailDomain, HYPHEN); 19744 ta(EmailDomainHyphen, groups.domain, EmailDomain); 19745 ta(Email$1, groups.domain, EmailDomain); 19746 tt(Email$1, DOT, EmailDomainDot); 19747 tt(Email$1, HYPHEN, EmailDomainHyphen); 19748 const EmailColon = tt(Email$1, COLON); 19749 ta(EmailColon, groups.numeric, Email); 19750 const DomainHyphen = tt(Domain, HYPHEN); 19751 const DomainDot = tt(Domain, DOT); 19752 ta(DomainHyphen, groups.domain, Domain); 19753 ta(DomainDot, localpartAccepting, Localpart); 19754 ta(DomainDot, groups.domain, Domain); 19755 const DomainDotTld = makeState(Url); 19756 ta(DomainDot, groups.tld, DomainDotTld); 19757 ta(DomainDot, groups.utld, DomainDotTld); 19758 ta(DomainDotTld, groups.domain, Domain); 19759 ta(DomainDotTld, localpartAccepting, Localpart); 19760 tt(DomainDotTld, DOT, DomainDot); 19761 tt(DomainDotTld, HYPHEN, DomainHyphen); 19762 tt(DomainDotTld, AT, LocalpartAt); 19763 const DomainDotTldColon = tt(DomainDotTld, COLON); 19764 const DomainDotTldColonPort = makeState(Url); 19765 ta(DomainDotTldColon, groups.numeric, DomainDotTldColonPort); 19766 const Url$1 = makeState(Url); 19767 const UrlNonaccept = makeState(); 19768 ta(Url$1, qsAccepting, Url$1); 19769 ta(Url$1, qsNonAccepting, UrlNonaccept); 19770 ta(UrlNonaccept, qsAccepting, Url$1); 19771 ta(UrlNonaccept, qsNonAccepting, UrlNonaccept); 19772 tt(DomainDotTld, SLASH, Url$1); 19773 tt(DomainDotTldColonPort, SLASH, Url$1); 19774 const SchemeColon = tt(Scheme, COLON); 19775 const SlashSchemeColon = tt(SlashScheme, COLON); 19776 const SlashSchemeColonSlash = tt(SlashSchemeColon, SLASH); 19777 const UriPrefix = tt(SlashSchemeColonSlash, SLASH); 19778 ta(Scheme, groups.domain, Domain); 19779 tt(Scheme, DOT, DomainDot); 19780 tt(Scheme, HYPHEN, DomainHyphen); 19781 ta(SlashScheme, groups.domain, Domain); 19782 tt(SlashScheme, DOT, DomainDot); 19783 tt(SlashScheme, HYPHEN, DomainHyphen); 19784 ta(SchemeColon, groups.domain, Url$1); 19785 tt(SchemeColon, SLASH, Url$1); 19786 ta(UriPrefix, groups.domain, Url$1); 19787 ta(UriPrefix, qsAccepting, Url$1); 19788 tt(UriPrefix, SLASH, Url$1); 19789 const bracketPairs = [ 19790 [OPENBRACE, CLOSEBRACE], 19791 // {} 19792 [OPENBRACKET, CLOSEBRACKET], 19793 // [] 19794 [OPENPAREN, CLOSEPAREN], 19795 // () 19796 [OPENANGLEBRACKET, CLOSEANGLEBRACKET], 19797 // <> 19798 [FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN], 19799 // ï¼ï¼ 19800 [LEFTCORNERBRACKET, RIGHTCORNERBRACKET], 19801 // ãã 19802 [LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET], 19803 // ãã 19804 [FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN] 19805 // ï¼ï¼ 19806 ]; 19807 for (let i = 0; i < bracketPairs.length; i++) { 19808 const [OPEN, CLOSE] = bracketPairs[i]; 19809 const UrlOpen = tt(Url$1, OPEN); 19810 tt(UrlNonaccept, OPEN, UrlOpen); 19811 tt(UrlOpen, CLOSE, Url$1); 19812 const UrlOpenQ = makeState(Url); 19813 ta(UrlOpen, qsAccepting, UrlOpenQ); 19814 const UrlOpenSyms = makeState(); 19815 ta(UrlOpen, qsNonAccepting); 19816 ta(UrlOpenQ, qsAccepting, UrlOpenQ); 19817 ta(UrlOpenQ, qsNonAccepting, UrlOpenSyms); 19818 ta(UrlOpenSyms, qsAccepting, UrlOpenQ); 19819 ta(UrlOpenSyms, qsNonAccepting, UrlOpenSyms); 19820 tt(UrlOpenQ, CLOSE, Url$1); 19821 tt(UrlOpenSyms, CLOSE, Url$1); 19822 } 19823 tt(Start, LOCALHOST, DomainDotTld); 19824 tt(Start, NL$1, Nl); 19825 return { 19826 start: Start, 19827 tokens: tk 19828 }; 19829} 19830function run(start2, input, tokens) { 19831 let len = tokens.length; 19832 let cursor = 0; 19833 let multis = []; 19834 let textTokens = []; 19835 while (cursor < len) { 19836 let state = start2; 19837 let secondState = null; 19838 let nextState = null; 19839 let multiLength = 0; 19840 let latestAccepting = null;
19841 let sinceAccepts = -1; 19842 while (cursor < len && !(secondState = state.go(tokens[cursor].t))) { 19843 textTokens.push(tokens[cursor++]); 19844 } 19845 while (cursor < len && (nextState = secondState || state.go(tokens[cursor].t))) { 19846 secondState = null; 19847 state = nextState; 19848 if (state.accepts()) { 19849 sinceAccepts = 0; 19850 latestAccepting = state; 19851 } else if (sinceAccepts >= 0) { 19852 sinceAccepts++; 19853 } 19854 cursor++; 19855 multiLength++; 19856 } 19857 if (sinceAccepts < 0) { 19858 cursor -= multiLength; 19859 if (cursor < len) { 19860 textTokens.push(tokens[cursor]); 19861 cursor++; 19862 } 19863 } else { 19864 if (textTokens.length > 0) { 19865 multis.push(initMultiToken(Text$1, input, textTokens)); 19866 textTokens = []; 19867 } 19868 cursor -= sinceAccepts; 19869 multiLength -= sinceAccepts; 19870 const Multi = latestAccepting.t; 19871 const subtokens = tokens.slice(cursor - multiLength, cursor); 19872 multis.push(initMultiToken(Multi, input, subtokens)); 19873 } 19874 } 19875 if (textTokens.length > 0) { 19876 multis.push(initMultiToken(Text$1, input, textTokens)); 19877 } 19878 return multis; 19879} 19880function initMultiToken(Multi, input, tokens) { 19881 const startIdx = tokens[0].s; 19882 const endIdx = tokens[tokens.length - 1].e; 19883 const value = input.slice(startIdx, endIdx); 19884 return new Multi(value, tokens); 19885} 19886const warn = typeof console !== "undefined" && console && console.warn || (() => { 19887}); 19888const warnAdvice = "until manual call of linkify.init(). Register all schemes and plugins before invoking linkify the first time."; 19889const INIT = { 19890 scanner: null, 19891 parser: null, 19892 tokenQueue: [], 19893 pluginQueue: [], 19894 customSchemes: [], 19895 initialized: false 19896}; 19897function reset() { 19898 State.groups = {}; 19899 INIT.scanner = null; 19900 INIT.parser = null; 19901 INIT.tokenQueue = []; 19902 INIT.pluginQueue = []; 19903 INIT.customSchemes = []; 19904 INIT.initialized = false; 19905} 19906function registerCustomProtocol(scheme2, optionalSlashSlash) { 19907 if (optionalSlashSlash === void 0) { 19908 optionalSlashSlash = false; 19909 } 19910 if (INIT.initialized) { 19911 warn(`linkifyjs: already initialized - will not register custom scheme "${scheme2}" ${warnAdvice}`); 19912 } 19913 if (!/^[0-9a-z]+(-[0-9a-z]+)*$/.test(scheme2)) { 19914 throw new Error(`linkifyjs: incorrect scheme format. 199151. Must only contain digits, lowercase ASCII letters or "-" 199162. Cannot start or end with "-" 199173. "-" cannot repeat`); 19918 } 19919 INIT.customSchemes.push([scheme2, optionalSlashSlash]); 19920} 19921function init() { 19922 INIT.scanner = init$2(INIT.customSchemes); 19923 for (let i = 0; i < INIT.tokenQueue.length; i++) { 19924 INIT.tokenQueue[i][1]({ 19925 scanner: INIT.scanner 19926 }); 19927 } 19928 INIT.parser = init$1(INIT.scanner.tokens); 19929 for (let i = 0; i < INIT.pluginQueue.length; i++) { 19930 INIT.pluginQueue[i][1]({ 19931 scanner: INIT.scanner, 19932 parser: INIT.parser 19933 }); 19934 } 19935 INIT.initialized = true; 19936} 19937function tokenize(str) { 19938 if (!INIT.initialized) { 19939 init(); 19940 } 19941 return run(INIT.parser.start, str, run$1(INIT.scanner.start, str)); 19942} 19943function find(str, type, opts) { 19944 if (type === void 0) { 19945 type = null; 19946 } 19947 if (opts === void 0) { 19948 opts = null; 19949 } 19950 if (type && typeof type === "object") { 19951 if (opts) { 19952 throw Error(`linkifyjs: Invalid link type ${type}; must be a string`); 19953 } 19954 opts = type; 19955 type = null; 19956 } 19957 const options = new Options(opts); 19958 const tokens = tokenize(str); 19959 const filtered = []; 19960 for (let i = 0; i < tokens.length; i++) { 19961 const token = tokens[i]; 19962 if (token.isLink && (!type || token.t === type) && options.check(token)) { 19963 filtered.push(token.toFormattedObject(options)); 19964 } 19965 } 19966 return filtered; 19967} 19968function isValidLinkStructure(tokens) { 19969 if (tokens.length === 1) { 19970 return tokens[0].isLink; 19971 } 19972 if (tokens.length === 3 && tokens[1].isLink) { 19973 return ["()", "[]"].includes(tokens[0].value + tokens[2].value); 19974 } 19975 return false; 19976} 19977function autolink(options) { 19978 return new Plugin({ 19979 key: new PluginKey("autolink"), 19980 appendTransaction: (transactions, oldState, newState) => { 19981 const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc); 19982 const preventAutolink = transactions.some((transaction) => transaction.getMeta("preventAutolink")); 19983 if (!docChanges || preventAutolink) { 19984 return; 19985 } 19986 const { tr: tr2 } = newState; 19987 const transform = combineTransactionSteps(oldState.doc, [...transactions]); 19988 const changes = getChangedRanges(transform);
19989 changes.forEach(({ newRange }) => { 19990 const nodesInChangedRanges = findChildrenInRange(newState.doc, newRange, (node) => node.isTextblock); 19991 let textBlock; 19992 let textBeforeWhitespace; 19993 if (nodesInChangedRanges.length > 1) { 19994 textBlock = nodesInChangedRanges[0]; 19995 textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, textBlock.pos + textBlock.node.nodeSize, void 0, " "); 19996 } else if (nodesInChangedRanges.length && newState.doc.textBetween(newRange.from, newRange.to, " ", " ").endsWith(" ")) { 19997 textBlock = nodesInChangedRanges[0]; 19998 textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, newRange.to, void 0, " "); 19999 } 20000 if (textBlock && textBeforeWhitespace) { 20001 const wordsBeforeWhitespace = textBeforeWhitespace.split(" ").filter((s) => s !== ""); 20002 if (wordsBeforeWhitespace.length <= 0) { 20003 return false; 20004 } 20005 const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]; 20006 const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace); 20007 if (!lastWordBeforeSpace) { 20008 return false; 20009 } 20010 const linksBeforeSpace = tokenize(lastWordBeforeSpace).map((t) => t.toObject()); 20011 if (!isValidLinkStructure(linksBeforeSpace)) { 20012 return false; 20013 } 20014 linksBeforeSpace.filter((link) => link.isLink).map((link) => ({ 20015 ...link, 20016 from: lastWordAndBlockOffset + link.start + 1, 20017 to: lastWordAndBlockOffset + link.end + 1 20018 })).filter((link) => { 20019 if (!newState.schema.marks.code) { 20020 return true; 20021 } 20022 return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code); 20023 }).filter((link) => { 20024 if (options.validate) { 20025 return options.validate(link.value); 20026 } 20027 return true; 20028 }
20028).forEach((link) => { 20029 if (getMarksBetween(link.from, link.to, newState.doc).some((item) => item.mark.type === options.type)) { 20030 return; 20031 } 20032 tr2.addMark(link.from, link.to, options.type.create({ 20033 href: link.href 20034 })); 20035 }); 20036 } 20037 }); 20038 if (!tr2.steps.length) { 20039 return; 20040 } 20041 return tr2; 20042 } 20043 }); 20044} 20045function clickHandler(options) { 20046 return new Plugin({ 20047 key: new PluginKey("handleClickLink"), 20048 props: { 20049 handleClick: (view, pos, event) => { 20050 var _a, _b; 20051 if (options.whenNotEditable && view.editable) { 20052 return false; 20053 } 20054 if (event.button !== 0) { 20055 return false; 20056 } 20057 let a = event.target; 20058 const els = []; 20059 while (a.nodeName !== "DIV") { 20060 els.push(a); 20061 a = a.parentNode; 20062 } 20063 if (!els.find((value) => value.nodeName === "A")) { 20064 return false; 20065 } 20066 const attrs = getAttributes(view.state, options.type.name); 20067 const link = event.target; 20068 const href = (_a = link === null || link === void 0 ? void 0 : link.href) !== null && _a !== void 0 ? _a : attrs.href; 20069 const target = (_b = link === null || link === void 0 ? void 0 : link.target) !== null && _b !== void 0 ? _b : attrs.target; 20070 if (link && href) { 20071 window.open(href, target); 20072 return true; 20073 } 20074 return false; 20075 } 20076 } 20077 }); 20078} 20079function pasteHandler(options) { 20080 return new Plugin({ 20081 key: new PluginKey("handlePasteLink"), 20082 props: { 20083 handlePaste: (view, event, slice2) => { 20084 const { state } = view; 20085 const { selection } = state; 20086 const { empty: empty2 } = selection; 20087 if (empty2) { 20088 return false; 20089 } 20090 let textContent = ""; 20091 slice2.content.forEach((node) => { 20092 textContent += node.textContent; 20093 }); 20094 const link = find(textContent).find((item) => item.isLink && item.value === textContent); 20095 if (!textContent || !link) { 20096 return false; 20097 } 20098 options.editor.commands.setMark(options.type, { 20099 href: link.href 20100 }); 20101 return true; 20102 } 20103 } 20104 }); 20105} 20106const Link = Mark2.create({ 20107 name: "link", 20108 priority: 1e3, 20109 keepOnSplit: false, 20110 onCreate() { 20111 this.options.protocols.forEach((protocol) => { 20112 if (typeof protocol === "string") { 20113 registerCustomProtocol(protocol); 20114 return; 20115 } 20116 registerCustomProtocol(protocol.scheme, protocol.optionalSlashes); 20117 }); 20118 }, 20119 onDestroy() { 20120 reset(); 20121 }, 20122 inclusive() { 20123 return this.options.autolink; 20124 }, 20125 addOptions() { 20126 return { 20127 openOnClick: true, 20128 linkOnPaste: true, 20129 autolink: true, 20130 protocols: [], 20131 HTMLAttributes: { 20132 target: "_blank", 20133 rel: "noopener noreferrer nofollow", 20134 class: null 20135 }, 20136 validate: void 0 20137 }; 20138 }, 20139 addAttributes() { 20140 return { 20141 href: { 20142 default: null 20143 }, 20144 target: { 20145 default: this.options.HTMLAttributes.target 20146 }, 20147 rel: { 20148 default: this.options.HTMLAttributes.rel 20149 }, 20150 class: { 20151 default: this.options.HTMLAttributes.class 20152 } 20153 }; 20154 }, 20155 parseHTML() { 20156 return [{ tag: 'a[href]:not([href *= "javascript:" i])' }]; 20157 }, 20158 renderHTML({ HTMLAttributes }) { 20159 var _a; 20160 if ((_a = HTMLAttributes.href) === null || _a === void 0 ? void 0 : _a.startsWith("javascript:")) { 20161 return ["a", mergeAttributes(this.options.HTMLAttributes, { ...HTMLAttributes, href: "" }), 0]; 20162 } 20163 return ["a", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 20164 }, 20165 addCommands() { 20166 return { 20167 setLink: (attributes) => ({ chain }) => { 20168 return chain().setMark(this.name, attributes).setMeta("preventAutolink", true).run(); 20169 }, 20170 toggleLink: (attributes) => ({ chain }) => { 20171 return chain().toggleMark(this.name, attributes, { extendEmptyMarkRange: true }).setMeta("preventAutolink", true).run(); 20172 }, 20173 unsetLink: () => ({ chain }) => { 20174 return chain().unsetMark(this.name, { extendEmptyMarkRange: true }).setMeta("preventAutolink", true).run(); 20175 } 20176 }; 20177 }, 20178 addPasteRules() { 20179 return [ 20180 markPasteRule({ 20181 find: (text) => { 20182 const foundLinks = []; 20183 if (text) { 20184 const links = find(text).filter((item) => item.isLink); 20185 if (links.length) { 20186 links.forEach((link) => foundLinks.push({ 20187 text: link.value, 20188 data: { 20189 href: link.href 20190 }, 20191 index: link.start 20192 })); 20193 } 20194 } 20195 return foundLinks; 20196 }, 20197 type: this.type, 20198 getAttributes: (match) => { 20199 var _a; 20200 return { 20201 href: (_a = match.data) === null || _a === void 0 ? void 0 : _a.href 20202 }; 20203 } 20204 }) 20205 ]; 20206 }, 20207 addProseMirrorPlugins() { 20208 const plugins = []; 20209 if (this.options.autolink) { 20210 plugins.push(autolink({ 20211 type: this.type, 20212 validate: this.options.validate 20213 })); 20214 } 20215 if (this.options.openOnClick) { 20216 plugins.push(clickHandler({ 20217 type: this.type, 20218 whenNotEditable: this.options.openOnClick === "whenNotEditable" 20219 })); 20220 } 20221 if (this.options.linkOnPaste) { 20222 plugins.push(pasteHandler({ 20223 editor: this.editor, 20224 type: this.type 20225 })); 20226 } 20227 return plugins; 20228 } 20229}); 20230const inputRegex$2 = /(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/; 20231const Image = Node2.create({ 20232 name: "image", 20233 addOptions() { 20234 return { 20235 inline: false, 20236 allowBase64: false, 20237 HTMLAttributes: {} 20238 }; 20239 }, 20240 inline() { 20241 return this.options.inline; 20242 }, 20243 group() { 20244 return this.options.inline ? "inline" : "block"; 20245 }, 20246 draggable: true, 20247 addAttributes() { 20248 return { 20249 src: { 20250 default: null 20251 }, 20252 alt: { 20253 default: null 20254 }, 20255 title: { 20256 default: null 20257 } 20258 }; 20259 }, 20260 parseHTML() { 20261 return [ 20262 { 20263 tag: this.options.allowBase64 ? "img[src]" : 'img[src]:not([src^="data:"])' 20264 } 20265 ]; 20266 }, 20267 renderHTML({ HTMLAttributes }) { 20268 return ["img", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)]; 20269 }, 20270 addCommands() { 20271 return { 20272 setImage: (options) => ({ commands: commands2 }) => {
20273 return commands2.insertContent({ 20274 type: this.name, 20275 attrs: options 20276 }); 20277 } 20278 }; 20279 }, 20280 addInputRules() { 20281 return [ 20282 nodeInputRule({ 20283 find: inputRegex$2, 20284 type: this.type, 20285 getAttributes: (match) => { 20286 const [, , alt, src, title] = match; 20287 return { src, alt, title }; 20288 } 20289 }) 20290 ]; 20291 } 20292}); 20293const ListItem$2 = Node2.create({ 20294 name: "listItem", 20295 addOptions() { 20296 return { 20297 HTMLAttributes: {}, 20298 bulletListTypeName: "bulletList", 20299 orderedListTypeName: "orderedList" 20300 }; 20301 }, 20302 content: "paragraph block*", 20303 defining: true, 20304 parseHTML() { 20305 return [ 20306 { 20307 tag: "li" 20308 } 20309 ]; 20310 }, 20311 renderHTML({ HTMLAttributes }) { 20312 return ["li", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 20313 }, 20314 addKeyboardShortcuts() { 20315 return { 20316 Enter: () => this.editor.commands.splitListItem(this.name), 20317 Tab: () => this.editor.commands.sinkListItem(this.name), 20318 "Shift-Tab": () => this.editor.commands.liftListItem(this.name) 20319 }; 20320 } 20321}); 20322const TextStyle$2 = Mark2.create({ 20323 name: "textStyle", 20324 addOptions() { 20325 return { 20326 HTMLAttributes: {} 20327 }; 20328 }, 20329 parseHTML() { 20330 return [ 20331 { 20332 tag: "span", 20333 getAttrs: (element) => { 20334 const hasStyles = element.hasAttribute("style"); 20335 if (!hasStyles) { 20336 return false; 20337 } 20338 return {}; 20339 } 20340 } 20341 ]; 20342 }, 20343 renderHTML({ HTMLAttributes }) { 20344 return ["span", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 20345 }, 20346 addCommands() { 20347 return { 20348 removeEmptyTextStyle: () => ({ state, commands: commands2 }) => { 20349 const attributes = getMarkAttributes(state, this.type); 20350 const hasStyles = Object.entries(attributes).some(([, value]) => !!value); 20351 if (hasStyles) { 20352 return true; 20353 } 20354 return commands2.unsetMark(this.name); 20355 } 20356 }; 20357 } 20358}); 20359const inputRegex$1 = /^\s*([-+*])\s$/; 20360const BulletList = Node2.create({ 20361 name: "bulletList", 20362 addOptions() { 20363 return { 20364 itemTypeName: "listItem", 20365 HTMLAttributes: {}, 20366 keepMarks: false, 20367 keepAttributes: false 20368 }; 20369 }, 20370 group: "block list", 20371 content() { 20372 return `${this.options.itemTypeName}+`; 20373 }, 20374 parseHTML() { 20375 return [ 20376 { tag: "ul" } 20377 ]; 20378 }, 20379 renderHTML({ HTMLAttributes }) { 20380 return ["ul", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 20381 }, 20382 addCommands() { 20383 return { 20384 toggleBulletList: () => ({ commands: commands2, chain }) => { 20385 if (this.options.keepAttributes) { 20386 return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItem$2.name, this.editor.getAttributes(TextStyle$2.name)).run(); 20387 } 20388 return commands2.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks); 20389 } 20390 }; 20391 }, 20392 addKeyboardShortcuts() { 20393 return { 20394 "Mod-Shift-8": () => this.editor.commands.toggleBulletList() 20395 }; 20396 }, 20397 addInputRules() { 20398 let inputRule = wrappingInputRule({ 20399 find: inputRegex$1, 20400 type: this.type 20401 }); 20402 if (this.options.keepMarks || this.options.keepAttributes) { 20403 inputRule = wrappingInputRule({ 20404 find: inputRegex$1, 20405 type: this.type, 20406 keepMarks: this.options.keepMarks, 20407 keepAttributes: this.options.keepAttributes, 20408 getAttributes: () => { 20409 return this.editor.getAttributes(TextStyle$2.name); 20410 }, 20411 editor: this.editor 20412 }); 20413 } 20414 return [ 20415 inputRule 20416 ]; 20417 } 20418}); 20419const ListItem$1 = Node2.create({ 20420 name: "listItem", 20421 addOptions() { 20422 return { 20423 HTMLAttributes: {}, 20424 bulletListTypeName: "bulletList", 20425 orderedListTypeName: "orderedList" 20426 }; 20427 }, 20428 content: "paragraph block*", 20429 defining: true, 20430 parseHTML() { 20431 return [ 20432 { 20433 tag: "li" 20434 } 20435 ]; 20436 }, 20437 renderHTML({ HTMLAttributes }) { 20438 return ["li", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 20439 }, 20440 addKeyboardShortcuts() { 20441 return { 20442 Enter: () => this.editor.commands.splitListItem(this.name), 20443 Tab: () => this.editor.commands.sinkListItem(this.name), 20444 "Shift-Tab": () => this.editor.commands.liftListItem(this.name) 20445 }; 20446 } 20447}); 20448const TextStyle$1 = Mark2.create({ 20449 name: "textStyle", 20450 addOptions() { 20451 return { 20452 HTMLAttributes: {} 20453 }; 20454 }, 20455 parseHTML() { 20456 return [ 20457 { 20458 tag: "span", 20459 getAttrs: (element) => { 20460 const hasStyles = element.hasAttribute("style"); 20461 if (!hasStyles) { 20462 return false;
20463 } 20464 return {}; 20465 } 20466 } 20467 ]; 20468 }, 20469 renderHTML({ HTMLAttributes }) { 20470 return ["span", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 20471 }, 20472 addCommands() { 20473 return { 20474 removeEmptyTextStyle: () => ({ state, commands: commands2 }) => { 20475 const attributes = getMarkAttributes(state, this.type); 20476 const hasStyles = Object.entries(attributes).some(([, value]) => !!value); 20477 if (hasStyles) { 20478 return true; 20479 } 20480 return commands2.unsetMark(this.name); 20481 } 20482 }; 20483 } 20484}); 20485const inputRegex = /^(\d+)\.\s$/; 20486const OrderedList = Node2.create({ 20487 name: "orderedList", 20488 addOptions() { 20489 return { 20490 itemTypeName: "listItem", 20491 HTMLAttributes: {}, 20492 keepMarks: false, 20493 keepAttributes: false 20494 }; 20495 }, 20496 group: "block list", 20497 content() { 20498 return `${this.options.itemTypeName}+`; 20499 }, 20500 addAttributes() { 20501 return { 20502 start: { 20503 default: 1, 20504 parseHTML: (element) => { 20505 return element.hasAttribute("start") ? parseInt(element.getAttribute("start") || "", 10) : 1; 20506 } 20507 } 20508 }; 20509 }, 20510 parseHTML() { 20511 return [ 20512 { 20513 tag: "ol" 20514 } 20515 ]; 20516 }, 20517 renderHTML({ HTMLAttributes }) { 20518 const { start: start2, ...attributesWithoutStart } = HTMLAttributes; 20519 return start2 === 1 ? ["ol", mergeAttributes(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 20520 }, 20521 addCommands() { 20522 return { 20523 toggleOrderedList: () => ({ commands: commands2, chain }) => { 20524 if (this.options.keepAttributes) { 20525 return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItem$1.name, this.editor.getAttributes(TextStyle$1.name)).run(); 20526 } 20527 return commands2.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks); 20528 } 20529 }; 20530 }, 20531 addKeyboardShortcuts() { 20532 return { 20533 "Mod-Shift-7": () => this.editor.commands.toggleOrderedList() 20534 }; 20535 }, 20536 addInputRules() { 20537 let inputRule = wrappingInputRule({ 20538 find: inputRegex, 20539 type: this.type, 20540 getAttributes: (match) => ({ start: +match[1] }), 20541 joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1] 20542 }); 20543 if (this.options.keepMarks || this.options.keepAttributes) { 20544 inputRule = wrappingInputRule({ 20545 find: inputRegex, 20546 type: this.type, 20547 keepMarks: this.options.keepMarks, 20548 keepAttributes: this.options.keepAttributes, 20549 getAttributes: (match) => ({ start: +match[1], ...this.editor.getAttributes(TextStyle$1.name) }), 20550 joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1], 20551 editor: this.editor 20552 }); 20553 } 20554 return [ 20555 inputRule 20556 ]; 20557 } 20558}); 20559const ListItem = Node2.create({ 20560 name: "listItem", 20561 addOptions() { 20562 return { 20563 HTMLAttributes: {}, 20564 bulletListTypeName: "bulletList", 20565 orderedListTypeName: "orderedList" 20566 }; 20567 }, 20568 content: "paragraph block*", 20569 defining: true, 20570 parseHTML() { 20571 return [ 20572 { 20573 tag: "li" 20574 } 20575 ]; 20576 }, 20577 renderHTML({ HTMLAttributes }) { 20578 return ["li", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 20579 }, 20580 addKeyboardShortcuts() { 20581 return { 20582 Enter: () => this.editor.commands.splitListItem(this.name), 20583 Tab: () => this.editor.commands.sinkListItem(this.name), 20584 "Shift-Tab": () => this.editor.commands.liftListItem(this.name) 20585 }; 20586 } 20587}); 20588const TextStyle = Mark2.create({ 20589 name: "textStyle", 20590 addOptions() { 20591 return { 20592 HTMLAttributes: {} 20593 }; 20594 }, 20595 parseHTML() { 20596 return [ 20597 { 20598 tag: "span", 20599 getAttrs: (element) => { 20600 const hasStyles = element.hasAttribute("style"); 20601 if (!hasStyles) { 20602 return false; 20603 } 20604 return {}; 20605 } 20606 } 20607 ]; 20608 }, 20609 renderHTML({ HTMLAttributes }) { 20610 return ["span", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 20611 }, 20612 addCommands() { 20613 return { 20614 removeEmptyTextStyle: () => ({ state, commands: commands2 }) => { 20615 const attributes = getMarkAttributes(state, this.type); 20616 const hasStyles = Object.entries(attributes).some(([, value]) => !!value); 20617 if (hasStyles) { 20618 return true; 20619 } 20620 return commands2.unsetMark(this.name); 20621 } 20622 }; 20623 } 20624}); 20625const Color = Extension.create({ 20626 name: "color", 20627 addOptions() { 20628 return { 20629 types: ["textStyle"] 20630 }; 20631 }, 20632 addGlobalAttributes() { 20633 return [ 20634 { 20635 types: this.options.types, 20636 attributes: { 20637 color: { 20638 default: null, 20639 parseHTML: (element) => { 20640 var _a; 20641 return (_a = element.style.color) === null || _a === void 0 ? void 0 : _a.replace(/['"]+/g, ""); 20642 }, 20643 renderHTML: (attributes) => { 20644 if (!attributes.color) { 20645 return {}; 20646 } 20647 return { 20648 style: `color: ${attributes.color}` 20649 }; 20650 } 20651 } 20652 } 20653 } 20654 ]; 20655 }, 20656 addCommands() { 20657 return { 20658 setColor: (color) => ({ chain }) => { 20659 return chain().setMark("textStyle", { color }).run(); 20660 }, 20661 unsetColor: () => ({ chain }) => { 20662 return chain().setMark("textStyle", { color: null }).removeEmptyTextStyle().run(); 20663 } 20664 }; 20665 } 20666}); 20667const Document = Node2.create({ 20668 name: "doc", 20669 topNode: true, 20670 content: "block+" 20671}); 20672const Text = Node2.create({ 20673 name: "text", 20674 group: "inline" 20675}); 20676const Paragraph = Node2.create({ 20677 name: "paragraph", 20678 priority: 1e3, 20679 addOptions() { 20680 return { 20681 HTMLAttributes: {} 20682 }; 20683 }, 20684 group: "block", 20685 content: "inline*", 20686 parseHTML() { 20687 return [ 20688 { tag: "p" } 20689 ]; 20690 }, 20691 renderHTML({ HTMLAttributes }) { 20692 return ["p", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 20693 }, 20694 addCommands() { 20695 return { 20696 setParagraph: () => ({ commands: commands2 }) => { 20697 return commands2.setNode(this.name); 20698 } 20699 }; 20700 }, 20701 addKeyboardShortcuts() { 20702 return { 20703 "Mod-Alt-0": () => this.editor.commands.setParagraph() 20704 }; 20705 } 20706}); 20707var readFromCache; 20708var addToCache; 20709if (typeof WeakMap != "undefined") { 20710 let cache = /* @__PURE__ */ new WeakMap(); 20711 readFromCache = (key) => cache.get(key); 20712 addToCache = (key, value) => { 20713 cache.set(key, value); 20714 return value; 20715 }; 20716} else { 20717 const cache = []; 20718 const cacheSize = 10; 20719 let cachePos = 0; 20720 readFromCache = (key) => { 20721 for (let i = 0; i < cache.length; i += 2) 20722 if (cache[i] == key) 20723 return cache[i + 1]; 20724 }; 20725 addToCache = (key, value) => { 20726 if (cachePos == cacheSize) 20727 cachePos = 0; 20728 cache[cachePos++] = key; 20729 return cache[cachePos++] = value; 20730 }; 20731} 20732var TableMap = class { 20733 constructor(width, height, map2, problems) { 20734 this.width = width; 20735 this.height = height; 20736 this.map = map2; 20737 this.problems = problems; 20738 } 20739 // Find the dimensions of the cell at the given position. 20740 findCell(pos) { 20741 for (let i = 0; i < this.map.length; i++) { 20742 const curPos = this.map[i]; 20743 if (curPos != pos) 20744 continue; 20745 const left2 = i % this.width; 20746 const top2 = i / this.width | 0; 20747 let right2 = left2 + 1; 20748 let bottom2 = top2 + 1; 20749 for (let j = 1; right2 < this.width && this.map[i + j] == curPos; j++) { 20750 right2++; 20751 } 20752 for (let j = 1; bottom2 < this.height && this.map[i + this.width * j] == curPos; j++) { 20753 bottom2++; 20754 } 20755 return { left: left2, top: top2, right: right2, bottom: bottom2 }; 20756 } 20757 throw new RangeError(`No cell with offset ${pos} found`); 20758 } 20759 // Find the left side of the cell at the given position.
vendor: 4,803 bytes, lines 20760-20908
20760 colCount(pos) { 20761 for (let i = 0; i < this.map.length; i++) { 20762 if (this.map[i] == pos) { 20763 return i % this.width; 20764 } 20765 } 20766 throw new RangeError(`No cell with offset ${pos} found`); 20767 } 20768 // Find the next cell in the given direction, starting from the cell 20769 // at `pos`, if any. 20770 nextCell(pos, axis, dir) { 20771 const { left: left2, right: right2, top: top2, bottom: bottom2 } = this.findCell(pos); 20772 if (axis == "horiz") { 20773 if (dir < 0 ? left2 == 0 : right2 == this.width) 20774 return null; 20775 return this.map[top2 * this.width + (dir < 0 ? left2 - 1 : right2)]; 20776 } else { 20777 if (dir < 0 ? top2 == 0 : bottom2 == this.height) 20778 return null; 20779 return this.map[left2 + this.width * (dir < 0 ? top2 - 1 : bottom2)]; 20780 } 20781 } 20782 // Get the rectangle spanning the two given cells. 20783 rectBetween(a, b) { 20784 const { 20785 left: leftA, 20786 right: rightA, 20787 top: topA, 20788 bottom: bottomA 20789 } = this.findCell(a); 20790 const { 20791 left: leftB, 20792 right: rightB, 20793 top: topB, 20794 bottom: bottomB 20795 } = this.findCell(b); 20796 return { 20797 left: Math.min(leftA, leftB), 20798 top: Math.min(topA, topB), 20799 right: Math.max(rightA, rightB), 20800 bottom: Math.max(bottomA, bottomB) 20801 }; 20802 } 20803 // Return the position of all cells that have the top left corner in 20804 // the given rectangle. 20805 cellsInRect(rect) { 20806 const result = []; 20807 const seen = {}; 20808 for (let row = rect.top; row < rect.bottom; row++) { 20809 for (let col = rect.left; col < rect.right; col++) { 20810 const index = row * this.width + col; 20811 const pos = this.map[index]; 20812 if (seen[pos]) 20813 continue; 20814 seen[pos] = true; 20815 if (col == rect.left && col && this.map[index - 1] == pos || row == rect.top && row && this.map[index - this.width] == pos) { 20816 continue; 20817 } 20818 result.push(pos); 20819 } 20820 } 20821 return result; 20822 } 20823 // Return the position at which the cell at the given row and column 20824 // starts, or would start, if a cell started there. 20825 positionAt(row, col, table) { 20826 for (let i = 0, rowStart = 0; ; i++) { 20827 const rowEnd = rowStart + table.child(i).nodeSize; 20828 if (i == row) { 20829 let index = col + row * this.width; 20830 const rowEndIndex = (row + 1) * this.width; 20831 while (index < rowEndIndex && this.map[index] < rowStart) 20832 index++; 20833 return index == rowEndIndex ? rowEnd - 1 : this.map[index]; 20834 } 20835 rowStart = rowEnd; 20836 } 20837 } 20838 // Find the table map for the given table node. 20839 static get(table) { 20840 return readFromCache(table) || addToCache(table, computeMap(table)); 20841 } 20842}; 20843function computeMap(table) { 20844 if (table.type.spec.tableRole != "table") 20845 throw new RangeError("Not a table node: " + table.type.name); 20846 const width = findWidth(table), height = table.childCount; 20847 const map2 = []; 20848 let mapPos = 0; 20849 let problems = null; 20850 const colWidths = []; 20851 for (let i = 0, e = width * height; i < e; i++) 20852 map2[i] = 0; 20853 for (let row = 0, pos = 0; row < height; row++) { 20854 const rowNode = table.child(row); 20855 pos++; 20856 for (let i = 0; ; i++) { 20857 while (mapPos < map2.length && map2[mapPos] != 0) 20858 mapPos++; 20859 if (i == rowNode.childCount) 20860 break; 20861 const cellNode = rowNode.child(i); 20862 const { colspan, rowspan, colwidth } = cellNode.attrs; 20863 for (let h2 = 0; h2 < rowspan; h2++) { 20864 if (h2 + row >= height) { 20865 (problems || (problems = [])).push({ 20866 type: "overlong_rowspan", 20867 pos, 20868 n: rowspan - h2 20869 }); 20870 break; 20871 } 20872 const start2 = mapPos + h2 * width; 20873 for (let w = 0; w < colspan; w++) { 20874 if (map2[start2 + w] == 0) 20875 map2[start2 + w] = pos; 20876 else 20877 (problems || (problems = [])).push({ 20878 type: "collision", 20879 row, 20880 pos, 20881 n: colspan - w 20882 }); 20883 const colW = colwidth && colwidth[w]; 20884 if (colW) { 20885 const widthIndex = (start2 + w) % width * 2, prev = colWidths[widthIndex]; 20886 if (prev == null || prev != colW && colWidths[widthIndex + 1] == 1) { 20887 colWidths[widthIndex] = colW; 20888 colWidths[widthIndex + 1] = 1; 20889 } else if (prev == colW) { 20890 colWidths[widthIndex + 1]++; 20891 } 20892 } 20893 } 20894 } 20895 mapPos += colspan; 20896 pos += cellNode.nodeSize; 20897 } 20898 const expectedPos = (row + 1) * width; 20899 let missing = 0; 20900 while (mapPos < expectedPos) 20901 if (map2[mapPos++] == 0) 20902 missing++; 20903 if (missing) 20904 (problems || (problems = [])).push({ type: "missing", row, n: missing }); 20905 pos++; 20906 } 20907 const tableMap = new TableMap(width, height, map2, problems); 20908 let badWidths = false;
20909 for (let i = 0; !badWidths && i < colWidths.length; i += 2) 20910 if (colWidths[i] != null && colWidths[i + 1] < height) 20911 badWidths = true; 20912 if (badWidths) 20913 findBadColWidths(tableMap, colWidths, table); 20914 return tableMap; 20915} 20916function findWidth(table) { 20917 let width = -1; 20918 let hasRowSpan = false; 20919 for (let row = 0; row < table.childCount; row++) { 20920 const rowNode = table.child(row); 20921 let rowWidth = 0; 20922 if (hasRowSpan) 20923 for (let j = 0; j < row; j++) { 20924 const prevRow = table.child(j); 20925 for (let i = 0; i < prevRow.childCount; i++) { 20926 const cell = prevRow.child(i); 20927 if (j + cell.attrs.rowspan > row) 20928 rowWidth += cell.attrs.colspan; 20929 } 20930 } 20931 for (let i = 0; i < rowNode.childCount; i++) { 20932 const cell = rowNode.child(i); 20933 rowWidth += cell.attrs.colspan; 20934 if (cell.attrs.rowspan > 1) 20935 hasRowSpan = true; 20936 } 20937 if (width == -1) 20938 width = rowWidth; 20939 else if (width != rowWidth) 20940 width = Math.max(width, rowWidth); 20941 } 20942 return width; 20943} 20944function findBadColWidths(map2, colWidths, table) { 20945 if (!map2.problems) 20946 map2.problems = []; 20947 const seen = {}; 20948 for (let i = 0; i < map2.map.length; i++) { 20949 const pos = map2.map[i]; 20950 if (seen[pos]) 20951 continue; 20952 seen[pos] = true; 20953 const node = table.nodeAt(pos); 20954 if (!node) { 20955 throw new RangeError(`No cell with offset ${pos} found`); 20956 } 20957 let updated = null; 20958 const attrs = node.attrs; 20959 for (let j = 0; j < attrs.colspan; j++) { 20960 const col = (i + j) % map2.width; 20961 const colWidth = colWidths[col * 2]; 20962 if (colWidth != null && (!attrs.colwidth || attrs.colwidth[j] != colWidth)) 20963 (updated || (updated = freshColWidth(attrs)))[j] = colWidth; 20964 } 20965 if (updated) 20966 map2.problems.unshift({ 20967 type: "colwidth mismatch", 20968 pos, 20969 colwidth: updated 20970 }); 20971 } 20972} 20973function freshColWidth(attrs) { 20974 if (attrs.colwidth) 20975 return attrs.colwidth.slice(); 20976 const result = []; 20977 for (let i = 0; i < attrs.colspan; i++) 20978 result.push(0); 20979 return result; 20980} 20981function tableNodeTypes(schema) { 20982 let result = schema.cached.tableNodeTypes; 20983 if (!result) { 20984 result = schema.cached.tableNodeTypes = {}; 20985 for (const name in schema.nodes) { 20986 const type = schema.nodes[name], role = type.spec.tableRole; 20987 if (role) 20988 result[role] = type; 20989 } 20990 } 20991 return result; 20992} 20993var tableEditingKey = new PluginKey("selectingCells"); 20994function cellAround($pos) { 20995 for (let d = $pos.depth - 1; d > 0; d--)
20996 if ($pos.node(d).type.spec.tableRole == "row") 20997 return $pos.node(0).resolve($pos.before(d + 1)); 20998 return null; 20999} 21000function cellWrapping($pos) { 21001 for (let d = $pos.depth; d > 0; d--) { 21002 const role = $pos.node(d).type.spec.tableRole; 21003 if (role === "cell" || role === "header_cell") 21004 return $pos.node(d); 21005 } 21006 return null; 21007} 21008function isInTable(state) { 21009 const $head = state.selection.$head; 21010 for (let d = $head.depth; d > 0; d--) 21011 if ($head.node(d).type.spec.tableRole == "row") 21012 return true; 21013 return false; 21014} 21015function selectionCell(state) { 21016 const sel = state.selection; 21017 if ("$anchorCell" in sel && sel.$anchorCell) { 21018 return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell; 21019 } else if ("node" in sel && sel.node && sel.node.type.spec.tableRole == "cell") { 21020 return sel.$anchor; 21021 } 21022 const $cell = cellAround(sel.$head) || cellNear(sel.$head); 21023 if ($cell) { 21024 return $cell; 21025 } 21026 throw new RangeError(`No cell found around position ${sel.head}`); 21027} 21028function cellNear($pos) { 21029 for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) { 21030 const role = after.type.spec.tableRole; 21031 if (role == "cell" || role == "header_cell") 21032 return $pos.doc.resolve(pos); 21033 } 21034 for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) { 21035 const role = before.type.spec.tableRole; 21036 if (role == "cell" || role == "header_cell") 21037 return $pos.doc.resolve(pos - before.nodeSize); 21038 } 21039} 21040function pointsAtCell($pos) { 21041 return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter; 21042} 21043function moveCellForward($pos) { 21044 return $pos.node(0).resolve($pos.pos + $pos.nodeAfter.nodeSize); 21045} 21046function inSameTable($cellA, $cellB) { 21047 return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1); 21048} 21049function nextCell($pos, axis, dir) { 21050 const table = $pos.node(-1); 21051 const map2 = TableMap.get(table); 21052 const tableStart = $pos.start(-1); 21053 const moved = map2.nextCell($pos.pos - tableStart, axis, dir); 21054 return moved == null ? null : $pos.node(0).resolve(tableStart + moved); 21055} 21056function removeColSpan(attrs, pos, n = 1) { 21057 const result = { ...attrs, colspan: attrs.colspan - n }; 21058 if (result.colwidth) { 21059 result.colwidth = result.colwidth.slice(); 21060 result.colwidth.splice(pos, n); 21061 if (!result.colwidth.some((w) => w > 0)) 21062 result.colwidth = null; 21063 } 21064 return result; 21065} 21066function addColSpan(attrs, pos, n = 1) { 21067 const result = { ...attrs, colspan: attrs.colspan + n }; 21068 if (result.colwidth) { 21069 result.colwidth = result.colwidth.slice(); 21070 for (let i = 0; i < n; i++) 21071 result.colwidth.splice(pos, 0, 0); 21072 } 21073 return result; 21074} 21075function columnIsHeader(map2, table, col) { 21076 const headerCell = tableNodeTypes(table.type.schema).header_cell; 21077 for (let row = 0; row < map2.height; row++) 21078 if (table.nodeAt(map2.map[col + row * map2.width]).type != headerCell) 21079 return false; 21080 return true; 21081} 21082var CellSelection = class _CellSelection extends Selection { 21083 // A table selection is identified by its anchor and head cells. The 21084 // positions given to this constructor should point _before_ two 21085 // cells in the same table. They may be the same, to select a single 21086 // cell. 21087 constructor($anchorCell, $headCell = $anchorCell) { 21088 const table = $anchorCell.node(-1); 21089 const map2 = TableMap.get(table); 21090 const tableStart = $anchorCell.start(-1); 21091 const rect = map2.rectBetween( 21092 $anchorCell.pos - tableStart, 21093 $headCell.pos - tableStart 21094 ); 21095 const doc2 = $anchorCell.node(0); 21096 const cells = map2.cellsInRect(rect).filter((p) => p != $headCell.pos - tableStart); 21097 cells.unshift($headCell.pos - tableStart); 21098 const ranges = cells.map((pos) => { 21099 const cell = table.nodeAt(pos); 21100 if (!cell) { 21101 throw RangeError(`No cell with offset ${pos} found`); 21102 } 21103 const from2 = tableStart + pos + 1; 21104 return new SelectionRange( 21105 doc2.resolve(from2), 21106 doc2.resolve(from2 + cell.content.size) 21107 ); 21108 }); 21109 super(ranges[0].$from, ranges[0].$to, ranges); 21110 this.$anchorCell = $anchorCell; 21111 this.$headCell = $headCell; 21112 } 21113 map(doc2, mapping) { 21114 const $anchorCell = doc2.resolve(mapping.map(this.$anchorCell.pos)); 21115 const $headCell = doc2.resolve(mapping.map(this.$headCell.pos)); 21116 if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) { 21117 const tableChanged = this.$anchorCell.node(-1) != $anchorCell.node(-1); 21118 if (tableChanged && this.isRowSelection()) 21119 return _CellSelection.rowSelection($anchorCell, $headCell); 21120 else if (tableChanged && this.isColSelection()) 21121 return _CellSelection.colSelection($anchorCell, $headCell); 21122 else 21123 return new _CellSelection($anchorCell, $headCell); 21124 } 21125 return TextSelection.between($anchorCell, $headCell); 21126 } 21127 // Returns a rectangular slice of table rows containing the selected 21128 // cells. 21129 content() { 21130 const table = this.$anchorCell.node(-1); 21131 const map2 = TableMap.get(table); 21132 const tableStart = this.$anchorCell.start(-1); 21133 const rect = map2.rectBetween( 21134 this.$anchorCell.pos - tableStart, 21135 this.$headCell.pos - tableStart 21136 ); 21137 const seen = {}; 21138 const rows = []; 21139 for (let row = rect.top; row < rect.bottom; row++) { 21140 const rowContent = []; 21141 for (let index = row * map2.width + rect.left, col = rect.left; col < rect.right; col++, index++) { 21142 const pos = map2.map[index]; 21143 if (seen[pos]) 21144 continue; 21145 seen[pos] = true; 21146 const cellRect = map2.findCell(pos); 21147 let cell = table.nodeAt(pos); 21148 if (!cell) { 21149 throw RangeError(`No cell with offset ${pos} found`); 21150 } 21151 const extraLeft = rect.left - cellRect.left; 21152 const extraRight = cellRect.right - rect.right; 21153 if (extraLeft > 0 || extraRight > 0) { 21154 let attrs = cell.attrs; 21155 if (extraLeft > 0) { 21156 attrs = removeColSpan(attrs, 0, extraLeft); 21157 } 21158 if (extraRight > 0) { 21159 attrs = removeColSpan( 21160 attrs, 21161 attrs.colspan - extraRight, 21162 extraRight 21163 ); 21164 } 21165 if (cellRect.left < rect.left) { 21166 cell = cell.type.createAndFill(attrs); 21167 if (!cell) { 21168 throw RangeError( 21169 `Could not create cell with attrs ${JSON.stringify(attrs)}` 21170 ); 21171 } 21172 } else { 21173 cell = cell.type.create(attrs, cell.content); 21174 } 21175 } 21176 if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) { 21177 const attrs = { 21178 ...cell.attrs, 21179 rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top) 21180 }; 21181 if (cellRect.top < rect.top) { 21182 cell = cell.type.createAndFill(attrs); 21183 } else { 21184 cell = cell.type.create(attrs, cell.content); 21185 } 21186 } 21187 rowContent.push(cell); 21188 } 21189 rows.push(table.child(row).copy(Fragment.from(rowContent))); 21190 } 21191 const fragment = this.isColSelection() && this.isRowSelection() ? table : rows; 21192 return new Slice(Fragment.from(fragment), 1, 1); 21193 }
vendor: 4,773 bytes, lines 21194-21317
21194 replace(tr2, content = Slice.empty) { 21195 const mapFrom = tr2.steps.length, ranges = this.ranges; 21196 for (let i = 0; i < ranges.length; i++) { 21197 const { $from, $to } = ranges[i], mapping = tr2.mapping.slice(mapFrom); 21198 tr2.replace( 21199 mapping.map($from.pos), 21200 mapping.map($to.pos), 21201 i ? Slice.empty : content 21202 ); 21203 } 21204 const sel = Selection.findFrom( 21205 tr2.doc.resolve(tr2.mapping.slice(mapFrom).map(this.to)), 21206 -1 21207 ); 21208 if (sel) 21209 tr2.setSelection(sel); 21210 } 21211 replaceWith(tr2, node) { 21212 this.replace(tr2, new Slice(Fragment.from(node), 0, 0)); 21213 } 21214 forEachCell(f) { 21215 const table = this.$anchorCell.node(-1); 21216 const map2 = TableMap.get(table); 21217 const tableStart = this.$anchorCell.start(-1); 21218 const cells = map2.cellsInRect( 21219 map2.rectBetween( 21220 this.$anchorCell.pos - tableStart, 21221 this.$headCell.pos - tableStart 21222 ) 21223 ); 21224 for (let i = 0; i < cells.length; i++) { 21225 f(table.nodeAt(cells[i]), tableStart + cells[i]); 21226 } 21227 } 21228 // True if this selection goes all the way from the top to the 21229 // bottom of the table. 21230 isColSelection() { 21231 const anchorTop = this.$anchorCell.index(-1); 21232 const headTop = this.$headCell.index(-1); 21233 if (Math.min(anchorTop, headTop) > 0) 21234 return false; 21235 const anchorBottom = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan; 21236 const headBottom = headTop + this.$headCell.nodeAfter.attrs.rowspan; 21237 return Math.max(anchorBottom, headBottom) == this.$headCell.node(-1).childCount; 21238 } 21239 // Returns the smallest column selection that covers the given anchor 21240 // and head cell. 21241 static colSelection($anchorCell, $headCell = $anchorCell) { 21242 const table = $anchorCell.node(-1); 21243 const map2 = TableMap.get(table); 21244 const tableStart = $anchorCell.start(-1); 21245 const anchorRect = map2.findCell($anchorCell.pos - tableStart); 21246 const headRect = map2.findCell($headCell.pos - tableStart); 21247 const doc2 = $anchorCell.node(0); 21248 if (anchorRect.top <= headRect.top) { 21249 if (anchorRect.top > 0) 21250 $anchorCell = doc2.resolve(tableStart + map2.map[anchorRect.left]); 21251 if (headRect.bottom < map2.height) 21252 $headCell = doc2.resolve( 21253 tableStart + map2.map[map2.width * (map2.height - 1) + headRect.right - 1] 21254 ); 21255 } else { 21256 if (headRect.top > 0) 21257 $headCell = doc2.resolve(tableStart + map2.map[headRect.left]); 21258 if (anchorRect.bottom < map2.height) 21259 $anchorCell = doc2.resolve( 21260 tableStart + map2.map[map2.width * (map2.height - 1) + anchorRect.right - 1] 21261 ); 21262 } 21263 return new _CellSelection($anchorCell, $headCell); 21264 } 21265 // True if this selection goes all the way from the left to the 21266 // right of the table. 21267 isRowSelection() { 21268 const table = this.$anchorCell.node(-1); 21269 const map2 = TableMap.get(table); 21270 const tableStart = this.$anchorCell.start(-1); 21271 const anchorLeft = map2.colCount(this.$anchorCell.pos - tableStart); 21272 const headLeft = map2.colCount(this.$headCell.pos - tableStart); 21273 if (Math.min(anchorLeft, headLeft) > 0) 21274 return false; 21275 const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan; 21276 const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan; 21277 return Math.max(anchorRight, headRight) == map2.width; 21278 } 21279 eq(other) { 21280 return other instanceof _CellSelection && other.$anchorCell.pos == this.$anchorCell.pos && other.$headCell.pos == this.$headCell.pos; 21281 } 21282 // Returns the smallest row selection that covers the given anchor 21283 // and head cell. 21284 static rowSelection($anchorCell, $headCell = $anchorCell) { 21285 const table = $anchorCell.node(-1); 21286 const map2 = TableMap.get(table); 21287 const tableStart = $anchorCell.start(-1); 21288 const anchorRect = map2.findCell($anchorCell.pos - tableStart); 21289 const headRect = map2.findCell($headCell.pos - tableStart); 21290 const doc2 = $anchorCell.node(0); 21291 if (anchorRect.left <= headRect.left) { 21292 if (anchorRect.left > 0) 21293 $anchorCell = doc2.resolve( 21294 tableStart + map2.map[anchorRect.top * map2.width] 21295 ); 21296 if (headRect.right < map2.width) 21297 $headCell = doc2.resolve( 21298 tableStart + map2.map[map2.width * (headRect.top + 1) - 1] 21299 ); 21300 } else { 21301 if (headRect.left > 0) 21302 $headCell = doc2.resolve(tableStart + map2.map[headRect.top * map2.width]); 21303 if (anchorRect.right < map2.width) 21304 $anchorCell = doc2.resolve( 21305 tableStart + map2.map[map2.width * (anchorRect.top + 1) - 1] 21306 ); 21307 } 21308 return new _CellSelection($anchorCell, $headCell); 21309 } 21310 toJSON() { 21311 return { 21312 type: "cell", 21313 anchor: this.$anchorCell.pos, 21314 head: this.$headCell.pos 21315 }; 21316 } 21317 static fromJSON(doc2, json) {
21318 return new _CellSelection(doc2.resolve(json.anchor), doc2.resolve(json.head)); 21319 } 21320 static create(doc2, anchorCell, headCell = anchorCell) { 21321 return new _CellSelection(doc2.resolve(anchorCell), doc2.resolve(headCell)); 21322 } 21323 getBookmark() { 21324 return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos); 21325 } 21326}; 21327CellSelection.prototype.visible = false; 21328Selection.jsonID("cell", CellSelection); 21329var CellBookmark = class _CellBookmark { 21330 constructor(anchor, head) { 21331 this.anchor = anchor; 21332 this.head = head; 21333 } 21334 map(mapping) { 21335 return new _CellBookmark(mapping.map(this.anchor), mapping.map(this.head)); 21336 } 21337 resolve(doc2) { 21338 const $anchorCell = doc2.resolve(this.anchor), $headCell = doc2.resolve(this.head); 21339 if ($anchorCell.parent.type.spec.tableRole == "row" && $headCell.parent.type.spec.tableRole == "row" && $anchorCell.index() < $anchorCell.parent.childCount && $headCell.index() < $headCell.parent.childCount && inSameTable($anchorCell, $headCell)) 21340 return new CellSelection($anchorCell, $headCell); 21341 else 21342 return Selection.near($headCell, 1); 21343 } 21344}; 21345function drawCellSelection(state) { 21346 if (!(state.selection instanceof CellSelection)) 21347 return null; 21348 const cells = []; 21349 state.selection.forEachCell((node, pos) => { 21350 cells.push( 21351 Decoration.node(pos, pos + node.nodeSize, { class: "selectedCell" }) 21352 ); 21353 }); 21354 return DecorationSet.create(state.doc, cells); 21355} 21356function isCellBoundarySelection({ $from, $to }) { 21357 if ($from.pos == $to.pos || $from.pos < $from.pos - 6) 21358 return false; 21359 let afterFrom = $from.pos; 21360 let beforeTo = $to.pos; 21361 let depth = $from.depth; 21362 for (; depth >= 0; depth--, afterFrom++) 21363 if ($from.after(depth + 1) < $from.end(depth)) 21364 break; 21365 for (let d = $to.depth; d >= 0; d--, beforeTo--) 21366 if ($to.before(d + 1) > $to.start(d)) 21367 break; 21368 return afterFrom == beforeTo && /row|table/.test($from.node(depth).type.spec.tableRole); 21369} 21370function isTextSelectionAcrossCells({ $from, $to }) { 21371 let fromCellBoundaryNode; 21372 let toCellBoundaryNode; 21373 for (let i = $from.depth; i > 0; i--) { 21374 const node = $from.node(i); 21375 if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") { 21376 fromCellBoundaryNode = node; 21377 break; 21378 } 21379 } 21380 for (let i = $to.depth; i > 0; i--) { 21381 const node = $to.node(i); 21382 if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") { 21383 toCellBoundaryNode = node; 21384 break; 21385 } 21386 } 21387 return fromCellBoundaryNode !== toCellBoundaryNode && $to.parentOffset === 0; 21388} 21389function normalizeSelection(state, tr2, allowTableNodeSelection) { 21390 const sel = (tr2 || state).selection; 21391 const doc2 = (tr2 || state).doc; 21392 let normalize2; 21393 let role; 21394 if (sel instanceof NodeSelection && (role = sel.node.type.spec.tableRole)) { 21395 if (role == "cell" || role == "header_cell") { 21396 normalize2 = CellSelection.create(doc2, sel.from); 21397 } else if (role == "row") { 21398 const $cell = doc2.resolve(sel.from + 1); 21399 normalize2 = CellSelection.rowSelection($cell, $cell); 21400 } else if (!allowTableNodeSelection) { 21401 const map2 = TableMap.get(sel.node); 21402 const start2 = sel.from + 1; 21403 const lastCell = start2 + map2.map[map2.width * map2.height - 1]; 21404 normalize2 = CellSelection.create(doc2, start2 + 1, lastCell); 21405 } 21406 } else if (sel instanceof TextSelection && isCellBoundarySelection(sel)) { 21407 normalize2 = TextSelection.create(doc2, sel.from); 21408 } else if (sel instanceof TextSelection && isTextSelectionAcrossCells(sel)) { 21409 normalize2 = TextSelection.create(doc2, sel.$from.start(), sel.$from.end()); 21410 } 21411 if (normalize2) 21412 (tr2 || (tr2 = state.tr)).setSelection(normalize2); 21413 return tr2; 21414} 21415var fixTablesKey = new PluginKey("fix-tables"); 21416function changedDescendants(old, cur, offset2, f) { 21417 const oldSize = old.childCount, curSize = cur.childCount; 21418 outer: 21419 for (let i = 0, j = 0; i < curSize; i++) { 21420 const child = cur.child(i); 21421 for (let scan = j, e = Math.min(oldSize, i + 3); scan < e; scan++) { 21422 if (old.child(scan) == child) { 21423 j = scan + 1; 21424 offset2 += child.nodeSize; 21425 continue outer; 21426 } 21427 } 21428 f(child, offset2); 21429 if (j < oldSize && old.child(j).sameMarkup(child)) 21430 changedDescendants(old.child(j), child, offset2 + 1, f); 21431 else 21432 child.nodesBetween(0, child.content.size, f, offset2 + 1); 21433 offset2 += child.nodeSize; 21434 } 21435} 21436function fixTables(state, oldState) { 21437 let tr2;
vendor: 12,044 bytes, lines 21438-21799
21438 const check = (node, pos) => { 21439 if (node.type.spec.tableRole == "table") 21440 tr2 = fixTable(state, node, pos, tr2); 21441 }; 21442 if (!oldState) 21443 state.doc.descendants(check); 21444 else if (oldState.doc != state.doc) 21445 changedDescendants(oldState.doc, state.doc, 0, check); 21446 return tr2; 21447} 21448function fixTable(state, table, tablePos, tr2) { 21449 const map2 = TableMap.get(table); 21450 if (!map2.problems) 21451 return tr2; 21452 if (!tr2) 21453 tr2 = state.tr; 21454 const mustAdd = []; 21455 for (let i = 0; i < map2.height; i++) 21456 mustAdd.push(0); 21457 for (let i = 0; i < map2.problems.length; i++) { 21458 const prob = map2.problems[i]; 21459 if (prob.type == "collision") { 21460 const cell = table.nodeAt(prob.pos); 21461 if (!cell) 21462 continue; 21463 const attrs = cell.attrs; 21464 for (let j = 0; j < attrs.rowspan; j++) 21465 mustAdd[prob.row + j] += prob.n; 21466 tr2.setNodeMarkup( 21467 tr2.mapping.map(tablePos + 1 + prob.pos), 21468 null, 21469 removeColSpan(attrs, attrs.colspan - prob.n, prob.n) 21470 ); 21471 } else if (prob.type == "missing") { 21472 mustAdd[prob.row] += prob.n; 21473 } else if (prob.type == "overlong_rowspan") { 21474 const cell = table.nodeAt(prob.pos); 21475 if (!cell) 21476 continue; 21477 tr2.setNodeMarkup(tr2.mapping.map(tablePos + 1 + prob.pos), null, { 21478 ...cell.attrs, 21479 rowspan: cell.attrs.rowspan - prob.n 21480 }); 21481 } else if (prob.type == "colwidth mismatch") { 21482 const cell = table.nodeAt(prob.pos); 21483 if (!cell) 21484 continue; 21485 tr2.setNodeMarkup(tr2.mapping.map(tablePos + 1 + prob.pos), null, { 21486 ...cell.attrs, 21487 colwidth: prob.colwidth 21488 }); 21489 } 21490 } 21491 let first2, last; 21492 for (let i = 0; i < mustAdd.length; i++) 21493 if (mustAdd[i]) { 21494 if (first2 == null) 21495 first2 = i; 21496 last = i; 21497 } 21498 for (let i = 0, pos = tablePos + 1; i < map2.height; i++) { 21499 const row = table.child(i); 21500 const end2 = pos + row.nodeSize; 21501 const add = mustAdd[i]; 21502 if (add > 0) { 21503 let role = "cell"; 21504 if (row.firstChild) { 21505 role = row.firstChild.type.spec.tableRole; 21506 } 21507 const nodes = []; 21508 for (let j = 0; j < add; j++) { 21509 const node = tableNodeTypes(state.schema)[role].createAndFill(); 21510 if (node) 21511 nodes.push(node); 21512 } 21513 const side = (i == 0 || first2 == i - 1) && last == i ? pos + 1 : end2 - 1; 21514 tr2.insert(tr2.mapping.map(side), nodes); 21515 } 21516 pos = end2; 21517 } 21518 return tr2.setMeta(fixTablesKey, { fixTables: true }); 21519} 21520function pastedCells(slice2) { 21521 if (!slice2.size) 21522 return null; 21523 let { content, openStart, openEnd } = slice2; 21524 while (content.childCount == 1 && (openStart > 0 && openEnd > 0 || content.child(0).type.spec.tableRole == "table")) { 21525 openStart--; 21526 openEnd--; 21527 content = content.child(0).content; 21528 } 21529 const first2 = content.child(0); 21530 const role = first2.type.spec.tableRole; 21531 const schema = first2.type.schema, rows = []; 21532 if (role == "row") { 21533 for (let i = 0; i < content.childCount; i++) { 21534 let cells = content.child(i).content; 21535 const left2 = i ? 0 : Math.max(0, openStart - 1); 21536 const right2 = i < content.childCount - 1 ? 0 : Math.max(0, openEnd - 1); 21537 if (left2 || right2) 21538 cells = fitSlice( 21539 tableNodeTypes(schema).row, 21540 new Slice(cells, left2, right2) 21541 ).content; 21542 rows.push(cells); 21543 } 21544 } else if (role == "cell" || role == "header_cell") { 21545 rows.push( 21546 openStart || openEnd ? fitSlice( 21547 tableNodeTypes(schema).row, 21548 new Slice(content, openStart, openEnd) 21549 ).content : content 21550 ); 21551 } else { 21552 return null; 21553 } 21554 return ensureRectangular(schema, rows); 21555} 21556function ensureRectangular(schema, rows) { 21557 const widths = []; 21558 for (let i = 0; i < rows.length; i++) { 21559 const row = rows[i]; 21560 for (let j = row.childCount - 1; j >= 0; j--) { 21561 const { rowspan, colspan } = row.child(j).attrs; 21562 for (let r = i; r < i + rowspan; r++) 21563 widths[r] = (widths[r] || 0) + colspan; 21564 } 21565 } 21566 let width = 0; 21567 for (let r = 0; r < widths.length; r++) 21568 width = Math.max(width, widths[r]); 21569 for (let r = 0; r < widths.length; r++) { 21570 if (r >= rows.length) 21571 rows.push(Fragment.empty); 21572 if (widths[r] < width) { 21573 const empty2 = tableNodeTypes(schema).cell.createAndFill(); 21574 const cells = []; 21575 for (let i = widths[r]; i < width; i++) { 21576 cells.push(empty2); 21577 } 21578 rows[r] = rows[r].append(Fragment.from(cells)); 21579 } 21580 } 21581 return { height: rows.length, width, rows }; 21582} 21583function fitSlice(nodeType, slice2) { 21584 const node = nodeType.createAndFill(); 21585 const tr2 = new Transform(node).replace(0, node.content.size, slice2); 21586 return tr2.doc; 21587} 21588function clipCells({ width, height, rows }, newWidth, newHeight) { 21589 if (width != newWidth) { 21590 const added = []; 21591 const newRows = []; 21592 for (let row = 0; row < rows.length; row++) { 21593 const frag = rows[row], cells = []; 21594 for (let col = added[row] || 0, i = 0; col < newWidth; i++) { 21595 let cell = frag.child(i % frag.childCount); 21596 if (col + cell.attrs.colspan > newWidth) 21597 cell = cell.type.createChecked( 21598 removeColSpan( 21599 cell.attrs, 21600 cell.attrs.colspan, 21601 col + cell.attrs.colspan - newWidth 21602 ), 21603 cell.content 21604 ); 21605 cells.push(cell); 21606 col += cell.attrs.colspan; 21607 for (let j = 1; j < cell.attrs.rowspan; j++) 21608 added[row + j] = (added[row + j] || 0) + cell.attrs.colspan; 21609 } 21610 newRows.push(Fragment.from(cells)); 21611 } 21612 rows = newRows; 21613 width = newWidth; 21614 } 21615 if (height != newHeight) { 21616 const newRows = []; 21617 for (let row = 0, i = 0; row < newHeight; row++, i++) { 21618 const cells = [], source = rows[i % height]; 21619 for (let j = 0; j < source.childCount; j++) { 21620 let cell = source.child(j); 21621 if (row + cell.attrs.rowspan > newHeight) 21622 cell = cell.type.create( 21623 { 21624 ...cell.attrs, 21625 rowspan: Math.max(1, newHeight - cell.attrs.rowspan) 21626 }, 21627 cell.content 21628 ); 21629 cells.push(cell); 21630 } 21631 newRows.push(Fragment.from(cells)); 21632 } 21633 rows = newRows; 21634 height = newHeight; 21635 } 21636 return { width, height, rows }; 21637} 21638function growTable(tr2, map2, table, start2, width, height, mapFrom) { 21639 const schema = tr2.doc.type.schema; 21640 const types = tableNodeTypes(schema); 21641 let empty2; 21642 let emptyHead; 21643 if (width > map2.width) { 21644 for (let row = 0, rowEnd = 0; row < map2.height; row++) { 21645 const rowNode = table.child(row); 21646 rowEnd += rowNode.nodeSize; 21647 const cells = []; 21648 let add; 21649 if (rowNode.lastChild == null || rowNode.lastChild.type == types.cell) 21650 add = empty2 || (empty2 = types.cell.createAndFill()); 21651 else 21652 add = emptyHead || (emptyHead = types.header_cell.createAndFill()); 21653 for (let i = map2.width; i < width; i++) 21654 cells.push(add); 21655 tr2.insert(tr2.mapping.slice(mapFrom).map(rowEnd - 1 + start2), cells); 21656 } 21657 } 21658 if (height > map2.height) { 21659 const cells = []; 21660 for (let i = 0, start22 = (map2.height - 1) * map2.width; i < Math.max(map2.width, width); i++) { 21661 const header = i >= map2.width ? false : table.nodeAt(map2.map[start22 + i]).type == types.header_cell; 21662 cells.push( 21663 header ? emptyHead || (emptyHead = types.header_cell.createAndFill()) : empty2 || (empty2 = types.cell.createAndFill()) 21664 ); 21665 } 21666 const emptyRow = types.row.create(null, Fragment.from(cells)), rows = []; 21667 for (let i = map2.height; i < height; i++) 21668 rows.push(emptyRow); 21669 tr2.insert(tr2.mapping.slice(mapFrom).map(start2 + table.nodeSize - 2), rows); 21670 } 21671 return !!(empty2 || emptyHead); 21672} 21673function isolateHorizontal(tr2, map2, table, start2, left2, right2, top2, mapFrom) { 21674 if (top2 == 0 || top2 == map2.height) 21675 return false; 21676 let found2 = false; 21677 for (let col = left2; col < right2; col++) { 21678 const index = top2 * map2.width + col, pos = map2.map[index]; 21679 if (map2.map[index - map2.width] == pos) { 21680 found2 = true; 21681 const cell = table.nodeAt(pos); 21682 const { top: cellTop, left: cellLeft } = map2.findCell(pos); 21683 tr2.setNodeMarkup(tr2.mapping.slice(mapFrom).map(pos + start2), null, { 21684 ...cell.attrs, 21685 rowspan: top2 - cellTop 21686 }); 21687 tr2.insert( 21688 tr2.mapping.slice(mapFrom).map(map2.positionAt(top2, cellLeft, table)), 21689 cell.type.createAndFill({ 21690 ...cell.attrs, 21691 rowspan: cellTop + cell.attrs.rowspan - top2 21692 }) 21693 ); 21694 col += cell.attrs.colspan - 1; 21695 } 21696 } 21697 return found2; 21698} 21699function isolateVertical(tr2, map2, table, start2, top2, bottom2, left2, mapFrom) { 21700 if (left2 == 0 || left2 == map2.width) 21701 return false; 21702 let found2 = false; 21703 for (let row = top2; row < bottom2; row++) { 21704 const index = row * map2.width + left2, pos = map2.map[index]; 21705 if (map2.map[index - 1] == pos) { 21706 found2 = true; 21707 const cell = table.nodeAt(pos); 21708 const cellLeft = map2.colCount(pos); 21709 const updatePos = tr2.mapping.slice(mapFrom).map(pos + start2); 21710 tr2.setNodeMarkup( 21711 updatePos, 21712 null, 21713 removeColSpan( 21714 cell.attrs, 21715 left2 - cellLeft, 21716 cell.attrs.colspan - (left2 - cellLeft) 21717 ) 21718 ); 21719 tr2.insert( 21720 updatePos + cell.nodeSize, 21721 cell.type.createAndFill( 21722 removeColSpan(cell.attrs, 0, left2 - cellLeft) 21723 ) 21724 ); 21725 row += cell.attrs.rowspan - 1; 21726 } 21727 } 21728 return found2; 21729} 21730function insertCells(state, dispatch, tableStart, rect, cells) { 21731 let table = tableStart ? state.doc.nodeAt(tableStart - 1) : state.doc; 21732 if (!table) { 21733 throw new Error("No table found"); 21734 } 21735 let map2 = TableMap.get(table); 21736 const { top: top2, left: left2 } = rect; 21737 const right2 = left2 + cells.width, bottom2 = top2 + cells.height; 21738 const tr2 = state.tr; 21739 let mapFrom = 0; 21740 function recomp() { 21741 table = tableStart ? tr2.doc.nodeAt(tableStart - 1) : tr2.doc; 21742 if (!table) { 21743 throw new Error("No table found"); 21744 } 21745 map2 = TableMap.get(table); 21746 mapFrom = tr2.mapping.maps.length; 21747 } 21748 if (growTable(tr2, map2, table, tableStart, right2, bottom2, mapFrom)) 21749 recomp(); 21750 if (isolateHorizontal(tr2, map2, table, tableStart, left2, right2, top2, mapFrom)) 21751 recomp(); 21752 if (isolateHorizontal(tr2, map2, table, tableStart, left2, right2, bottom2, mapFrom)) 21753 recomp(); 21754 if (isolateVertical(tr2, map2, table, tableStart, top2, bottom2, left2, mapFrom)) 21755 recomp(); 21756 if (isolateVertical(tr2, map2, table, tableStart, top2, bottom2, right2, mapFrom)) 21757 recomp(); 21758 for (let row = top2; row < bottom2; row++) { 21759 const from2 = map2.positionAt(row, left2, table), to = map2.positionAt(row, right2, table); 21760 tr2.replace( 21761 tr2.mapping.slice(mapFrom).map(from2 + tableStart), 21762 tr2.mapping.slice(mapFrom).map(to + tableStart), 21763 new Slice(cells.rows[row - top2], 0, 0) 21764 ); 21765 } 21766 recomp(); 21767 tr2.setSelection( 21768 new CellSelection( 21769 tr2.doc.resolve(tableStart + map2.positionAt(top2, left2, table)), 21770 tr2.doc.resolve(tableStart + map2.positionAt(bottom2 - 1, right2 - 1, table)) 21771 ) 21772 ); 21773 dispatch(tr2); 21774} 21775var handleKeyDown$1 = keydownHandler({ 21776 ArrowLeft: arrow$1("horiz", -1), 21777 ArrowRight: arrow$1("horiz", 1), 21778 ArrowUp: arrow$1("vert", -1), 21779 ArrowDown: arrow$1("vert", 1), 21780 "Shift-ArrowLeft": shiftArrow("horiz", -1), 21781 "Shift-ArrowRight": shiftArrow("horiz", 1), 21782 "Shift-ArrowUp": shiftArrow("vert", -1), 21783 "Shift-ArrowDown": shiftArrow("vert", 1), 21784 Backspace: deleteCellSelection, 21785 "Mod-Backspace": deleteCellSelection, 21786 Delete: deleteCellSelection, 21787 "Mod-Delete": deleteCellSelection 21788}); 21789function maybeSetSelection(state, dispatch, selection) { 21790 if (selection.eq(state.selection)) 21791 return false; 21792 if (dispatch) 21793 dispatch(state.tr.setSelection(selection).scrollIntoView()); 21794 return true; 21795} 21796function arrow$1(axis, dir) { 21797 return (state, dispatch, view) => { 21798 if (!view) 21799 return false;
21800 const sel = state.selection; 21801 if (sel instanceof CellSelection) { 21802 return maybeSetSelection( 21803 state, 21804 dispatch, 21805 Selection.near(sel.$headCell, dir) 21806 ); 21807 } 21808 if (axis != "horiz" && !sel.empty) 21809 return false; 21810 const end2 = atEndOfCell(view, axis, dir); 21811 if (end2 == null) 21812 return false; 21813 if (axis == "horiz") { 21814 return maybeSetSelection( 21815 state, 21816 dispatch, 21817 Selection.near(state.doc.resolve(sel.head + dir), dir) 21818 ); 21819 } else { 21820 const $cell = state.doc.resolve(end2); 21821 const $next = nextCell($cell, axis, dir); 21822 let newSel; 21823 if ($next) 21824 newSel = Selection.near($next, 1); 21825 else if (dir < 0) 21826 newSel = Selection.near(state.doc.resolve($cell.before(-1)), -1); 21827 else 21828 newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1); 21829 return maybeSetSelection(state, dispatch, newSel); 21830 } 21831 }; 21832} 21833function shiftArrow(axis, dir) { 21834 return (state, dispatch, view) => { 21835 if (!view) 21836 return false; 21837 const sel = state.selection; 21838 let cellSel; 21839 if (sel instanceof CellSelection) { 21840 cellSel = sel; 21841 } else { 21842 const end2 = atEndOfCell(view, axis, dir); 21843 if (end2 == null) 21844 return false; 21845 cellSel = new CellSelection(state.doc.resolve(end2)); 21846 } 21847 const $head = nextCell(cellSel.$headCell, axis, dir); 21848 if (!$head) 21849 return false; 21850 return maybeSetSelection( 21851 state, 21852 dispatch, 21853 new CellSelection(cellSel.$anchorCell, $head) 21854 ); 21855 }; 21856} 21857function deleteCellSelection(state, dispatch) { 21858 const sel = state.selection; 21859 if (!(sel instanceof CellSelection)) 21860 return false; 21861 if (dispatch) { 21862 const tr2 = state.tr; 21863 const baseContent = tableNodeTypes(state.schema).cell.createAndFill().content; 21864 sel.forEachCell((cell, pos) => { 21865 if (!cell.content.eq(baseContent)) 21866 tr2.replace( 21867 tr2.mapping.map(pos + 1), 21868 tr2.mapping.map(pos + cell.nodeSize - 1), 21869 new Slice(baseContent, 0, 0) 21870 ); 21871 }); 21872 if (tr2.docChanged) 21873 dispatch(tr2); 21874 } 21875 return true; 21876} 21877function handleTripleClick(view, pos) { 21878 const doc2 = view.state.doc, $cell = cellAround(doc2.resolve(pos)); 21879 if (!$cell) 21880 return false; 21881 view.dispatch(view.state.tr.setSelection(new CellSelection($cell))); 21882 return true; 21883} 21884function handlePaste(view, _, slice2) { 21885 if (!isInTable(view.state)) 21886 return false; 21887 let cells = pastedCells(slice2); 21888 const sel = view.state.selection; 21889 if (sel instanceof CellSelection) { 21890 if (!cells) 21891 cells = { 21892 width: 1, 21893 height: 1, 21894 rows: [ 21895 Fragment.from( 21896 fitSlice(tableNodeTypes(view.state.schema).cell, slice2) 21897 ) 21898 ] 21899 }; 21900 const table = sel.$anchorCell.node(-1); 21901 const start2 = sel.$anchorCell.start(-1); 21902 const rect = TableMap.get(table).rectBetween( 21903 sel.$anchorCell.pos - start2, 21904 sel.$headCell.pos - start2 21905 ); 21906 cells = clipCells(cells, rect.right - rect.left, rect.bottom - rect.top); 21907 insertCells(view.state, view.dispatch, start2, rect, cells); 21908 return true; 21909 } else if (cells) { 21910 const $cell = selectionCell(view.state); 21911 const start2 = $cell.start(-1); 21912 insertCells( 21913 view.state, 21914 view.dispatch, 21915 start2, 21916 TableMap.get($cell.node(-1)).findCell($cell.pos - start2), 21917 cells 21918 ); 21919 return true; 21920 } else { 21921 return false; 21922 } 21923} 21924function handleMouseDown(view, startEvent) { 21925 var _a; 21926 if (startEvent.ctrlKey || startEvent.metaKey) 21927 return; 21928 const startDOMCell = domInCell(view, startEvent.target); 21929 let $anchor; 21930 if (startEvent.shiftKey && view.state.selection instanceof CellSelection) { 21931 setCellSelection(view.state.selection.$anchorCell, startEvent); 21932 startEvent.preventDefault(); 21933 } else if (startEvent.shiftKey && startDOMCell && ($anchor = cellAround(view.state.selection.$anchor)) != null && ((_a = cellUnderMouse(view, startEvent)) == null ? void 0 : _a.pos) != $anchor.pos) { 21934 setCellSelection($anchor, startEvent); 21935 startEvent.preventDefault(); 21936 } else if (!startDOMCell) { 21937 return; 21938 } 21939 function setCellSelection($anchor2, event) { 21940 let $head = cellUnderMouse(view, event); 21941 const starting = tableEditingKey.getState(view.state) == null; 21942 if (!$head || !inSameTable($anchor2, $head)) { 21943 if (starting) 21944 $head = $anchor2; 21945 else 21946 return; 21947 } 21948 const selection = new CellSelection($anchor2, $head); 21949 if (starting || !view.state.selection.eq(selection)) { 21950 const tr2 = view.state.tr.setSelection(selection); 21951 if (starting) 21952 tr2.setMeta(tableEditingKey, $anchor2.pos); 21953 view.dispatch(tr2); 21954 } 21955 } 21956 function stop() {
21957 view.root.removeEventListener("mouseup", stop); 21958 view.root.removeEventListener("dragstart", stop); 21959 view.root.removeEventListener("mousemove", move); 21960 if (tableEditingKey.getState(view.state) != null) 21961 view.dispatch(view.state.tr.setMeta(tableEditingKey, -1)); 21962 } 21963 function move(_event) { 21964 const event = _event; 21965 const anchor = tableEditingKey.getState(view.state); 21966 let $anchor2; 21967 if (anchor != null) { 21968 $anchor2 = view.state.doc.resolve(anchor); 21969 } else if (domInCell(view, event.target) != startDOMCell) { 21970 $anchor2 = cellUnderMouse(view, startEvent); 21971 if (!$anchor2) 21972 return stop(); 21973 } 21974 if ($anchor2) 21975 setCellSelection($anchor2, event); 21976 } 21977 view.root.addEventListener("mouseup", stop); 21978 view.root.addEventListener("dragstart", stop); 21979 view.root.addEventListener("mousemove", move); 21980} 21981function atEndOfCell(view, axis, dir) { 21982 if (!(view.state.selection instanceof TextSelection)) 21983 return null; 21984 const { $head } = view.state.selection; 21985 for (let d = $head.depth - 1; d >= 0; d--) { 21986 const parent = $head.node(d), index = dir < 0 ? $head.index(d) : $head.indexAfter(d); 21987 if (index != (dir < 0 ? 0 : parent.childCount)) 21988 return null; 21989 if (parent.type.spec.tableRole == "cell" || parent.type.spec.tableRole == "header_cell") { 21990 const cellPos = $head.before(d); 21991 const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left"; 21992 return view.endOfTextblock(dirStr) ? cellPos : null; 21993 } 21994 } 21995 return null; 21996} 21997function domInCell(view, dom) { 21998 for (; dom && dom != view.dom; dom = dom.parentNode) { 21999 if (dom.nodeName == "TD" || dom.nodeName == "TH") { 22000 return dom; 22001 } 22002 } 22003 return null; 22004} 22005function cellUnderMouse(view, event) { 22006 const mousePos = view.posAtCoords({ 22007 left: event.clientX, 22008 top: event.clientY 22009 }); 22010 if (!mousePos) 22011 return null; 22012 return mousePos ? cellAround(view.state.doc.resolve(mousePos.pos)) : null; 22013} 22014var TableView$1 = class TableView { 22015 constructor(node, cellMinWidth) { 22016 this.node = node; 22017 this.cellMinWidth = cellMinWidth; 22018 this.dom = document.createElement("div"); 22019 this.dom.className = "tableWrapper"; 22020 this.table = this.dom.appendChild(document.createElement("table")); 22021 this.colgroup = this.table.appendChild(document.createElement("colgroup")); 22022 updateColumnsOnResize(node, this.colgroup, this.table, cellMinWidth); 22023 this.contentDOM = this.table.appendChild(document.createElement("tbody")); 22024 } 22025 update(node) { 22026 if (node.type != this.node.type) 22027 return false; 22028 this.node = node; 22029 updateColumnsOnResize(node, this.colgroup, this.table, this.cellMinWidth); 22030 return true; 22031 } 22032 ignoreMutation(record) { 22033 return record.type == "attributes" && (record.target == this.table || this.colgroup.contains(record.target)); 22034 } 22035}; 22036function updateColumnsOnResize(node, colgroup, table, cellMinWidth, overrideCol, overrideValue) { 22037 var _a; 22038 let totalWidth = 0; 22039 let fixedWidth = true; 22040 let nextDOM = colgroup.firstChild; 22041 const row = node.firstChild; 22042 if (!row) 22043 return; 22044 for (let i = 0, col = 0; i < row.childCount; i++) { 22045 const { colspan, colwidth } = row.child(i).attrs; 22046 for (let j = 0; j < colspan; j++, col++) { 22047 const hasWidth = overrideCol == col ? overrideValue : colwidth && colwidth[j]; 22048 const cssWidth = hasWidth ? hasWidth + "px" : ""; 22049 totalWidth += hasWidth || cellMinWidth; 22050 if (!hasWidth) 22051 fixedWidth = false; 22052 if (!nextDOM) { 22053 colgroup.appendChild(document.createElement("col")).style.width = cssWidth; 22054 } else { 22055 if (nextDOM.style.width != cssWidth) 22056 nextDOM.style.width = cssWidth; 22057 nextDOM = nextDOM.nextSibling; 22058 } 22059 } 22060 } 22061 while (nextDOM) { 22062 const after = nextDOM.nextSibling; 22063 (_a = nextDOM.parentNode) == null ? void 0 : _a.removeChild(nextDOM); 22064 nextDOM = after; 22065 } 22066 if (fixedWidth) { 22067 table.style.width = totalWidth + "px"; 22068 table.style.minWidth = ""; 22069 } else { 22070 table.style.width = ""; 22071 table.style.minWidth = totalWidth + "px"; 22072 } 22073} 22074var columnResizingPluginKey = new PluginKey( 22075 "tableColumnResizing" 22076); 22077function columnResizing({ 22078 handleWidth = 5, 22079 cellMinWidth = 25, 22080 View = TableView$1, 22081 lastColumnResizable = true 22082} = {}) { 22083 const plugin = new Plugin({
22084 key: columnResizingPluginKey, 22085 state: { 22086 init(_, state) { 22087 plugin.spec.props.nodeViews[tableNodeTypes(state.schema).table.name] = (node, view) => new View(node, cellMinWidth, view); 22088 return new ResizeState(-1, false); 22089 }, 22090 apply(tr2, prev) { 22091 return prev.apply(tr2); 22092 } 22093 }, 22094 props: { 22095 attributes: (state) => { 22096 const pluginState = columnResizingPluginKey.getState(state); 22097 return pluginState && pluginState.activeHandle > -1 ? { class: "resize-cursor" } : {}; 22098 }, 22099 handleDOMEvents: { 22100 mousemove: (view, event) => { 22101 handleMouseMove( 22102 view, 22103 event, 22104 handleWidth, 22105 cellMinWidth, 22106 lastColumnResizable 22107 ); 22108 }, 22109 mouseleave: (view) => { 22110 handleMouseLeave(view); 22111 }, 22112 mousedown: (view, event) => { 22113 handleMouseDown2(view, event, cellMinWidth); 22114 } 22115 }, 22116 decorations: (state) => { 22117 const pluginState = columnResizingPluginKey.getState(state); 22118 if (pluginState && pluginState.activeHandle > -1) { 22119 return handleDecorations(state, pluginState.activeHandle); 22120 } 22121 }, 22122 nodeViews: {} 22123 } 22124 }); 22125 return plugin; 22126} 22127var ResizeState = class _ResizeState { 22128 constructor(activeHandle, dragging) { 22129 this.activeHandle = activeHandle; 22130 this.dragging = dragging; 22131 } 22132 apply(tr2) { 22133 const state = this; 22134 const action = tr2.getMeta(columnResizingPluginKey); 22135 if (action && action.setHandle != null) 22136 return new _ResizeState(action.setHandle, false); 22137 if (action && action.setDragging !== void 0) 22138 return new _ResizeState(state.activeHandle, action.setDragging); 22139 if (state.activeHandle > -1 && tr2.docChanged) { 22140 let handle = tr2.mapping.map(state.activeHandle, -1); 22141 if (!pointsAtCell(tr2.doc.resolve(handle))) { 22142 handle = -1; 22143 } 22144 return new _ResizeState(handle, state.dragging); 22145 } 22146 return state; 22147 } 22148}; 22149function handleMouseMove(view, event, handleWidth, cellMinWidth, lastColumnResizable) { 22150 const pluginState = columnResizingPluginKey.getState(view.state); 22151 if (!pluginState) 22152 return; 22153 if (!pluginState.dragging) { 22154 const target = domCellAround(event.target); 22155 let cell = -1; 22156 if (target) {
22157 const { left: left2, right: right2 } = target.getBoundingClientRect(); 22158 if (event.clientX - left2 <= handleWidth) 22159 cell = edgeCell(view, event, "left", handleWidth); 22160 else if (right2 - event.clientX <= handleWidth) 22161 cell = edgeCell(view, event, "right", handleWidth); 22162 } 22163 if (cell != pluginState.activeHandle) { 22164 if (!lastColumnResizable && cell !== -1) { 22165 const $cell = view.state.doc.resolve(cell); 22166 const table = $cell.node(-1); 22167 const map2 = TableMap.get(table); 22168 const tableStart = $cell.start(-1); 22169 const col = map2.colCount($cell.pos - tableStart) + $cell.nodeAfter.attrs.colspan - 1; 22170 if (col == map2.width - 1) { 22171 return; 22172 } 22173 } 22174 updateHandle(view, cell); 22175 } 22176 } 22177} 22178function handleMouseLeave(view) { 22179 const pluginState = columnResizingPluginKey.getState(view.state); 22180 if (pluginState && pluginState.activeHandle > -1 && !pluginState.dragging) 22181 updateHandle(view, -1); 22182} 22183function handleMouseDown2(view, event, cellMinWidth) { 22184 var _a; 22185 const win = (_a = view.dom.ownerDocument.defaultView) != null ? _a : window; 22186 const pluginState = columnResizingPluginKey.getState(view.state); 22187 if (!pluginState || pluginState.activeHandle == -1 || pluginState.dragging) 22188 return false; 22189 const cell = view.state.doc.nodeAt(pluginState.activeHandle); 22190 const width = currentColWidth(view, pluginState.activeHandle, cell.attrs); 22191 view.dispatch( 22192 view.state.tr.setMeta(columnResizingPluginKey, { 22193 setDragging: { startX: event.clientX, startWidth: width } 22194 }) 22195 ); 22196 function finish(event2) { 22197 win.removeEventListener("mouseup", finish); 22198 win.removeEventListener("mousemove", move); 22199 const pluginState2 = columnResizingPluginKey.getState(view.state); 22200 if (pluginState2 == null ? void 0 : pluginState2.dragging) { 22201 updateColumnWidth( 22202 view, 22203 pluginState2.activeHandle, 22204 draggedWidth(pluginState2.dragging, event2, cellMinWidth) 22205 ); 22206 view.dispatch( 22207 view.state.tr.setMeta(columnResizingPluginKey, { setDragging: null }) 22208 ); 22209 } 22210 } 22211 function move(event2) { 22212 if (!event2.which) 22213 return finish(event2); 22214 const pluginState2 = columnResizingPluginKey.getState(view.state); 22215 if (!pluginState2) 22216 return; 22217 if (pluginState2.dragging) { 22218 const dragged = draggedWidth(pluginState2.dragging, event2, cellMinWidth); 22219 displayColumnWidth(view, pluginState2.activeHandle, dragged, cellMinWidth); 22220 } 22221 } 22222 win.addEventListener("mouseup", finish); 22223 win.addEventListener("mousemove", move); 22224 event.preventDefault(); 22225 return true; 22226} 22227function currentColWidth(view, cellPos, { colspan, colwidth }) { 22228 const width = colwidth && colwidth[colwidth.length - 1]; 22229 if (width) 22230 return width; 22231 const dom = view.domAtPos(cellPos); 22232 const node = dom.node.childNodes[dom.offset]; 22233 let domWidth = node.offsetWidth, parts = colspan; 22234 if (colwidth) { 22235 for (let i = 0; i < colspan; i++) 22236 if (colwidth[i]) { 22237 domWidth -= colwidth[i]; 22238 parts--; 22239 } 22240 } 22241 return domWidth / parts; 22242} 22243function domCellAround(target) { 22244 while (target && target.nodeName != "TD" && target.nodeName != "TH") 22245 target = target.classList && target.classList.contains("ProseMirror") ? null : target.parentNode; 22246 return target; 22247} 22248function edgeCell(view, event, side, handleWidth) { 22249 const offset2 = side == "right" ? -handleWidth : handleWidth; 22250 const found2 = view.posAtCoords({ 22251 left: event.clientX + offset2, 22252 top: event.clientY 22253 }); 22254 if (!found2) 22255 return -1; 22256 const { pos } = found2; 22257 const $cell = cellAround(view.state.doc.resolve(pos)); 22258 if (!$cell) 22259 return -1; 22260 if (side == "right") 22261 return $cell.pos; 22262 const map2 = TableMap.get($cell.node(-1)), start2 = $cell.start(-1); 22263 const index = map2.map.indexOf($cell.pos - start2); 22264 return index % map2.width == 0 ? -1 : start2 + map2.map[index - 1]; 22265} 22266function draggedWidth(dragging, event, cellMinWidth) { 22267 const offset2 = event.clientX - dragging.startX; 22268 return Math.max(cellMinWidth, dragging.startWidth + offset2); 22269} 22270function updateHandle(view, value) { 22271 view.dispatch( 22272 view.state.tr.setMeta(columnResizingPluginKey, { setHandle: value }) 22273 ); 22274} 22275function updateColumnWidth(view, cell, width) { 22276 const $cell = view.state.doc.resolve(cell); 22277 const table = $cell.node(-1), map2 = TableMap.get(table), start2 = $cell.start(-1); 22278 const col = map2.colCount($cell.pos - start2) + $cell.nodeAfter.attrs.colspan - 1; 22279 const tr2 = view.state.tr; 22280 for (let row = 0; row < map2.height; row++) { 22281 const mapIndex = row * map2.width + col; 22282 if (row && map2.map[mapIndex] == map2.map[mapIndex - map2.width]) 22283 continue; 22284 const pos = map2.map[mapIndex]; 22285 const attrs = table.nodeAt(pos).attrs; 22286 const index = attrs.colspan == 1 ? 0 : col - map2.colCount(pos); 22287 if (attrs.colwidth && attrs.colwidth[index] == width) 22288 continue; 22289 const colwidth = attrs.colwidth ? attrs.colwidth.slice() : zeroes(attrs.colspan); 22290 colwidth[index] = width; 22291 tr2.setNodeMarkup(start2 + pos, null, { ...attrs, colwidth }); 22292 } 22293 if (tr2.docChanged) 22294 view.dispatch(tr2); 22295} 22296function displayColumnWidth(view, cell, width, cellMinWidth) { 22297 const $cell = view.state.doc.resolve(cell); 22298 const table = $cell.node(-1), start2 = $cell.start(-1); 22299 const col = TableMap.get(table).colCount($cell.pos - start2) + $cell.nodeAfter.attrs.colspan - 1; 22300 let dom = view.domAtPos($cell.start(-1)).node; 22301 while (dom && dom.nodeName != "TABLE") { 22302 dom = dom.parentNode; 22303 } 22304 if (!dom) 22305 return; 22306 updateColumnsOnResize( 22307 table, 22308 dom.firstChild, 22309 dom, 22310 cellMinWidth, 22311 col, 22312 width 22313 ); 22314} 22315function zeroes(n) { 22316 return Array(n).fill(0); 22317} 22318function handleDecorations(state, cell) { 22319 const decorations = []; 22320 const $cell = state.doc.resolve(cell); 22321 const table = $cell.node(-1); 22322 if (!table) { 22323 return DecorationSet.empty; 22324 } 22325 const map2 = TableMap.get(table); 22326 const start2 = $cell.start(-1); 22327 const col = map2.colCount($cell.pos - start2) + $cell.nodeAfter.attrs.colspan; 22328 for (let row = 0; row < map2.height; row++) { 22329 const index = col + row * map2.width - 1; 22330 if ((col == map2.width || map2.map[index] != map2.map[index + 1]) && (row == 0 || map2.map[index] != map2.map[index - map2.width])) {
22331 const cellPos = map2.map[index]; 22332 const pos = start2 + cellPos + table.nodeAt(cellPos).nodeSize - 1; 22333 const dom = document.createElement("div"); 22334 dom.className = "column-resize-handle"; 22335 decorations.push(Decoration.widget(pos, dom)); 22336 } 22337 } 22338 return DecorationSet.create(state.doc, decorations); 22339} 22340function selectedRect(state) { 22341 const sel = state.selection; 22342 const $pos = selectionCell(state); 22343 const table = $pos.node(-1); 22344 const tableStart = $pos.start(-1); 22345 const map2 = TableMap.get(table); 22346 const rect = sel instanceof CellSelection ? map2.rectBetween( 22347 sel.$anchorCell.pos - tableStart, 22348 sel.$headCell.pos - tableStart 22349 ) : map2.findCell($pos.pos - tableStart); 22350 return { ...rect, tableStart, map: map2, table }; 22351} 22352function addColumn(tr2, { map: map2, tableStart, table }, col) { 22353 let refColumn = col > 0 ? -1 : 0; 22354 if (columnIsHeader(map2, table, col + refColumn)) { 22355 refColumn = col == 0 || col == map2.width ? null : 0; 22356 } 22357 for (let row = 0; row < map2.height; row++) { 22358 const index = row * map2.width + col; 22359 if (col > 0 && col < map2.width && map2.map[index - 1] == map2.map[index]) { 22360 const pos = map2.map[index]; 22361 const cell = table.nodeAt(pos); 22362 tr2.setNodeMarkup( 22363 tr2.mapping.map(tableStart + pos), 22364 null, 22365 addColSpan(cell.attrs, col - map2.colCount(pos)) 22366 ); 22367 row += cell.attrs.rowspan - 1; 22368 } else { 22369 const type = refColumn == null ? tableNodeTypes(table.type.schema).cell : table.nodeAt(map2.map[index + refColumn]).type; 22370 const pos = map2.positionAt(row, col, table); 22371 tr2.insert(tr2.mapping.map(tableStart + pos), type.createAndFill()); 22372 } 22373 } 22374 return tr2; 22375} 22376function addColumnBefore(state, dispatch) { 22377 if (!isInTable(state)) 22378 return false; 22379 if (dispatch) { 22380 const rect = selectedRect(state); 22381 dispatch(addColumn(state.tr, rect, rect.left)); 22382 } 22383 return true; 22384} 22385function addColumnAfter(state, dispatch) { 22386 if (!isInTable(state)) 22387 return false; 22388 if (dispatch) { 22389 const rect = selectedRect(state); 22390 dispatch(addColumn(state.tr, rect, rect.right)); 22391 } 22392 return true; 22393} 22394function removeColumn(tr2, { map: map2, table, tableStart }, col) { 22395 const mapStart = tr2.mapping.maps.length; 22396 for (let row = 0; row < map2.height; ) { 22397 const index = row * map2.width + col; 22398 const pos = map2.map[index]; 22399 const cell = table.nodeAt(pos); 22400 const attrs = cell.attrs; 22401 if (col > 0 && map2.map[index - 1] == pos || col < map2.width - 1 && map2.map[index + 1] == pos) { 22402 tr2.setNodeMarkup( 22403 tr2.mapping.slice(mapStart).map(tableStart + pos), 22404 null, 22405 removeColSpan(attrs, col - map2.colCount(pos)) 22406 ); 22407 } else { 22408 const start2 = tr2.mapping.slice(mapStart).map(tableStart + pos); 22409 tr2.delete(start2, start2 + cell.nodeSize); 22410 } 22411 row += attrs.rowspan; 22412 } 22413} 22414function deleteColumn(state, dispatch) { 22415 if (!isInTable(state)) 22416 return false; 22417 if (dispatch) { 22418 const rect = selectedRect(state); 22419 const tr2 = state.tr; 22420 if (rect.left == 0 && rect.right == rect.map.width) 22421 return false; 22422 for (let i = rect.right - 1; ; i--) { 22423 removeColumn(tr2, rect, i); 22424 if (i == rect.left) 22425 break; 22426 const table = rect.tableStart ? tr2.doc.nodeAt(rect.tableStart - 1) : tr2.doc; 22427 if (!table) { 22428 throw RangeError("No table found"); 22429 } 22430 rect.table = table; 22431 rect.map = TableMap.get(table); 22432 } 22433 dispatch(tr2); 22434 } 22435 return true; 22436} 22437function rowIsHeader(map2, table, row) { 22438 var _a; 22439 const headerCell = tableNodeTypes(table.type.schema).header_cell; 22440 for (let col = 0; col < map2.width; col++) 22441 if (((_a = table.nodeAt(map2.map[col + row * map2.width])) == null ? void 0 : _a.type) != headerCell) 22442 return false; 22443 return true; 22444} 22445function addRow(tr2, { map: map2, tableStart, table }, row) { 22446 var _a; 22447 let rowPos = tableStart; 22448 for (let i = 0; i < row; i++) 22449 rowPos += table.child(i).nodeSize; 22450 const cells = []; 22451 let refRow = row > 0 ? -1 : 0; 22452 if (rowIsHeader(map2, table, row + refRow)) 22453 refRow = row == 0 || row == map2.height ? null : 0; 22454 for (let col = 0, index = map2.width * row; col < map2.width; col++, index++) { 22455 if (row > 0 && row < map2.height && map2.map[index] == map2.map[index - map2.width]) { 22456 const pos = map2.map[index]; 22457 const attrs = table.nodeAt(pos).attrs; 22458 tr2.setNodeMarkup(tableStart + pos, null, { 22459 ...attrs, 22460 rowspan: attrs.rowspan + 1 22461 }); 22462 col += attrs.colspan - 1; 22463 } else { 22464 const type = refRow == null ? tableNodeTypes(table.type.schema).cell : (_a = table.nodeAt(map2.map[index + refRow * map2.width])) == null ? void 0 : _a.type; 22465 const node = type == null ? void 0 : type.createAndFill(); 22466 if (node) 22467 cells.push(node); 22468 } 22469 } 22470 tr2.insert(rowPos, tableNodeTypes(table.type.schema).row.create(null, cells)); 22471 return tr2; 22472} 22473function addRowBefore(state, dispatch) { 22474 if (!isInTable(state)) 22475 return false;
22476 if (dispatch) { 22477 const rect = selectedRect(state); 22478 dispatch(addRow(state.tr, rect, rect.top)); 22479 } 22480 return true; 22481} 22482function addRowAfter(state, dispatch) { 22483 if (!isInTable(state)) 22484 return false; 22485 if (dispatch) { 22486 const rect = selectedRect(state); 22487 dispatch(addRow(state.tr, rect, rect.bottom)); 22488 } 22489 return true; 22490} 22491function removeRow(tr2, { map: map2, table, tableStart }, row) { 22492 let rowPos = 0; 22493 for (let i = 0; i < row; i++) 22494 rowPos += table.child(i).nodeSize; 22495 const nextRow = rowPos + table.child(row).nodeSize; 22496 const mapFrom = tr2.mapping.maps.length; 22497 tr2.delete(rowPos + tableStart, nextRow + tableStart); 22498 const seen = /* @__PURE__ */ new Set(); 22499 for (let col = 0, index = row * map2.width; col < map2.width; col++, index++) { 22500 const pos = map2.map[index]; 22501 if (seen.has(pos)) 22502 continue; 22503 seen.add(pos); 22504 if (row > 0 && pos == map2.map[index - map2.width]) { 22505 const attrs = table.nodeAt(pos).attrs; 22506 tr2.setNodeMarkup(tr2.mapping.slice(mapFrom).map(pos + tableStart), null, { 22507 ...attrs, 22508 rowspan: attrs.rowspan - 1 22509 }); 22510 col += attrs.colspan - 1; 22511 } else if (row < map2.height && pos == map2.map[index + map2.width]) { 22512 const cell = table.nodeAt(pos); 22513 const attrs = cell.attrs; 22514 const copy2 = cell.type.create( 22515 { ...attrs, rowspan: cell.attrs.rowspan - 1 }, 22516 cell.content 22517 ); 22518 const newPos = map2.positionAt(row + 1, col, table); 22519 tr2.insert(tr2.mapping.slice(mapFrom).map(tableStart + newPos), copy2); 22520 col += attrs.colspan - 1; 22521 } 22522 } 22523} 22524function deleteRow(state, dispatch) { 22525 if (!isInTable(state)) 22526 return false; 22527 if (dispatch) { 22528 const rect = selectedRect(state), tr2 = state.tr; 22529 if (rect.top == 0 && rect.bottom == rect.map.height) 22530 return false; 22531 for (let i = rect.bottom - 1; ; i--) { 22532 removeRow(tr2, rect, i); 22533 if (i == rect.top) 22534 break; 22535 const table = rect.tableStart ? tr2.doc.nodeAt(rect.tableStart - 1) : tr2.doc; 22536 if (!table) { 22537 throw RangeError("No table found"); 22538 } 22539 rect.table = table; 22540 rect.map = TableMap.get(rect.table); 22541 } 22542 dispatch(tr2); 22543 } 22544 return true; 22545} 22546function isEmpty(cell) { 22547 const c = cell.content; 22548 return c.childCount == 1 && c.child(0).isTextblock && c.child(0).childCount == 0; 22549} 22550function cellsOverlapRectangle({ width, height, map: map2 }, rect) { 22551 let indexTop = rect.top * width + rect.left, indexLeft = indexTop; 22552 let indexBottom = (rect.bottom - 1) * width + rect.left, indexRight = indexTop + (rect.right - rect.left - 1); 22553 for (let i = rect.top; i < rect.bottom; i++) { 22554 if (rect.left > 0 && map2[indexLeft] == map2[indexLeft - 1] || rect.right < width && map2[indexRight] == map2[indexRight + 1]) 22555 return true; 22556 indexLeft += width; 22557 indexRight += width; 22558 } 22559 for (let i = rect.left; i < rect.right; i++) { 22560 if (rect.top > 0 && map2[indexTop] == map2[indexTop - width] || rect.bottom < height && map2[indexBottom] == map2[indexBottom + width]) 22561 return true; 22562 indexTop++; 22563 indexBottom++; 22564 } 22565 return false; 22566} 22567function mergeCells(state, dispatch) { 22568 const sel = state.selection; 22569 if (!(sel instanceof CellSelection) || sel.$anchorCell.pos == sel.$headCell.pos) 22570 return false; 22571 const rect = selectedRect(state), { map: map2 } = rect; 22572 if (cellsOverlapRectangle(map2, rect)) 22573 return false; 22574 if (dispatch) { 22575 const tr2 = state.tr; 22576 const seen = {}; 22577 let content = Fragment.empty; 22578 let mergedPos; 22579 let mergedCell; 22580 for (let row = rect.top; row < rect.bottom; row++) { 22581 for (let col = rect.left; col < rect.right; col++) { 22582 const cellPos = map2.map[row * map2.width + col]; 22583 const cell = rect.table.nodeAt(cellPos); 22584 if (seen[cellPos] || !cell) 22585 continue; 22586 seen[cellPos] = true; 22587 if (mergedPos == null) { 22588 mergedPos = cellPos; 22589 mergedCell = cell; 22590 } else { 22591 if (!isEmpty(cell)) 22592 content = content.append(cell.content); 22593 const mapped = tr2.mapping.map(cellPos + rect.tableStart); 22594 tr2.delete(mapped, mapped + cell.nodeSize); 22595 } 22596 } 22597 } 22598 if (mergedPos == null || mergedCell == null) { 22599 return true; 22600 } 22601 tr2.setNodeMarkup(mergedPos + rect.tableStart, null, { 22602 ...addColSpan( 22603 mergedCell.attrs, 22604 mergedCell.attrs.colspan, 22605 rect.right - rect.left - mergedCell.attrs.colspan 22606 ), 22607 rowspan: rect.bottom - rect.top 22608 }); 22609 if (content.size) { 22610 const end2 = mergedPos + 1 + mergedCell.content.size; 22611 const start2 = isEmpty(mergedCell) ? mergedPos + 1 : end2; 22612 tr2.replaceWith(start2 + rect.tableStart, end2 + rect.tableStart, content); 22613 } 22614 tr2.setSelection( 22615 new CellSelection(tr2.doc.resolve(mergedPos + rect.tableStart)) 22616 ); 22617 dispatch(tr2); 22618 } 22619 return true; 22620} 22621function splitCell(state, dispatch) { 22622 const nodeTypes = tableNodeTypes(state.schema); 22623 return splitCellWithType(({ node }) => { 22624 return nodeTypes[node.type.spec.tableRole]; 22625 })(state, dispatch); 22626} 22627function splitCellWithType(getCellType) { 22628 return (state, dispatch) => { 22629 var _a; 22630 const sel = state.selection;
22631 let cellNode; 22632 let cellPos; 22633 if (!(sel instanceof CellSelection)) { 22634 cellNode = cellWrapping(sel.$from); 22635 if (!cellNode) 22636 return false; 22637 cellPos = (_a = cellAround(sel.$from)) == null ? void 0 : _a.pos; 22638 } else { 22639 if (sel.$anchorCell.pos != sel.$headCell.pos) 22640 return false; 22641 cellNode = sel.$anchorCell.nodeAfter; 22642 cellPos = sel.$anchorCell.pos; 22643 } 22644 if (cellNode == null || cellPos == null) { 22645 return false; 22646 } 22647 if (cellNode.attrs.colspan == 1 && cellNode.attrs.rowspan == 1) { 22648 return false; 22649 } 22650 if (dispatch) { 22651 let baseAttrs = cellNode.attrs; 22652 const attrs = []; 22653 const colwidth = baseAttrs.colwidth; 22654 if (baseAttrs.rowspan > 1) 22655 baseAttrs = { ...baseAttrs, rowspan: 1 }; 22656 if (baseAttrs.colspan > 1) 22657 baseAttrs = { ...baseAttrs, colspan: 1 }; 22658 const rect = selectedRect(state), tr2 = state.tr; 22659 for (let i = 0; i < rect.right - rect.left; i++) 22660 attrs.push( 22661 colwidth ? { 22662 ...baseAttrs, 22663 colwidth: colwidth && colwidth[i] ? [colwidth[i]] : null 22664 } : baseAttrs 22665 ); 22666 let lastCell; 22667 for (let row = rect.top; row < rect.bottom; row++) { 22668 let pos = rect.map.positionAt(row, rect.left, rect.table); 22669 if (row == rect.top) 22670 pos += cellNode.nodeSize; 22671 for (let col = rect.left, i = 0; col < rect.right; col++, i++) { 22672 if (col == rect.left && row == rect.top) 22673 continue; 22674 tr2.insert( 22675 lastCell = tr2.mapping.map(pos + rect.tableStart, 1), 22676 getCellType({ node: cellNode, row, col }).createAndFill(attrs[i]) 22677 ); 22678 } 22679 } 22680 tr2.setNodeMarkup( 22681 cellPos, 22682 getCellType({ node: cellNode, row: rect.top, col: rect.left }), 22683 attrs[0] 22684 ); 22685 if (sel instanceof CellSelection) 22686 tr2.setSelection( 22687 new CellSelection( 22688 tr2.doc.resolve(sel.$anchorCell.pos), 22689 lastCell ? tr2.doc.resolve(lastCell) : void 0 22690 ) 22691 ); 22692 dispatch(tr2); 22693 } 22694 return true; 22695 }; 22696} 22697function setCellAttr(name, value) { 22698 return function(state, dispatch) { 22699 if (!isInTable(state)) 22700 return false; 22701 const $cell = selectionCell(state); 22702 if ($cell.nodeAfter.attrs[name] === value) 22703 return false; 22704 if (dispatch) { 22705 const tr2 = state.tr; 22706 if (state.selection instanceof CellSelection) 22707 state.selection.forEachCell((node, pos) => { 22708 if (node.attrs[name] !== value) 22709 tr2.setNodeMarkup(pos, null, { 22710 ...node.attrs, 22711 [name]: value 22712 }); 22713 }); 22714 else 22715 tr2.setNodeMarkup($cell.pos, null, { 22716 ...$cell.nodeAfter.attrs, 22717 [name]: value 22718 }); 22719 dispatch(tr2); 22720 } 22721 return true; 22722 }; 22723} 22724function deprecated_toggleHeader(type) { 22725 return function(state, dispatch) { 22726 if (!isInTable(state)) 22727 return false; 22728 if (dispatch) { 22729 const types = tableNodeTypes(state.schema); 22730 const rect = selectedRect(state), tr2 = state.tr; 22731 const cells = rect.map.cellsInRect( 22732 type == "column" ? { 22733 left: rect.left, 22734 top: 0, 22735 right: rect.right, 22736 bottom: rect.map.height 22737 } : type == "row" ? { 22738 left: 0, 22739 top: rect.top, 22740 right: rect.map.width, 22741 bottom: rect.bottom 22742 } : rect 22743 ); 22744 const nodes = cells.map((pos) => rect.table.nodeAt(pos)); 22745 for (let i = 0; i < cells.length; i++) 22746 if (nodes[i].type == types.header_cell) 22747 tr2.setNodeMarkup( 22748 rect.tableStart + cells[i], 22749 types.cell, 22750 nodes[i].attrs 22751 ); 22752 if (tr2.steps.length == 0) 22753 for (let i = 0; i < cells.length; i++) 22754 tr2.setNodeMarkup( 22755 rect.tableStart + cells[i], 22756 types.header_cell, 22757 nodes[i].attrs 22758 ); 22759 dispatch(tr2); 22760 } 22761 return true; 22762 }; 22763} 22764function isHeaderEnabledByType(type, rect, types) { 22765 const cellPositions = rect.map.cellsInRect({ 22766 left: 0, 22767 top: 0, 22768 right: type == "row" ? rect.map.width : 1, 22769 bottom: type == "column" ? rect.map.height : 1 22770 }); 22771 for (let i = 0; i < cellPositions.length; i++) { 22772 const cell = rect.table.nodeAt(cellPositions[i]); 22773 if (cell && cell.type !== types.header_cell) { 22774 return false;
22775 } 22776 } 22777 return true; 22778} 22779function toggleHeader(type, options) { 22780 options = options || { useDeprecatedLogic: false }; 22781 if (options.useDeprecatedLogic) 22782 return deprecated_toggleHeader(type); 22783 return function(state, dispatch) { 22784 if (!isInTable(state)) 22785 return false; 22786 if (dispatch) { 22787 const types = tableNodeTypes(state.schema); 22788 const rect = selectedRect(state), tr2 = state.tr; 22789 const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types); 22790 const isHeaderColumnEnabled = isHeaderEnabledByType( 22791 "column", 22792 rect, 22793 types 22794 ); 22795 const isHeaderEnabled = type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false; 22796 const selectionStartsAt = isHeaderEnabled ? 1 : 0; 22797 const cellsRect = type == "column" ? { 22798 left: 0, 22799 top: selectionStartsAt, 22800 right: 1, 22801 bottom: rect.map.height 22802 } : type == "row" ? { 22803 left: selectionStartsAt, 22804 top: 0, 22805 right: rect.map.width, 22806 bottom: 1 22807 } : rect; 22808 const newType = type == "column" ? isHeaderColumnEnabled ? types.cell : types.header_cell : type == "row" ? isHeaderRowEnabled ? types.cell : types.header_cell : types.cell; 22809 rect.map.cellsInRect(cellsRect).forEach((relativeCellPos) => { 22810 const cellPos = relativeCellPos + rect.tableStart; 22811 const cell = tr2.doc.nodeAt(cellPos); 22812 if (cell) { 22813 tr2.setNodeMarkup(cellPos, newType, cell.attrs); 22814 } 22815 }); 22816 dispatch(tr2); 22817 } 22818 return true; 22819 }; 22820} 22821toggleHeader("row", { 22822 useDeprecatedLogic: true 22823}); 22824toggleHeader("column", { 22825 useDeprecatedLogic: true 22826}); 22827var toggleHeaderCell = toggleHeader("cell", { 22828 useDeprecatedLogic: true 22829}); 22830function findNextCell($cell, dir) { 22831 if (dir < 0) { 22832 const before = $cell.nodeBefore; 22833 if (before) 22834 return $cell.pos - before.nodeSize; 22835 for (let row = $cell.index(-1) - 1, rowEnd = $cell.before(); row >= 0; row--) { 22836 const rowNode = $cell.node(-1).child(row); 22837 const lastChild = rowNode.lastChild; 22838 if (lastChild) { 22839 return rowEnd - 1 - lastChild.nodeSize; 22840 } 22841 rowEnd -= rowNode.nodeSize; 22842 } 22843 } else { 22844 if ($cell.index() < $cell.parent.childCount - 1) { 22845 return $cell.pos + $cell.nodeAfter.nodeSize; 22846 } 22847 const table = $cell.node(-1); 22848 for (let row = $cell.indexAfter(-1), rowStart = $cell.after(); row < table.childCount; row++) { 22849 const rowNode = table.child(row); 22850 if (rowNode.childCount) 22851 return rowStart + 1; 22852 rowStart += rowNode.nodeSize; 22853 } 22854 } 22855 return null; 22856} 22857function goToNextCell(direction) { 22858 return function(state, dispatch) { 22859 if (!isInTable(state)) 22860 return false; 22861 const cell = findNextCell(selectionCell(state), direction); 22862 if (cell == null) 22863 return false; 22864 if (dispatch) { 22865 const $cell = state.doc.resolve(cell); 22866 dispatch( 22867 state.tr.setSelection(TextSelection.between($cell, moveCellForward($cell))).scrollIntoView() 22868 ); 22869 } 22870 return true; 22871 }; 22872} 22873function deleteTable(state, dispatch) { 22874 const $pos = state.selection.$anchor; 22875 for (let d = $pos.depth; d > 0; d--) { 22876 const node = $pos.node(d); 22877 if (node.type.spec.tableRole == "table") { 22878 if (dispatch) 22879 dispatch( 22880 state.tr.delete($pos.before(d), $pos.after(d)).scrollIntoView() 22881 ); 22882 return true; 22883 } 22884 } 22885 return false; 22886} 22887function tableEditing({ 22888 allowTableNodeSelection = false 22889} = {}) { 22890 return new Plugin({ 22891 key: tableEditingKey, 22892 // This piece of state is used to remember when a mouse-drag 22893 // cell-selection is happening, so that it can continue even as 22894 // transactions (which might move its anchor cell) come in. 22895 state: { 22896 init() { 22897 return null; 22898 }, 22899 apply(tr2, cur) { 22900 const set = tr2.getMeta(tableEditingKey); 22901 if (set != null) 22902 return set == -1 ? null : set; 22903 if (cur == null || !tr2.docChanged) 22904 return cur; 22905 const { deleted, pos } = tr2.mapping.mapResult(cur); 22906 return deleted ? null : pos; 22907 } 22908 }, 22909 props: { 22910 decorations: drawCellSelection, 22911 handleDOMEvents: { 22912 mousedown: handleMouseDown 22913 }, 22914 createSelectionBetween(view) { 22915 return tableEditingKey.getState(view.state) != null ? view.state.selection : null; 22916 }, 22917 handleTripleClick, 22918 handleKeyDown: handleKeyDown$1, 22919 handlePaste 22920 }, 22921 appendTransaction(_, oldState, state) { 22922 return normalizeSelection( 22923 state, 22924 fixTables(state, oldState), 22925 allowTableNodeSelection 22926 ); 22927 } 22928 }); 22929} 22930function updateColumns(node, colgroup, table, cellMinWidth, overrideCol, overrideValue) { 22931 let totalWidth = 0; 22932 let fixedWidth = true; 22933 let nextDOM = colgroup.firstChild;
22934 const row = node.firstChild; 22935 for (let i = 0, col = 0; i < row.childCount; i += 1) { 22936 const { colspan, colwidth } = row.child(i).attrs; 22937 for (let j = 0; j < colspan; j += 1, col += 1) { 22938 const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j]; 22939 const cssWidth = hasWidth ? `${hasWidth}px` : ""; 22940 totalWidth += hasWidth || cellMinWidth; 22941 if (!hasWidth) { 22942 fixedWidth = false; 22943 } 22944 if (!nextDOM) { 22945 colgroup.appendChild(document.createElement("col")).style.width = cssWidth; 22946 } else { 22947 if (nextDOM.style.width !== cssWidth) { 22948 nextDOM.style.width = cssWidth; 22949 } 22950 nextDOM = nextDOM.nextSibling; 22951 } 22952 } 22953 } 22954 while (nextDOM) { 22955 const after = nextDOM.nextSibling; 22956 nextDOM.parentNode.removeChild(nextDOM); 22957 nextDOM = after; 22958 } 22959 if (fixedWidth) { 22960 table.style.width = `${totalWidth}px`; 22961 table.style.minWidth = ""; 22962 } else { 22963 table.style.width = ""; 22964 table.style.minWidth = `${totalWidth}px`; 22965 } 22966} 22967class TableView2 { 22968 constructor(node, cellMinWidth) { 22969 this.node = node; 22970 this.cellMinWidth = cellMinWidth; 22971 this.dom = document.createElement("div"); 22972 this.dom.className = "tableWrapper"; 22973 this.table = this.dom.appendChild(document.createElement("table")); 22974 this.colgroup = this.table.appendChild(document.createElement("colgroup")); 22975 updateColumns(node, this.colgroup, this.table, cellMinWidth); 22976 this.contentDOM = this.table.appendChild(document.createElement("tbody")); 22977 } 22978 update(node) { 22979 if (node.type !== this.node.type) { 22980 return false; 22981 } 22982 this.node = node; 22983 updateColumns(node, this.colgroup, this.table, this.cellMinWidth); 22984 return true; 22985 } 22986 ignoreMutation(mutation) { 22987 return mutation.type === "attributes" && (mutation.target === this.table || this.colgroup.contains(mutation.target)); 22988 } 22989} 22990function createColGroup(node, cellMinWidth, overrideCol, overrideValue) { 22991 let totalWidth = 0; 22992 let fixedWidth = true; 22993 const cols = []; 22994 const row = node.firstChild; 22995 if (!row) { 22996 return {}; 22997 } 22998 for (let i = 0, col = 0; i < row.childCount; i += 1) { 22999 const { colspan, colwidth } = row.child(i).attrs; 23000 for (let j = 0; j < colspan; j += 1, col += 1) { 23001 const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j]; 23002 const cssWidth = hasWidth ? `${hasWidth}px` : ""; 23003 totalWidth += hasWidth || cellMinWidth; 23004 if (!hasWidth) { 23005 fixedWidth = false; 23006 } 23007 cols.push(["col", cssWidth ? { style: `width: ${cssWidth}` } : {}]); 23008 } 23009 } 23010 const tableWidth = fixedWidth ? `${totalWidth}px` : ""; 23011 const tableMinWidth = fixedWidth ? "" : `${totalWidth}px`; 23012 const colgroup = ["colgroup", {}, ...cols]; 23013 return { colgroup, tableWidth, tableMinWidth }; 23014} 23015function createCell(cellType, cellContent) { 23016 if (cellContent) { 23017 return cellType.createChecked(null, cellContent); 23018 } 23019 return cellType.createAndFill(); 23020} 23021function getTableNodeTypes(schema) { 23022 if (schema.cached.tableNodeTypes) { 23023 return schema.cached.tableNodeTypes; 23024 } 23025 const roles = {}; 23026 Object.keys(schema.nodes).forEach((type) => { 23027 const nodeType = schema.nodes[type]; 23028 if (nodeType.spec.tableRole) { 23029 roles[nodeType.spec.tableRole] = nodeType; 23030 } 23031 }); 23032 schema.cached.tableNodeTypes = roles; 23033 return roles; 23034} 23035function createTable(schema, rowsCount, colsCount, withHeaderRow, cellContent) { 23036 const types = getTableNodeTypes(schema); 23037 const headerCells = []; 23038 const cells = []; 23039 for (let index = 0; index < colsCount; index += 1) { 23040 const cell = createCell(types.cell, cellContent); 23041 if (cell) { 23042 cells.push(cell); 23043 } 23044 if (withHeaderRow) { 23045 const headerCell = createCell(types.header_cell, cellContent); 23046 if (headerCell) { 23047 headerCells.push(headerCell); 23048 } 23049 } 23050 } 23051 const rows = []; 23052 for (let index = 0; index < rowsCount; index += 1) { 23053 rows.push(types.row.createChecked(null, withHeaderRow && index === 0 ? headerCells : cells)); 23054 } 23055 return types.table.createChecked(null, rows); 23056} 23057function isCellSelection(value) { 23058 return value instanceof CellSelection; 23059} 23060const deleteTableWhenAllCellsSelected = ({ editor }) => { 23061 const { selection } = editor.state; 23062 if (!isCellSelection(selection)) { 23063 return false;
23064 } 23065 let cellCount = 0; 23066 const table = findParentNodeClosestToPos(selection.ranges[0].$from, (node) => { 23067 return node.type.name === "table"; 23068 }); 23069 table === null || table === void 0 ? void 0 : table.node.descendants((node) => { 23070 if (node.type.name === "table") { 23071 return false; 23072 } 23073 if (["tableCell", "tableHeader"].includes(node.type.name)) { 23074 cellCount += 1; 23075 } 23076 }); 23077 const allCellsSelected = cellCount === selection.ranges.length; 23078 if (!allCellsSelected) { 23079 return false; 23080 } 23081 editor.commands.deleteTable(); 23082 return true; 23083}; 23084const Table = Node2.create({ 23085 name: "table", 23086 // @ts-ignore 23087 addOptions() { 23088 return { 23089 HTMLAttributes: {}, 23090 resizable: false, 23091 handleWidth: 5, 23092 cellMinWidth: 25, 23093 // TODO: fix 23094 View: TableView2, 23095 lastColumnResizable: true, 23096 allowTableNodeSelection: false 23097 }; 23098 }, 23099 content: "tableRow+", 23100 tableRole: "table", 23101 isolating: true, 23102 group: "block", 23103 parseHTML() { 23104 return [{ tag: "table" }]; 23105 }, 23106 renderHTML({ node, HTMLAttributes }) { 23107 const { colgroup, tableWidth, tableMinWidth } = createColGroup(node, this.options.cellMinWidth); 23108 const table = [ 23109 "table", 23110 mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { 23111 style: tableWidth ? `width: ${tableWidth}` : `minWidth: ${tableMinWidth}` 23112 }), 23113 colgroup, 23114 ["tbody", 0] 23115 ]; 23116 return table; 23117 }, 23118 addCommands() { 23119 return { 23120 insertTable: ({ rows = 3, cols = 3, withHeaderRow = true } = {}) => ({ tr: tr2, dispatch, editor }) => { 23121 const node = createTable(editor.schema, rows, cols, withHeaderRow); 23122 if (dispatch) { 23123 const offset2 = tr2.selection.anchor + 1; 23124 tr2.replaceSelectionWith(node).scrollIntoView().setSelection(TextSelection.near(tr2.doc.resolve(offset2))); 23125 } 23126 return true; 23127 }, 23128 addColumnBefore: () => ({ state, dispatch }) => { 23129 return addColumnBefore(state, dispatch); 23130 }, 23131 addColumnAfter: () => ({ state, dispatch }) => { 23132 return addColumnAfter(state, dispatch); 23133 }, 23134 deleteColumn: () => ({ state, dispatch }) => { 23135 return deleteColumn(state, dispatch); 23136 }, 23137 addRowBefore: () => ({ state, dispatch }) => { 23138 return addRowBefore(state, dispatch); 23139 }, 23140 addRowAfter: () => ({ state, dispatch }) => { 23141 return addRowAfter(state, dispatch); 23142 }, 23143 deleteRow: () => ({ state, dispatch }) => { 23144 return deleteRow(state, dispatch); 23145 }, 23146 deleteTable: () => ({ state, dispatch }) => { 23147 return deleteTable(state, dispatch); 23148 }, 23149 mergeCells: () => ({ state, dispatch }) => { 23150 return mergeCells(state, dispatch); 23151 }, 23152 splitCell: () => ({ state, dispatch }) => { 23153 return splitCell(state, dispatch); 23154 }, 23155 toggleHeaderColumn: () => ({ state, dispatch }) => { 23156 return toggleHeader("column")(state, dispatch); 23157 }, 23158 toggleHeaderRow: () => ({ state, dispatch }) => { 23159 return toggleHeader("row")(state, dispatch); 23160 }, 23161 toggleHeaderCell: () => ({ state, dispatch }) => { 23162 return toggleHeaderCell(state, dispatch); 23163 }, 23164 mergeOrSplit: () => ({ state, dispatch }) => { 23165 if (mergeCells(state, dispatch)) { 23166 return true; 23167 } 23168 return splitCell(state, dispatch); 23169 }, 23170 setCellAttribute: (name, value) => ({ state, dispatch }) => { 23171 return setCellAttr(name, value)(state, dispatch); 23172 }, 23173 goToNextCell: () => ({ state, dispatch }) => { 23174 return goToNextCell(1)(state, dispatch); 23175 }, 23176 goToPreviousCell: () => ({ state, dispatch }) => { 23177 return goToNextCell(-1)(state, dispatch); 23178 }, 23179 fixTables: () => ({ state, dispatch }) => { 23180 if (dispatch) { 23181 fixTables(state); 23182 } 23183 return true; 23184 }, 23185 setCellSelection: (position) => ({ tr: tr2, dispatch }) => { 23186 if (dispatch) { 23187 const selection = CellSelection.create(tr2.doc, position.anchorCell, position.headCell); 23188 tr2.setSelection(selection); 23189 } 23190 return true; 23191 } 23192 }; 23193 }, 23194 addKeyboardShortcuts() { 23195 return { 23196 Tab: () => { 23197 if (this.editor.commands.goToNextCell()) { 23198 return true; 23199 } 23200 if (!this.editor.can().addRowAfter()) { 23201 return false;
23202 } 23203 return this.editor.chain().addRowAfter().goToNextCell().run(); 23204 }, 23205 "Shift-Tab": () => this.editor.commands.goToPreviousCell(), 23206 Backspace: deleteTableWhenAllCellsSelected, 23207 "Mod-Backspace": deleteTableWhenAllCellsSelected, 23208 Delete: deleteTableWhenAllCellsSelected, 23209 "Mod-Delete": deleteTableWhenAllCellsSelected 23210 }; 23211 }, 23212 addProseMirrorPlugins() { 23213 const isResizable = this.options.resizable && this.editor.isEditable; 23214 return [ 23215 ...isResizable ? [ 23216 columnResizing({ 23217 handleWidth: this.options.handleWidth, 23218 cellMinWidth: this.options.cellMinWidth, 23219 // @ts-ignore (incorrect type) 23220 View: this.options.View, 23221 // TODO: PR for @types/prosemirror-tables 23222 // @ts-ignore (incorrect type) 23223 lastColumnResizable: this.options.lastColumnResizable 23224 }) 23225 ] : [], 23226 tableEditing({ 23227 allowTableNodeSelection: this.options.allowTableNodeSelection 23228 }) 23229 ]; 23230 }, 23231 extendNodeSchema(extension) { 23232 const context = { 23233 name: extension.name, 23234 options: extension.options, 23235 storage: extension.storage 23236 }; 23237 return { 23238 tableRole: callOrReturn(getExtensionField(extension, "tableRole", context)) 23239 }; 23240 } 23241}); 23242const TableCell = Node2.create({ 23243 name: "tableCell", 23244 addOptions() { 23245 return { 23246 HTMLAttributes: {} 23247 }; 23248 }, 23249 content: "block+", 23250 addAttributes() { 23251 return { 23252 colspan: { 23253 default: 1 23254 }, 23255 rowspan: { 23256 default: 1 23257 }, 23258 colwidth: { 23259 default: null, 23260 parseHTML: (element) => { 23261 const colwidth = element.getAttribute("colwidth"); 23262 const value = colwidth ? [parseInt(colwidth, 10)] : null; 23263 return value; 23264 } 23265 } 23266 }; 23267 }, 23268 tableRole: "cell", 23269 isolating: true, 23270 parseHTML() { 23271 return [ 23272 { tag: "td" } 23273 ]; 23274 }, 23275 renderHTML({ HTMLAttributes }) { 23276 return ["td", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 23277 } 23278}); 23279const TableHeader = Node2.create({ 23280 name: "tableHeader", 23281 addOptions() { 23282 return { 23283 HTMLAttributes: {} 23284 }; 23285 }, 23286 content: "block+", 23287 addAttributes() { 23288 return { 23289 colspan: { 23290 default: 1 23291 }, 23292 rowspan: { 23293 default: 1 23294 }, 23295 colwidth: { 23296 default: null, 23297 parseHTML: (element) => { 23298 const colwidth = element.getAttribute("colwidth"); 23299 const value = colwidth ? [parseInt(colwidth, 10)] : null; 23300 return value; 23301 } 23302 } 23303 }; 23304 }, 23305 tableRole: "header_cell", 23306 isolating: true, 23307 parseHTML() { 23308 return [ 23309 { tag: "th" } 23310 ]; 23311 }, 23312 renderHTML({ HTMLAttributes }) { 23313 return ["th", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 23314 } 23315}); 23316const TableRow = Node2.create({ 23317 name: "tableRow", 23318 addOptions() { 23319 return { 23320 HTMLAttributes: {} 23321 }; 23322 }, 23323 content: "(tableCell | tableHeader)*", 23324 tableRole: "row", 23325 parseHTML() { 23326 return [ 23327 { tag: "tr" } 23328 ]; 23329 }, 23330 renderHTML({ HTMLAttributes }) { 23331 return ["tr", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 23332 } 23333}); 23334class GapCursor extends Selection { 23335 /** 23336 Create a gap cursor. 23337 */ 23338 constructor($pos) { 23339 super($pos, $pos); 23340 } 23341 map(doc2, mapping) { 23342 let $pos = doc2.resolve(mapping.map(this.head)); 23343 return GapCursor.valid($pos) ? new GapCursor($pos) : Selection.near($pos); 23344 } 23345 content() { 23346 return Slice.empty; 23347 } 23348 eq(other) { 23349 return other instanceof GapCursor && other.head == this.head; 23350 } 23351 toJSON() { 23352 return { type: "gapcursor", pos: this.head }; 23353 } 23354 /** 23355 @internal 23356 */ 23357 static fromJSON(doc2, json) { 23358 if (typeof json.pos != "number") 23359 throw new RangeError("Invalid input for GapCursor.fromJSON"); 23360 return new GapCursor(doc2.resolve(json.pos)); 23361 } 23362 /** 23363 @internal 23364 */ 23365 getBookmark() { 23366 return new GapBookmark(this.anchor); 23367 } 23368 /** 23369 @internal 23370 */ 23371 static valid($pos) { 23372 let parent = $pos.parent; 23373 if (parent.isTextblock || !closedBefore($pos) || !closedAfter($pos)) 23374 return false; 23375 let override = parent.type.spec.allowGapCursor; 23376 if (override != null) 23377 return override; 23378 let deflt = parent.contentMatchAt($pos.index()).defaultType; 23379 return deflt && deflt.isTextblock; 23380 } 23381 /** 23382 @internal 23383 */ 23384 static findGapCursorFrom($pos, dir, mustMove = false) { 23385 search: 23386 for (; ; ) { 23387 if (!mustMove && GapCursor.valid($pos)) 23388 return $pos; 23389 let pos = $pos.pos, next = null; 23390 for (let d = $pos.depth; ; d--) {
vendor: 4,293 bytes, lines 23391-23524
23391 let parent = $pos.node(d); 23392 if (dir > 0 ? $pos.indexAfter(d) < parent.childCount : $pos.index(d) > 0) { 23393 next = parent.child(dir > 0 ? $pos.indexAfter(d) : $pos.index(d) - 1); 23394 break; 23395 } else if (d == 0) { 23396 return null; 23397 } 23398 pos += dir; 23399 let $cur = $pos.doc.resolve(pos); 23400 if (GapCursor.valid($cur)) 23401 return $cur; 23402 } 23403 for (; ; ) { 23404 let inside = dir > 0 ? next.firstChild : next.lastChild; 23405 if (!inside) { 23406 if (next.isAtom && !next.isText && !NodeSelection.isSelectable(next)) { 23407 $pos = $pos.doc.resolve(pos + next.nodeSize * dir); 23408 mustMove = false; 23409 continue search; 23410 } 23411 break; 23412 } 23413 next = inside; 23414 pos += dir; 23415 let $cur = $pos.doc.resolve(pos); 23416 if (GapCursor.valid($cur)) 23417 return $cur; 23418 } 23419 return null; 23420 } 23421 } 23422} 23423GapCursor.prototype.visible = false; 23424GapCursor.findFrom = GapCursor.findGapCursorFrom; 23425Selection.jsonID("gapcursor", GapCursor); 23426class GapBookmark { 23427 constructor(pos) { 23428 this.pos = pos; 23429 } 23430 map(mapping) { 23431 return new GapBookmark(mapping.map(this.pos)); 23432 } 23433 resolve(doc2) { 23434 let $pos = doc2.resolve(this.pos); 23435 return GapCursor.valid($pos) ? new GapCursor($pos) : Selection.near($pos); 23436 } 23437} 23438function closedBefore($pos) { 23439 for (let d = $pos.depth; d >= 0; d--) { 23440 let index = $pos.index(d), parent = $pos.node(d); 23441 if (index == 0) { 23442 if (parent.type.spec.isolating) 23443 return true; 23444 continue; 23445 } 23446 for (let before = parent.child(index - 1); ; before = before.lastChild) { 23447 if (before.childCount == 0 && !before.inlineContent || before.isAtom || before.type.spec.isolating) 23448 return true; 23449 if (before.inlineContent) 23450 return false; 23451 } 23452 } 23453 return true; 23454} 23455function closedAfter($pos) { 23456 for (let d = $pos.depth; d >= 0; d--) { 23457 let index = $pos.indexAfter(d), parent = $pos.node(d); 23458 if (index == parent.childCount) { 23459 if (parent.type.spec.isolating) 23460 return true; 23461 continue; 23462 } 23463 for (let after = parent.child(index); ; after = after.firstChild) { 23464 if (after.childCount == 0 && !after.inlineContent || after.isAtom || after.type.spec.isolating) 23465 return true; 23466 if (after.inlineContent) 23467 return false; 23468 } 23469 } 23470 return true; 23471} 23472function gapCursor() { 23473 return new Plugin({ 23474 props: { 23475 decorations: drawGapCursor, 23476 createSelectionBetween(_view, $anchor, $head) { 23477 return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null; 23478 }, 23479 handleClick, 23480 handleKeyDown, 23481 handleDOMEvents: { beforeinput } 23482 } 23483 }); 23484} 23485const handleKeyDown = keydownHandler({ 23486 "ArrowLeft": arrow("horiz", -1), 23487 "ArrowRight": arrow("horiz", 1), 23488 "ArrowUp": arrow("vert", -1), 23489 "ArrowDown": arrow("vert", 1) 23490}); 23491function arrow(axis, dir) { 23492 const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left"; 23493 return function(state, dispatch, view) { 23494 let sel = state.selection; 23495 let $start = dir > 0 ? sel.$to : sel.$from, mustMove = sel.empty; 23496 if (sel instanceof TextSelection) { 23497 if (!view.endOfTextblock(dirStr) || $start.depth == 0) 23498 return false; 23499 mustMove = false; 23500 $start = state.doc.resolve(dir > 0 ? $start.after() : $start.before()); 23501 } 23502 let $found = GapCursor.findGapCursorFrom($start, dir, mustMove); 23503 if (!$found) 23504 return false; 23505 if (dispatch) 23506 dispatch(state.tr.setSelection(new GapCursor($found))); 23507 return true; 23508 }; 23509} 23510function handleClick(view, pos, event) { 23511 if (!view || !view.editable) 23512 return false; 23513 let $pos = view.state.doc.resolve(pos); 23514 if (!GapCursor.valid($pos)) 23515 return false; 23516 let clickPos = view.posAtCoords({ left: event.clientX, top: event.clientY }); 23517 if (clickPos && clickPos.inside > -1 && NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside))) 23518 return false; 23519 view.dispatch(view.state.tr.setSelection(new GapCursor($pos))); 23520 return true; 23521} 23522function beforeinput(view, event) { 23523 if (event.inputType != "insertCompositionText" || !(view.state.selection instanceof GapCursor)) 23524 return false;
23525 let { $from } = view.state.selection; 23526 let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text); 23527 if (!insert) 23528 return false; 23529 let frag = Fragment.empty; 23530 for (let i = insert.length - 1; i >= 0; i--) 23531 frag = Fragment.from(insert[i].createAndFill(null, frag)); 23532 let tr2 = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0)); 23533 tr2.setSelection(TextSelection.near(tr2.doc.resolve($from.pos + 1))); 23534 view.dispatch(tr2); 23535 return false; 23536} 23537function drawGapCursor(state) { 23538 if (!(state.selection instanceof GapCursor)) 23539 return null; 23540 let node = document.createElement("div"); 23541 node.className = "ProseMirror-gapcursor"; 23542 return DecorationSet.create(state.doc, [Decoration.widget(state.selection.head, node, { key: "gapcursor" })]); 23543} 23544const Gapcursor = Extension.create({ 23545 name: "gapCursor", 23546 addProseMirrorPlugins() { 23547 return [ 23548 gapCursor() 23549 ]; 23550 }, 23551 extendNodeSchema(extension) { 23552 var _a; 23553 const context = { 23554 name: extension.name, 23555 options: extension.options, 23556 storage: extension.storage 23557 }; 23558 return { 23559 allowGapCursor: (_a = callOrReturn(getExtensionField(extension, "allowGapCursor", context))) !== null && _a !== void 0 ? _a : null 23560 }; 23561 } 23562}); 23563const Heading = Node2.create({ 23564 name: "heading", 23565 addOptions() { 23566 return { 23567 levels: [1, 2, 3, 4, 5, 6], 23568 HTMLAttributes: {} 23569 }; 23570 }, 23571 content: "inline*", 23572 group: "block", 23573 defining: true, 23574 addAttributes() { 23575 return { 23576 level: { 23577 default: 1, 23578 rendered: false 23579 } 23580 }; 23581 }, 23582 parseHTML() { 23583 return this.options.levels.map((level) => ({ 23584 tag: `h${level}`, 23585 attrs: { level } 23586 })); 23587 }, 23588 renderHTML({ node, HTMLAttributes }) { 23589 const hasLevel = this.options.levels.includes(node.attrs.level); 23590 const level = hasLevel ? node.attrs.level : this.options.levels[0]; 23591 return [`h${level}`, mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; 23592 }, 23593 addCommands() { 23594 return { 23595 setHeading: (attributes) => ({ commands: commands2 }) => { 23596 if (!this.options.levels.includes(attributes.level)) { 23597 return false; 23598 } 23599 return commands2.setNode(this.name, attributes); 23600 }, 23601 toggleHeading: (attributes) => ({ commands: commands2 }) => { 23602 if (!this.options.levels.includes(attributes.level)) { 23603 return false; 23604 } 23605 return commands2.toggleNode(this.name, "paragraph", attributes); 23606 } 23607 }; 23608 }, 23609 addKeyboardShortcuts() { 23610 return this.options.levels.reduce((items, level) => ({ 23611 ...items, 23612 ...{ 23613 [`Mod-Alt-${level}`]: () => this.editor.commands.toggleHeading({ level }) 23614 } 23615 }), {}); 23616 }, 23617 addInputRules() { 23618 return this.options.levels.map((level) => { 23619 return textblockTypeInputRule({ 23620 find: new RegExp(`^(#{1,${level}})\\s$`), 23621 type: this.type, 23622 getAttributes: { 23623 level 23624 } 23625 }); 23626 }); 23627 } 23628}); 23629const FontFamily = Extension.create({ 23630 name: "fontFamily", 23631 addOptions() { 23632 return { 23633 types: ["textStyle"] 23634 }; 23635 }, 23636 addGlobalAttributes() { 23637 return [ 23638 { 23639 types: this.options.types, 23640 attributes: { 23641 fontFamily: { 23642 default: null, 23643 parseHTML: (element) => { 23644 var _a; 23645 return (_a = element.style.fontFamily) === null || _a === void 0 ? void 0 : _a.replace(/['"]+/g, ""); 23646 }, 23647 renderHTML: (attributes) => { 23648 if (!attributes.fontFamily) { 23649 return {}; 23650 } 23651 return { 23652 style: `font-family: ${attributes.fontFamily.split(",").map((fontFamily) => CSS.escape(fontFamily.trim())).join(", ")}` 23653 }; 23654 } 23655 } 23656 } 23657 } 23658 ]; 23659 }, 23660 addCommands() { 23661 return { 23662 setFontFamily: (fontFamily) => ({ chain }) => { 23663 return chain().setMark("textStyle", { fontFamily }).run(); 23664 }, 23665 unsetFontFamily: () => ({ chain }) => { 23666 return chain().setMark("textStyle", { fontFamily: null }).removeEmptyTextStyle().run(); 23667 } 23668 }; 23669 } 23670}); 23671const emDash = (override) => textInputRule({ 23672 find: /--$/, 23673 replace: override !== null && override !== void 0 ? override : "â" 23674}); 23675const ellipsis = (override) => textInputRule({ 23676 find: /\.\.\.$/, 23677 replace: override !== null && override !== void 0 ? override : "â¦" 23678}); 23679const openDoubleQuote = (override) => textInputRule({ 23680 find: /(?:^|[\s{[(<'"\u2018\u201C])(")$/, 23681 replace: override !== null && override !== void 0 ? override : "â" 23682}); 23683const closeDoubleQuote = (override) => textInputRule({ 23684 find: /"$/, 23685 replace: override !== null && override !== void 0 ? override : "â" 23686}); 23687const openSingleQuote = (override) => textInputRule({ 23688 find: /(?:^|[\s{[(<'"\u2018\u201C])(')$/, 23689 replace: override !== null && override !== void 0 ? override : "â" 23690}); 23691const closeSingleQuote = (override) => textInputRule({ 23692 find: /'$/, 23693 replace: override !== null && override !== void 0 ? override : "â" 23694}); 23695const leftArrow = (override) => textInputRule({ 23696 find: /<-$/, 23697 replace: override !== null && override !== void 0 ? override : "â" 23698}); 23699const rightArrow = (override) => textInputRule({ 23700 find: /->$/, 23701 replace: override !== null && override !== void 0 ? override : "â" 23702}); 23703const copyright = (override) => textInputRule({ 23704 find: /\(c\)$/,
23705 replace: override !== null && override !== void 0 ? override : "©" 23706}); 23707const trademark = (override) => textInputRule({ 23708 find: /\(tm\)$/, 23709 replace: override !== null && override !== void 0 ? override : "â¢" 23710}); 23711const servicemark = (override) => textInputRule({ 23712 find: /\(sm\)$/, 23713 replace: override !== null && override !== void 0 ? override : "â " 23714}); 23715const registeredTrademark = (override) => textInputRule({ 23716 find: /\(r\)$/, 23717 replace: override !== null && override !== void 0 ? override : "®" 23718}); 23719const oneHalf = (override) => textInputRule({ 23720 find: /(?:^|\s)(1\/2)\s$/, 23721 replace: override !== null && override !== void 0 ? override : "½" 23722}); 23723const plusMinus = (override) => textInputRule({ 23724 find: /\+\/-$/, 23725 replace: override !== null && override !== void 0 ? override : "±" 23726}); 23727const notEqual = (override) => textInputRule({ 23728 find: /!=$/, 23729 replace: override !== null && override !== void 0 ? override : "â " 23730}); 23731const laquo = (override) => textInputRule({ 23732 find: /<<$/, 23733 replace: override !== null && override !== void 0 ? override : "«" 23734}); 23735const raquo = (override) => textInputRule({ 23736 find: />>$/, 23737 replace: override !== null && override !== void 0 ? override : "»" 23738}); 23739const multiplication = (override) => textInputRule({ 23740 find: /\d+\s?([*x])\s?\d+$/, 23741 replace: override !== null && override !== void 0 ? override : "Ã" 23742}); 23743const superscriptTwo = (override) => textInputRule({ 23744 find: /\^2$/, 23745 replace: override !== null && override !== void 0 ? override : "²" 23746}); 23747const superscriptThree = (override) => textInputRule({ 23748 find: /\^3$/, 23749 replace: override !== null && override !== void 0 ? override : "³" 23750}); 23751const oneQuarter = (override) => textInputRule({ 23752 find: /(?:^|\s)(1\/4)\s$/, 23753 replace: override !== null && override !== void 0 ? override : "¼" 23754}); 23755const threeQuarters = (override) => textInputRule({ 23756 find: /(?:^|\s)(3\/4)\s$/, 23757 replace: override !== null && override !== void 0 ? override : "¾" 23758}); 23759const Typography = Extension.create({ 23760 name: "typography", 23761 addOptions() { 23762 return { 23763 closeDoubleQuote: "â", 23764 closeSingleQuote: "â", 23765 copyright: "©", 23766 ellipsis: "â¦", 23767 emDash: "â", 23768 laquo: "«", 23769 leftArrow: "â", 23770 multiplication: "Ã", 23771 notEqual: "â ", 23772 oneHalf: "½", 23773 oneQuarter: "¼", 23774 openDoubleQuote: "â", 23775 openSingleQuote: "â", 23776 plusMinus: "±", 23777 raquo: "»", 23778 registeredTrademark: "®", 23779 rightArrow: "â", 23780 servicemark: "â ", 23781 superscriptThree: "³", 23782 superscriptTwo: "²", 23783 threeQuarters: "¾", 23784 trademark: "â¢" 23785 }; 23786 }, 23787 addInputRules() { 23788 const rules = []; 23789 if (this.options.emDash !== false) { 23790 rules.push(emDash(this.options.emDash)); 23791 } 23792 if (this.options.ellipsis !== false) { 23793 rules.push(ellipsis(this.options.ellipsis)); 23794 } 23795 if (this.options.openDoubleQuote !== false) { 23796 rules.push(openDoubleQuote(this.options.openDoubleQuote)); 23797 } 23798 if (this.options.closeDoubleQuote !== false) { 23799 rules.push(closeDoubleQuote(this.options.closeDoubleQuote)); 23800 } 23801 if (this.options.openSingleQuote !== false) { 23802 rules.push(openSingleQuote(this.options.openSingleQuote)); 23803 } 23804 if (this.options.closeSingleQuote !== false) { 23805 rules.push(closeSingleQuote(this.options.closeSingleQuote)); 23806 } 23807 if (this.options.leftArrow !== false) { 23808 rules.push(leftArrow(this.options.leftArrow)); 23809 } 23810 if (this.options.rightArrow !== false) { 23811 rules.push(rightArrow(this.options.rightArrow)); 23812 } 23813 if (this.options.copyright !== false) { 23814 rules.push(copyright(this.options.copyright)); 23815 } 23816 if (this.options.trademark !== false) { 23817 rules.push(trademark(this.options.trademark)); 23818 } 23819 if (this.options.servicemark !== false) { 23820 rules.push(servicemark(this.options.servicemark)); 23821 } 23822 if (this.options.registeredTrademark !== false) { 23823 rules.push(registeredTrademark(this.options.registeredTrademark)); 23824 } 23825 if (this.options.oneHalf !== false) { 23826 rules.push(oneHalf(this.options.oneHalf)); 23827 } 23828 if (this.options.plusMinus !== false) { 23829 rules.push(plusMinus(this.options.plusMinus)); 23830 } 23831 if (this.options.notEqual !== false) { 23832 rules.push(notEqual(this.options.notEqual)); 23833 } 23834 if (this.options.laquo !== false) { 23835 rules.push(laquo(this.options.laquo)); 23836 } 23837 if (this.options.raquo !== false) { 23838 rules.push(raquo(this.options.raquo)); 23839 } 23840 if (this.options.multiplication !== false) { 23841 rules.push(multiplication(this.options.multiplication)); 23842 } 23843 if (this.options.superscriptTwo !== false) { 23844 rules.push(superscriptTwo(this.options.superscriptTwo)); 23845 } 23846 if (this.options.superscriptThree !== false) { 23847 rules.push(superscriptThree(this.options.superscriptThree)); 23848 } 23849 if (this.options.oneQuarter !== false) { 23850 rules.push(oneQuarter(this.options.oneQuarter)); 23851 } 23852 if (this.options.threeQuarters !== false) { 23853 rules.push(threeQuarters(this.options.threeQuarters)); 23854 } 23855 return rules; 23856 } 23857}); 23858const TextAlign = Extension.create({ 23859 name: "textAlign", 23860 addOptions() { 23861 return { 23862 types: [], 23863 alignments: ["left", "center", "right", "justify"], 23864 defaultAlignment: "left" 23865 }; 23866 }, 23867 addGlobalAttributes() { 23868 return [ 23869 { 23870 types: this.options.types, 23871 attributes: { 23872 textAlign: { 23873 default: this.options.defaultAlignment, 23874 parseHTML: (element) => element.style.textAlign || this.options.defaultAlignment, 23875 renderHTML: (attributes) => { 23876 if (attributes.textAlign === this.options.defaultAlignment) { 23877 return {}; 23878 } 23879 return { style: `text-align: ${attributes.textAlign}` }; 23880 } 23881 } 23882 } 23883 } 23884 ]; 23885 }, 23886 addCommands() { 23887 return { 23888 setTextAlign: (alignment) => ({ commands: commands2 }) => { 23889 if (!this.options.alignments.includes(alignment)) { 23890 return false;
23891 } 23892 return this.options.types.map((type) => commands2.updateAttributes(type, { textAlign: alignment })).every((response) => response); 23893 }, 23894 unsetTextAlign: () => ({ commands: commands2 }) => { 23895 return this.options.types.map((type) => commands2.resetAttributes(type, "textAlign")).every((response) => response); 23896 } 23897 }; 23898 }, 23899 addKeyboardShortcuts() { 23900 return { 23901 "Mod-Shift-l": () => this.editor.commands.setTextAlign("left"), 23902 "Mod-Shift-e": () => this.editor.commands.setTextAlign("center"), 23903 "Mod-Shift-r": () => this.editor.commands.setTextAlign("right"), 23904 "Mod-Shift-j": () => this.editor.commands.setTextAlign("justify") 23905 }; 23906 } 23907}); 23908var GOOD_LEAF_SIZE = 200; 23909var RopeSequence = function RopeSequence2() { 23910}; 23911RopeSequence.prototype.append = function append(other) { 23912 if (!other.length) { 23913 return this; 23914 } 23915 other = RopeSequence.from(other); 23916 return !this.length && other || other.length < GOOD_LEAF_SIZE && this.leafAppend(other) || this.length < GOOD_LEAF_SIZE && other.leafPrepend(this) || this.appendInner(other); 23917}; 23918RopeSequence.prototype.prepend = function prepend(other) { 23919 if (!other.length) { 23920 return this; 23921 } 23922 return RopeSequence.from(other).append(this); 23923}; 23924RopeSequence.prototype.appendInner = function appendInner(other) { 23925 return new Append(this, other); 23926}; 23927RopeSequence.prototype.slice = function slice(from2, to) { 23928 if (from2 === void 0) 23929 from2 = 0; 23930 if (to === void 0) 23931 to = this.length; 23932 if (from2 >= to) { 23933 return RopeSequence.empty; 23934 } 23935 return this.sliceInner(Math.max(0, from2), Math.min(this.length, to)); 23936}; 23937RopeSequence.prototype.get = function get(i) { 23938 if (i < 0 || i >= this.length) { 23939 return void 0; 23940 } 23941 return this.getInner(i); 23942}; 23943RopeSequence.prototype.forEach = function forEach2(f, from2, to) { 23944 if (from2 === void 0) 23945 from2 = 0; 23946 if (to === void 0) 23947 to = this.length; 23948 if (from2 <= to) { 23949 this.forEachInner(f, from2, to, 0); 23950 } else { 23951 this.forEachInvertedInner(f, from2, to, 0); 23952 } 23953}; 23954RopeSequence.prototype.map = function map(f, from2, to) { 23955 if (from2 === void 0) 23956 from2 = 0; 23957 if (to === void 0) 23958 to = this.length; 23959 var result = []; 23960 this.forEach(function(elt, i) { 23961 return result.push(f(elt, i)); 23962 }, from2, to); 23963 return result; 23964}; 23965RopeSequence.from = function from(values) { 23966 if (values instanceof RopeSequence) { 23967 return values; 23968 } 23969 return values && values.length ? new Leaf(values) : RopeSequence.empty; 23970}; 23971var Leaf = /* @__PURE__ */ function(RopeSequence3) { 23972 function Leaf2(values) { 23973 RopeSequence3.call(this); 23974 this.values = values; 23975 } 23976 if (RopeSequence3) 23977 Leaf2.__proto__ = RopeSequence3; 23978 Leaf2.prototype = Object.create(RopeSequence3 && RopeSequence3.prototype); 23979 Leaf2.prototype.constructor = Leaf2; 23980 var prototypeAccessors = { length: { configurable: true }, depth: { configurable: true } }; 23981 Leaf2.prototype.flatten = function flatten() { 23982 return this.values; 23983 }; 23984 Leaf2.prototype.sliceInner = function sliceInner(from2, to) { 23985 if (from2 == 0 && to == this.length) { 23986 return this; 23987 } 23988 return new Leaf2(this.values.slice(from2, to)); 23989 }; 23990 Leaf2.prototype.getInner = function getInner(i) { 23991 return this.values[i]; 23992 }; 23993 Leaf2.prototype.forEachInner = function forEachInner(f, from2, to, start2) { 23994 for (var i = from2; i < to; i++) { 23995 if (f(this.values[i], start2 + i) === false) { 23996 return false; 23997 } 23998 } 23999 }; 24000 Leaf2.prototype.forEachInvertedInner = function forEachInvertedInner(f, from2, to, start2) { 24001 for (var i = from2 - 1; i >= to; i--) { 24002 if (f(this.values[i], start2 + i) === false) { 24003 return false; 24004 } 24005 } 24006 }; 24007 Leaf2.prototype.leafAppend = function leafAppend(other) { 24008 if (this.length + other.length <= GOOD_LEAF_SIZE) { 24009 return new Leaf2(this.values.concat(other.flatten())); 24010 } 24011 }; 24012 Leaf2.prototype.leafPrepend = function leafPrepend(other) { 24013 if (this.length + other.length <= GOOD_LEAF_SIZE) { 24014 return new Leaf2(other.flatten().concat(this.values)); 24015 } 24016 }; 24017 prototypeAccessors.length.get = function() { 24018 return this.values.length; 24019 }; 24020 prototypeAccessors.depth.get = function() { 24021 return 0; 24022 }; 24023 Object.defineProperties(Leaf2.prototype, prototypeAccessors); 24024 return Leaf2; 24025}(RopeSequence); 24026RopeSequence.empty = new Leaf([]); 24027var Append = /* @__PURE__ */ function(RopeSequence3) { 24028 function Append2(left2, right2) { 24029 RopeSequence3.call(this); 24030 this.left = left2; 24031 this.right = right2;
24032 this.length = left2.length + right2.length; 24033 this.depth = Math.max(left2.depth, right2.depth) + 1; 24034 } 24035 if (RopeSequence3) 24036 Append2.__proto__ = RopeSequence3; 24037 Append2.prototype = Object.create(RopeSequence3 && RopeSequence3.prototype); 24038 Append2.prototype.constructor = Append2; 24039 Append2.prototype.flatten = function flatten() { 24040 return this.left.flatten().concat(this.right.flatten()); 24041 }; 24042 Append2.prototype.getInner = function getInner(i) { 24043 return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length); 24044 }; 24045 Append2.prototype.forEachInner = function forEachInner(f, from2, to, start2) { 24046 var leftLen = this.left.length; 24047 if (from2 < leftLen && this.left.forEachInner(f, from2, Math.min(to, leftLen), start2) === false) { 24048 return false; 24049 } 24050 if (to > leftLen && this.right.forEachInner(f, Math.max(from2 - leftLen, 0), Math.min(this.length, to) - leftLen, start2 + leftLen) === false) { 24051 return false; 24052 } 24053 }; 24054 Append2.prototype.forEachInvertedInner = function forEachInvertedInner(f, from2, to, start2) { 24055 var leftLen = this.left.length; 24056 if (from2 > leftLen && this.right.forEachInvertedInner(f, from2 - leftLen, Math.max(to, leftLen) - leftLen, start2 + leftLen) === false) { 24057 return false; 24058 } 24059 if (to < leftLen && this.left.forEachInvertedInner(f, Math.min(from2, leftLen), to, start2) === false) { 24060 return false; 24061 } 24062 }; 24063 Append2.prototype.sliceInner = function sliceInner(from2, to) { 24064 if (from2 == 0 && to == this.length) { 24065 return this; 24066 } 24067 var leftLen = this.left.length; 24068 if (to <= leftLen) { 24069 return this.left.slice(from2, to); 24070 } 24071 if (from2 >= leftLen) { 24072 return this.right.slice(from2 - leftLen, to - leftLen); 24073 } 24074 return this.left.slice(from2, leftLen).append(this.right.slice(0, to - leftLen)); 24075 }; 24076 Append2.prototype.leafAppend = function leafAppend(other) { 24077 var inner = this.right.leafAppend(other); 24078 if (inner) { 24079 return new Append2(this.left, inner); 24080 } 24081 }; 24082 Append2.prototype.leafPrepend = function leafPrepend(other) { 24083 var inner = this.left.leafPrepend(other); 24084 if (inner) { 24085 return new Append2(inner, this.right); 24086 } 24087 }; 24088 Append2.prototype.appendInner = function appendInner2(other) { 24089 if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1) { 24090 return new Append2(this.left, new Append2(this.right, other)); 24091 } 24092 return new Append2(this, other); 24093 }; 24094 return Append2; 24095}(RopeSequence); 24096const max_empty_items = 500; 24097class Branch { 24098 constructor(items, eventCount) { 24099 this.items = items; 24100 this.eventCount = eventCount; 24101 } 24102 // Pop the latest event off the branch's history and apply it 24103 // to a document transform. 24104 popEvent(state, preserveItems) { 24105 if (this.eventCount == 0) 24106 return null; 24107 let end2 = this.items.length; 24108 for (; ; end2--) { 24109 let next = this.items.get(end2 - 1); 24110 if (next.selection) { 24111 --end2; 24112 break; 24113 } 24114 } 24115 let remap, mapFrom; 24116 if (preserveItems) { 24117 remap = this.remapping(end2, this.items.length); 24118 mapFrom = remap.maps.length; 24119 } 24120 let transform = state.tr; 24121 let selection, remaining; 24122 let addAfter = [], addBefore = []; 24123 this.items.forEach((item, i) => { 24124 if (!item.step) { 24125 if (!remap) { 24126 remap = this.remapping(end2, i + 1); 24127 mapFrom = remap.maps.length; 24128 } 24129 mapFrom--; 24130 addBefore.push(item); 24131 return; 24132 } 24133 if (remap) { 24134 addBefore.push(new Item(item.map)); 24135 let step = item.step.map(remap.slice(mapFrom)), map2; 24136 if (step && transform.maybeStep(step).doc) { 24137 map2 = transform.mapping.maps[transform.mapping.maps.length - 1]; 24138 addAfter.push(new Item(map2, void 0, void 0, addAfter.length + addBefore.length)); 24139 } 24140 mapFrom--; 24141 if (map2) 24142 remap.appendMap(map2, mapFrom); 24143 } else { 24144 transform.maybeStep(item.step); 24145 } 24146 if (item.selection) { 24147 selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection; 24148 remaining = new Branch(this.items.slice(0, end2).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1); 24149 return false;
24150 } 24151 }, this.items.length, 0); 24152 return { remaining, transform, selection }; 24153 } 24154 // Create a new branch with the given transform added. 24155 addTransform(transform, selection, histOptions, preserveItems) { 24156 let newItems = [], eventCount = this.eventCount; 24157 let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null; 24158 for (let i = 0; i < transform.steps.length; i++) { 24159 let step = transform.steps[i].invert(transform.docs[i]); 24160 let item = new Item(transform.mapping.maps[i], step, selection), merged; 24161 if (merged = lastItem && lastItem.merge(item)) { 24162 item = merged; 24163 if (i) 24164 newItems.pop(); 24165 else 24166 oldItems = oldItems.slice(0, oldItems.length - 1); 24167 } 24168 newItems.push(item); 24169 if (selection) { 24170 eventCount++; 24171 selection = void 0; 24172 } 24173 if (!preserveItems) 24174 lastItem = item; 24175 } 24176 let overflow = eventCount - histOptions.depth; 24177 if (overflow > DEPTH_OVERFLOW) { 24178 oldItems = cutOffEvents(oldItems, overflow); 24179 eventCount -= overflow; 24180 } 24181 return new Branch(oldItems.append(newItems), eventCount); 24182 } 24183 remapping(from2, to) { 24184 let maps = new Mapping(); 24185 this.items.forEach((item, i) => { 24186 let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from2 ? maps.maps.length - item.mirrorOffset : void 0; 24187 maps.appendMap(item.map, mirrorPos); 24188 }, from2, to); 24189 return maps; 24190 } 24191 addMaps(array) { 24192 if (this.eventCount == 0) 24193 return this; 24194 return new Branch(this.items.append(array.map((map2) => new Item(map2))), this.eventCount); 24195 } 24196 // When the collab module receives remote changes, the history has 24197 // to know about those, so that it can adjust the steps that were 24198 // rebased on top of the remote changes, and include the position 24199 // maps for the remote changes in its array of items. 24200 rebased(rebasedTransform, rebasedCount) { 24201 if (!this.eventCount) 24202 return this; 24203 let rebasedItems = [], start2 = Math.max(0, this.items.length - rebasedCount); 24204 let mapping = rebasedTransform.mapping; 24205 let newUntil = rebasedTransform.steps.length; 24206 let eventCount = this.eventCount; 24207 this.items.forEach((item) => { 24208 if (item.selection) 24209 eventCount--; 24210 }, start2); 24211 let iRebased = rebasedCount; 24212 this.items.forEach((item) => { 24213 let pos = mapping.getMirror(--iRebased); 24214 if (pos == null) 24215 return; 24216 newUntil = Math.min(newUntil, pos); 24217 let map2 = mapping.maps[pos]; 24218 if (item.step) { 24219 let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]); 24220 let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos)); 24221 if (selection) 24222 eventCount++; 24223 rebasedItems.push(new Item(map2, step, selection)); 24224 } else { 24225 rebasedItems.push(new Item(map2)); 24226 } 24227 }, start2); 24228 let newMaps = []; 24229 for (let i = rebasedCount; i < newUntil; i++) 24230 newMaps.push(new Item(mapping.maps[i])); 24231 let items = this.items.slice(0, start2).append(newMaps).append(rebasedItems); 24232 let branch = new Branch(items, eventCount); 24233 if (branch.emptyItemCount() > max_empty_items) 24234 branch = branch.compress(this.items.length - rebasedItems.length); 24235 return branch; 24236 } 24237 emptyItemCount() {
vendor: 3,499 bytes, lines 24238-24331
24238 let count = 0; 24239 this.items.forEach((item) => { 24240 if (!item.step) 24241 count++; 24242 }); 24243 return count; 24244 } 24245 // Compressing a branch means rewriting it to push the air (map-only 24246 // items) out. During collaboration, these naturally accumulate 24247 // because each remote change adds one. The `upto` argument is used 24248 // to ensure that only the items below a given level are compressed, 24249 // because `rebased` relies on a clean, untouched set of items in 24250 // order to associate old items with rebased steps. 24251 compress(upto = this.items.length) { 24252 let remap = this.remapping(0, upto), mapFrom = remap.maps.length; 24253 let items = [], events = 0; 24254 this.items.forEach((item, i) => { 24255 if (i >= upto) { 24256 items.push(item); 24257 if (item.selection) 24258 events++; 24259 } else if (item.step) { 24260 let step = item.step.map(remap.slice(mapFrom)), map2 = step && step.getMap(); 24261 mapFrom--; 24262 if (map2) 24263 remap.appendMap(map2, mapFrom); 24264 if (step) { 24265 let selection = item.selection && item.selection.map(remap.slice(mapFrom)); 24266 if (selection) 24267 events++; 24268 let newItem = new Item(map2.invert(), step, selection), merged, last = items.length - 1; 24269 if (merged = items.length && items[last].merge(newItem)) 24270 items[last] = merged; 24271 else 24272 items.push(newItem); 24273 } 24274 } else if (item.map) { 24275 mapFrom--; 24276 } 24277 }, this.items.length, 0); 24278 return new Branch(RopeSequence.from(items.reverse()), events); 24279 } 24280} 24281Branch.empty = new Branch(RopeSequence.empty, 0); 24282function cutOffEvents(items, n) { 24283 let cutPoint; 24284 items.forEach((item, i) => { 24285 if (item.selection && n-- == 0) { 24286 cutPoint = i; 24287 return false; 24288 } 24289 }); 24290 return items.slice(cutPoint); 24291} 24292class Item { 24293 constructor(map2, step, selection, mirrorOffset) { 24294 this.map = map2; 24295 this.step = step; 24296 this.selection = selection; 24297 this.mirrorOffset = mirrorOffset; 24298 } 24299 merge(other) { 24300 if (this.step && other.step && !other.selection) { 24301 let step = other.step.merge(this.step); 24302 if (step) 24303 return new Item(step.getMap().invert(), step, this.selection); 24304 } 24305 } 24306} 24307class HistoryState { 24308 constructor(done, undone, prevRanges, prevTime, prevComposition) { 24309 this.done = done; 24310 this.undone = undone; 24311 this.prevRanges = prevRanges; 24312 this.prevTime = prevTime; 24313 this.prevComposition = prevComposition; 24314 } 24315} 24316const DEPTH_OVERFLOW = 20; 24317function applyTransaction(history2, state, tr2, options) { 24318 let historyTr = tr2.getMeta(historyKey), rebased; 24319 if (historyTr) 24320 return historyTr.historyState; 24321 if (tr2.getMeta(closeHistoryKey)) 24322 history2 = new HistoryState(history2.done, history2.undone, null, 0, -1); 24323 let appended = tr2.getMeta("appendedTransaction"); 24324 if (tr2.steps.length == 0) { 24325 return history2; 24326 } else if (appended && appended.getMeta(historyKey)) { 24327 if (appended.getMeta(historyKey).redo) 24328 return new HistoryState(history2.done.addTransform(tr2, void 0, options, mustPreserveItems(state)), history2.undone, rangesFor(tr2.mapping.maps[tr2.steps.length - 1]), history2.prevTime, history2.prevComposition); 24329 else 24330 return new HistoryState(history2.done, history2.undone.addTransform(tr2, void 0, options, mustPreserveItems(state)), null, history2.prevTime, history2.prevComposition); 24331 } else if (tr2.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) {
vendor: 4,115 bytes, lines 24332-24432
24332 let composition = tr2.getMeta("composition"); 24333 let newGroup = history2.prevTime == 0 || !appended && history2.prevComposition != composition && (history2.prevTime < (tr2.time || 0) - options.newGroupDelay || !isAdjacentTo(tr2, history2.prevRanges)); 24334 let prevRanges = appended ? mapRanges(history2.prevRanges, tr2.mapping) : rangesFor(tr2.mapping.maps[tr2.steps.length - 1]); 24335 return new HistoryState(history2.done.addTransform(tr2, newGroup ? state.selection.getBookmark() : void 0, options, mustPreserveItems(state)), Branch.empty, prevRanges, tr2.time, composition == null ? history2.prevComposition : composition); 24336 } else if (rebased = tr2.getMeta("rebased")) { 24337 return new HistoryState(history2.done.rebased(tr2, rebased), history2.undone.rebased(tr2, rebased), mapRanges(history2.prevRanges, tr2.mapping), history2.prevTime, history2.prevComposition); 24338 } else { 24339 return new HistoryState(history2.done.addMaps(tr2.mapping.maps), history2.undone.addMaps(tr2.mapping.maps), mapRanges(history2.prevRanges, tr2.mapping), history2.prevTime, history2.prevComposition); 24340 } 24341} 24342function isAdjacentTo(transform, prevRanges) { 24343 if (!prevRanges) 24344 return false; 24345 if (!transform.docChanged) 24346 return true; 24347 let adjacent = false; 24348 transform.mapping.maps[0].forEach((start2, end2) => { 24349 for (let i = 0; i < prevRanges.length; i += 2) 24350 if (start2 <= prevRanges[i + 1] && end2 >= prevRanges[i]) 24351 adjacent = true; 24352 }); 24353 return adjacent; 24354} 24355function rangesFor(map2) { 24356 let result = []; 24357 map2.forEach((_from, _to, from2, to) => result.push(from2, to)); 24358 return result; 24359} 24360function mapRanges(ranges, mapping) { 24361 if (!ranges) 24362 return null; 24363 let result = []; 24364 for (let i = 0; i < ranges.length; i += 2) { 24365 let from2 = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1); 24366 if (from2 <= to) 24367 result.push(from2, to); 24368 } 24369 return result; 24370} 24371function histTransaction(history2, state, redo2) { 24372 let preserveItems = mustPreserveItems(state); 24373 let histOptions = historyKey.get(state).spec.config; 24374 let pop = (redo2 ? history2.undone : history2.done).popEvent(state, preserveItems); 24375 if (!pop) 24376 return null; 24377 let selection = pop.selection.resolve(pop.transform.doc); 24378 let added = (redo2 ? history2.done : history2.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems); 24379 let newHist = new HistoryState(redo2 ? added : pop.remaining, redo2 ? pop.remaining : added, null, 0, -1); 24380 return pop.transform.setSelection(selection).setMeta(historyKey, { redo: redo2, historyState: newHist }); 24381} 24382let cachedPreserveItems = false, cachedPreserveItemsPlugins = null; 24383function mustPreserveItems(state) { 24384 let plugins = state.plugins; 24385 if (cachedPreserveItemsPlugins != plugins) { 24386 cachedPreserveItems = false; 24387 cachedPreserveItemsPlugins = plugins; 24388 for (let i = 0; i < plugins.length; i++) 24389 if (plugins[i].spec.historyPreserveItems) { 24390 cachedPreserveItems = true; 24391 break; 24392 } 24393 } 24394 return cachedPreserveItems; 24395} 24396const historyKey = new PluginKey("history"); 24397const closeHistoryKey = new PluginKey("closeHistory"); 24398function history(config = {}) { 24399 config = { 24400 depth: config.depth || 100, 24401 newGroupDelay: config.newGroupDelay || 500 24402 }; 24403 return new Plugin({ 24404 key: historyKey, 24405 state: { 24406 init() { 24407 return new HistoryState(Branch.empty, Branch.empty, null, 0, -1); 24408 }, 24409 apply(tr2, hist, state) { 24410 return applyTransaction(hist, state, tr2, config); 24411 } 24412 }, 24413 config, 24414 props: { 24415 handleDOMEvents: { 24416 beforeinput(view, e) { 24417 let inputType = e.inputType; 24418 let command2 = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null; 24419 if (!command2) 24420 return false; 24421 e.preventDefault(); 24422 return command2(view.state, view.dispatch); 24423 } 24424 } 24425 } 24426 }); 24427} 24428function buildCommand(redo2, scroll) { 24429 return (state, dispatch) => { 24430 let hist = historyKey.getState(state); 24431 if (!hist || (redo2 ? hist.undone : hist.done).eventCount == 0) 24432 return false;
24433 if (dispatch) { 24434 let tr2 = histTransaction(hist, state, redo2); 24435 if (tr2) 24436 dispatch(scroll ? tr2.scrollIntoView() : tr2); 24437 } 24438 return true; 24439 }; 24440} 24441const undo = buildCommand(false, true); 24442const redo = buildCommand(true, true); 24443const History = Extension.create({ 24444 name: "history", 24445 addOptions() { 24446 return { 24447 depth: 100, 24448 newGroupDelay: 500 24449 }; 24450 }, 24451 addCommands() { 24452 return { 24453 undo: () => ({ state, dispatch }) => { 24454 return undo(state, dispatch); 24455 }, 24456 redo: () => ({ state, dispatch }) => { 24457 return redo(state, dispatch); 24458 } 24459 }; 24460 }, 24461 addProseMirrorPlugins() { 24462 return [ 24463 history(this.options) 24464 ]; 24465 }, 24466 addKeyboardShortcuts() { 24467 return { 24468 "Mod-z": () => this.editor.commands.undo(), 24469 "Shift-Mod-z": () => this.editor.commands.redo(), 24470 "Mod-y": () => this.editor.commands.redo(), 24471 // Russian keyboard layouts 24472 "Mod-Ñ": () => this.editor.commands.undo(), 24473 "Shift-Mod-Ñ": () => this.editor.commands.redo() 24474 }; 24475 } 24476}); 24477const _withScopeId = (n) => (pushScopeId("data-v-c6f7dbd5"), n = n(), popScopeId(), n); 24478const _hoisted_1 = { class: "text-editor-area" }; 24479const _hoisted_2 = { 24480 key: 0, 24481 class: "text-editor-toolbar" 24482}; 24483const _hoisted_3 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("option", { disabled: "" }, "Text Format", -1)); 24484const _hoisted_4 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("option", null, "Paragraph", -1)); 24485const _hoisted_5 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("option", null, "Heading 1", -1)); 24486const _hoisted_6 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("option", null, "Heading 2", -1)); 24487const _hoisted_7 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("option", null, "Heading 3", -1)); 24488const _hoisted_8 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("option", null, "Heading 4", -1)); 24489const _hoisted_9 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("option", null, "Heading 5", -1)); 24490const _hoisted_10 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("option", null, "Heading 6", -1)); 24491const _hoisted_11 = [ 24492 _hoisted_3, 24493 _hoisted_4, 24494 _hoisted_5, 24495 _hoisted_6, 24496 _hoisted_7, 24497 _hoisted_8, 24498 _hoisted_9, 24499 _hoisted_10 24500]; 24501const _hoisted_12 = /* @__PURE__ */ createStaticVNode("<option disabled data-v-c6f7dbd5>Font Family</option><option data-v-c6f7dbd5>Arial</option><option data-v-c6f7dbd5>Courier New</option><option data-v-c6f7dbd5>Georgia</option><option data-v-c6f7dbd5>Impact</option><option data-v-c6f7dbd5>Lucida Console</option><option data-v-c6f7dbd5>Tahoma</option><option data-v-c6f7dbd5>Times New Roman</option><option data-v-c6f7dbd5>Trebuchet MS</option><option data-v-c6f7dbd5>Verdana</option>", 10); 24502const _hoisted_22 = [ 24503 _hoisted_12 24504]; 24505const _hoisted_23 = ["value"]; 24506const _hoisted_24 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-bold" }, null, -1)); 24507const _hoisted_25 = [ 24508 _hoisted_24 24509]; 24510const _hoisted_26 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-italic" }, null, -1)); 24511const _hoisted_27 = [ 24512 _hoisted_26 24513]; 24514const _hoisted_28 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-underline" }, null, -1)); 24515const _hoisted_29 = [ 24516 _hoisted_28 24517]; 24518const _hoisted_30 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { 24519 class: "ri-link", 24520 title: "Add Link" 24521}, null, -1)); 24522const _hoisted_31 = [ 24523 _hoisted_30 24524]; 24525const _hoisted_32 = ["disabled"]; 24526const _hoisted_33 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-link-unlink" }, null, -1)); 24527const _hoisted_34 = [ 24528 _hoisted_33 24529]; 24530const _hoisted_35 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-list-unordered" }, null, -1)); 24531const _hoisted_36 = [ 24532 _hoisted_35 24533]; 24534const _hoisted_37 = /* @__PURE__ */ _withScopeId(() =>
24534 /* @__PURE__ */ createBaseVNode("i", { class: "ri-list-ordered" }, null, -1)); 24535const _hoisted_38 = [ 24536 _hoisted_37 24537]; 24538const _hoisted_39 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-align-left" }, null, -1)); 24539const _hoisted_40 = [ 24540 _hoisted_39 24541]; 24542const _hoisted_41 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-align-center" }, null, -1)); 24543const _hoisted_42 = [ 24544 _hoisted_41 24545]; 24546const _hoisted_43 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-align-right" }, null, -1)); 24547const _hoisted_44 = [ 24548 _hoisted_43 24549]; 24550const _hoisted_45 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-align-justify" }, null, -1)); 24551const _hoisted_46 = [ 24552 _hoisted_45 24553]; 24554const _hoisted_47 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-arrow-go-back-line" }, null, -1)); 24555const _hoisted_48 = [ 24556 _hoisted_47 24557]; 24558const _hoisted_49 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("i", { class: "ri-arrow-go-forward-line" }, null, -1)); 24559const _hoisted_50 = [ 24560 _hoisted_49 24561]; 24562const _sfc_main = /* @__PURE__ */ defineComponent({ 24563 __name: "TextEditor", 24564 props: { 24565 modelValue: String 24566 }, 24567 emits: ["update:modelValue", "update:model-value"], 24568 setup(__props, { emit }) { 24569 const props = __props; 24570 watch( 24571 () => props.modelValue, 24572 (value) => { 24573 const isSame = editor.value?.getHTML() === value; 24574 if (isSame) { 24575 return; 24576 } 24577 editor.value?.commands.setContent(value, false); 24578 } 24579 ); 24580 const editor = useEditor({ 24581 content: props.modelValue, 24582 onUpdate: ({ editor: editor2 }) => { 24583 emit("update:model-value", editor2.getHTML()); 24584 }, 24585 extensions: [ 24586 Document, 24587 Text, 24588 Paragraph, 24589 Typography, 24590 Bold, 24591 Italic, 24592 Underline, 24593 Link.configure({ 24594 linkOnPaste: false, 24595 autolink: false 24596 }), 24597 Image, 24598 BulletList.configure({ 24599 itemTypeName: "listItem", 24600 keepMarks: true, 24601 keepAttributes: true 24602 }), 24603 OrderedList, 24604 ListItem, 24605 TextStyle, 24606 Color.configure({ 24607 types: ["textStyle"] 24608 }), 24609 Table.configure({ 24610 HTMLAttributes: { 24611 class: "editor-table" 24612 } 24613 }), 24614 TableCell, 24615 TableHeader, 24616 TableRow, 24617 Gapcursor, 24618 Heading.configure({ 24619 levels: [1, 2, 3, 4, 5, 6] 24620 }), 24621 FontFamily.configure({ 24622 types: ["textStyle"] 24623 }), 24624 TextAlign.configure({ 24625 types: ["heading", "paragraph"], 24626 alignments: ["left", "center", "right", "justify"] 24627 }), 24628 History 24629 ] 24630 }); 24631 const setLink = () => { 24632 const previourUrl = editor.value?.getAttributes("link").href; 24633 const url = window.prompt("Enter the URL", previourUrl || "https://"); 24634 if (url === null) { 24635 return; 24636 } 24637 if (url === "") { 24638 editor.value?.chain().focus().unsetLink().run(); 24639 return; 24640 } 24641 editor.value?.chain().focus().setLink({ href: url }).run(); 24642 }; 24643 const handleTextFormatChange = (event) => { 24644 const value = event.target.value; 24645 switch (value) { 24646 case "Paragraph": 24647 editor.value?.chain().focus().setParagraph().run(); 24648 break; 24649 case "Heading 1": 24650 editor.value?.chain().focus().toggleHeading({ level: 1 }).run(); 24651 break; 24652 case "Heading 2": 24653 editor.value?.chain().focus().toggleHeading({ level: 2 }).run(); 24654 break; 24655 case "Heading 3": 24656 editor.value?.chain().focus().toggleHeading({ level: 3 }).run(); 24657 break; 24658 case "Heading 4": 24659 editor.value?.chain().focus().toggleHeading({ level: 4 }).run(); 24660 break; 24661 case "Heading 5": 24662 editor.value?.chain().focus().toggleHeading({ level: 5 }).run(); 24663 break; 24664 case "Heading 6": 24665 editor.value?.chain().focus().toggleHeading({ level: 6 }).run(); 24666 break; 24667 } 24668 }; 24669 const handleFontFamilyChange = (event) => { 24670 const value = event.target.value; 24671 editor.value?.chain().focus().setFontFamily(value).run(); 24672 }; 24673 return (_ctx, _cache) => { 24674 return openBlock(), createElementBlock("div", _hoisted_1, [ 24675 unref(editor) ? (openBlock(), createElementBlock("div", _hoisted_2, [ 24676 createBaseVNode("select", { 24677 name: "text-format", 24678 id: "text-format", 24679 class: "text-format-dropdown", 24680 onChange: handleTextFormatChange 24681 }, _hoisted_11, 32), 24682 createBaseVNode("select", { 24683 name: "font-family", 24684 id: "font-family", 24685 class: "text-format-dropdown", 24686 onChange: handleFontFamilyChange 24687 }, _hoisted_22, 32), 24688 createBaseVNode("input", { 24689 type: "color", 24690 onInput: _cache[0] || (_cache[0] = ($event) => unref(editor)?.chain().focus().setColor($event.target.value).run()), 24691 value: unref(editor)?.getAttributes("textStyle").color, 24692 class: "editor-toolbar-colorpicker" 24693 }, null, 40, _hoisted_23), 24694 createBaseVNode("button", { 24695 onClick: _cache[1] || (_cache[1] = ($event) => unref(editor)?.chain().focus().toggleBold().run()), 24696 class: normalizeClass(["editor-toolbar-button", { "active-toggle": unref(editor).isActive("bold") }
24696]), 24697 title: "Bold Text" 24698 }, _hoisted_25, 2), 24699 createBaseVNode("button", { 24700 onClick: _cache[2] || (_cache[2] = ($event) => unref(editor)?.chain().focus().toggleItalic().run()), 24701 class: normalizeClass(["editor-toolbar-button", { "active-toggle": unref(editor).isActive("italic") }]), 24702 title: "Italicize Text" 24703 }, _hoisted_27, 2), 24704 createBaseVNode("button", { 24705 onClick: _cache[3] || (_cache[3] = ($event) => unref(editor)?.chain().focus().toggleUnderline().run()), 24706 class: normalizeClass(["editor-toolbar-button", { "active-toggle": unref(editor).isActive("underline") }]), 24707 title: "Underline Text" 24708 }, _hoisted_29, 2), 24709 createBaseVNode("button", { 24710 onClick: setLink, 24711 class: normalizeClass(["editor-toolbar-button", { "active-toggle": unref(editor).isActive("link") }]) 24712 }, _hoisted_31, 2), 24713 createBaseVNode("button", { 24714 onClick: _cache[4] || (_cache[4] = ($event) => unref(editor)?.chain().focus().unsetLink().run()), 24715 class: "editor-toolbar-button", 24716 disabled: !unref(editor).isActive("link"), 24717 title: "Remove Link" 24718 }, _hoisted_34, 8, _hoisted_32), 24719 createBaseVNode("button", { 24720 onClick: _cache[5] || (_cache[5] = ($event) => unref(editor)?.chain().focus().toggleBulletList().run()), 24721 class: normalizeClass(["editor-toolbar-button", { "active-toggle": unref(editor).isActive("bulletList") }]), 24722 title: "Toggle Bullet List" 24723 }, _hoisted_36, 2), 24724 createBaseVNode("button", { 24725 onClick: _cache[6] || (_cache[6] = ($event) => unref(editor)?.chain().focus().toggleOrderedList().run()), 24726 class: normalizeClass(["editor-toolbar-button", { "active-toggle": unref(editor).isActive("orderedList") }]), 24727 title: "Toggle Numbered List" 24728 }, _hoisted_38, 2), 24729 createBaseVNode("button", { 24730 onClick: _cache[7] || (_cache[7] = ($event) => unref(editor)?.chain().focus().setTextAlign("left").run()), 24731 class: "editor-toolbar-button", 24732 title: "Left Align Text" 24733 }, _hoisted_40), 24734 createBaseVNode("button", { 24735 onClick: _cache[8] || (_cache[8] = ($event) => unref(editor)?.chain().focus().setTextAlign("center").run()), 24736 class: "editor-toolbar-button", 24737 title: "Center Align Text" 24738 }, _hoisted_42), 24739 createBaseVNode("button", { 24740 onClick: _cache[9] || (_cache[9] = ($event) => unref(editor)?.chain().focus().setTextAlign("right").run()), 24741 class: "editor-toolbar-button", 24742 title: "Right Align Text" 24743 }, _hoisted_44), 24744 createBaseVNode("button", { 24745 onClick: _cache[10] || (_cache[10] = ($event) => unref(editor)?.chain().focus().setTextAlign("justify").run()), 24746 class: "editor-toolbar-button", 24747 title: "Justify Text" 24748 }, _hoisted_46), 24749 createBaseVNode("button", { 24750 onClick: _cache[11] || (_cache[11] = ($event) => unref(editor)?.chain().focus().undo().run()), 24751 class: "editor-toolbar-button", 24752 title: "Undo Change" 24753 }, _hoisted_48), 24754 createBaseVNode("button", { 24755 onClick: _cache[12] || (_cache[12] = ($event) => unref(editor)?.chain().focus().redo().run()), 24756 class: "editor-toolbar-button", 24757 title: "Redo Change" 24758 }, _hoisted_50) 24759 ])) : createCommentVNode("", true), 24760 createVNode(unref(EditorContent), { 24761 editor: unref(editor), 24762 class: "text-editor-content" 24763 }, null, 8, ["editor"]) 24764 ]); 24765 }; 24766 } 24767}); 24768const TextEditor_vue_vue_type_style_index_0_scoped_c6f7dbd5_lang = ""; 24769const TextEditor = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-c6f7dbd5"]]); 24770export { 24771 TextEditor as T 24772};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.