vendor: 2,319 bytes, lines 1-77
1/* 2Trix 2.1.16 3Copyright © 2025 37signals, LLC 4 */ 5(function (global, factory) { 6 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 7 typeof define === 'function' && define.amd ? define(factory) : 8 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Trix = factory()); 9})(this, (function () { 'use strict'; 10 11 var name = "trix"; 12 var version = "2.1.16"; 13 var description = "A rich text editor for everyday writing"; 14 var main = "dist/trix.umd.min.js"; 15 var module = "dist/trix.esm.min.js"; 16 var style = "dist/trix.css"; 17 var files = [ 18 "dist/*.css", 19 "dist/*.js", 20 "dist/*.map", 21 "src/{inspector,trix}/*.js" 22 ]; 23 var repository = { 24 type: "git", 25 url: "git+https://github.com/basecamp/trix.git" 26 }; 27 var keywords = [ 28 "rich text", 29 "wysiwyg", 30 "editor" 31 ]; 32 var author = "37signals, LLC"; 33 var license = "MIT"; 34 var bugs = { 35 url: "https://github.com/basecamp/trix/issues" 36 }; 37 var homepage = "https://trix-editor.org/"; 38 var devDependencies = { 39 "@babel/core": "^7.16.0", 40 "@babel/preset-env": "^7.16.4", 41 "@rollup/plugin-babel": "^5.3.0", 42 "@rollup/plugin-commonjs": "^22.0.2", 43 "@rollup/plugin-json": "^4.1.0", 44 "@rollup/plugin-node-resolve": "^13.3.0", 45 "@web/dev-server": "^0.1.34", 46 "babel-eslint": "^10.1.0", 47 chokidar: "^4.0.2", 48 concurrently: "^7.4.0", 49 eslint: "^7.32.0", 50 esm: "^3.2.25", 51 idiomorph: "^0.7.3", 52 karma: "6.4.1", 53 "karma-chrome-launcher": "3.2.0", 54 "karma-qunit": "^4.1.2", 55 "karma-sauce-launcher": "^4.3.6", 56 qunit: "2.19.1", 57 rangy: "^1.3.0", 58 rollup: "^2.56.3", 59 "rollup-plugin-includepaths": "^0.2.4", 60 "rollup-plugin-terser": "^7.0.2", 61 sass: "^1.83.0", 62 svgo: "^2.8.0", 63 webdriverio: "^7.19.5" 64 }; 65 var resolutions = { 66 webdriverio: "^7.19.5" 67 }; 68 var scripts = { 69 "build-css": "bin/sass-build assets/trix.scss dist/trix.css action_text-trix/app/assets/stylesheets/trix.css", 70 "build-js": "rollup -c", 71 "build-assets": "cp -f assets/*.html dist/", 72 "build-ruby": "rake -C action_text-trix sync", 73 build: "yarn run build-js && yarn run build-css && yarn run build-assets && yarn run build-ruby", 74 watch: "rollup -c -w", 75 lint: "eslint .", 76 pretest: "yarn run lint && yarn run build", 77 test: "karma start
vendor: 56,417 bytes, lines 77-1767
77", 78 version: "yarn build && git add action_text-trix", 79 prerelease: "yarn version && yarn test", 80 "release-npm": "npm adduser && npm publish", 81 "release-ruby": "rake -C action_text-trix release", 82 release: "yarn run release-npm && yarn run release-ruby", 83 postrelease: "git push && git push --tags", 84 dev: "web-dev-server --app-index index.html --root-dir dist --node-resolve --open", 85 start: "yarn build-assets && concurrently --kill-others --names js,css,dev-server 'yarn watch' 'yarn build-css --watch' 'yarn dev'" 86 }; 87 var dependencies = { 88 dompurify: "^3.2.5" 89 }; 90 var engines = { 91 node: ">= 18" 92 }; 93 var _package = { 94 name: name, 95 version: version, 96 description: description, 97 main: main, 98 module: module, 99 style: style, 100 files: files, 101 repository: repository, 102 keywords: keywords, 103 author: author, 104 license: license, 105 bugs: bugs, 106 homepage: homepage, 107 devDependencies: devDependencies, 108 resolutions: resolutions, 109 scripts: scripts, 110 dependencies: dependencies, 111 engines: engines 112 }; 113 114 const attachmentSelector = "[data-trix-attachment]"; 115 const attachments = { 116 preview: { 117 presentation: "gallery", 118 caption: { 119 name: true, 120 size: true 121 } 122 }, 123 file: { 124 caption: { 125 size: true 126 } 127 } 128 }; 129 130 const attributes = { 131 default: { 132 tagName: "div", 133 parse: false 134 }, 135 quote: { 136 tagName: "blockquote", 137 nestable: true 138 }, 139 heading1: { 140 tagName: "h1", 141 terminal: true, 142 breakOnReturn: true, 143 group: false 144 }, 145 code: { 146 tagName: "pre", 147 terminal: true, 148 htmlAttributes: ["language"], 149 text: { 150 plaintext: true 151 } 152 }, 153 bulletList: { 154 tagName: "ul", 155 parse: false 156 }, 157 bullet: { 158 tagName: "li", 159 listAttribute: "bulletList", 160 group: false, 161 nestable: true, 162 test(element) { 163 return tagName$1(element.parentNode) === attributes[this.listAttribute].tagName; 164 } 165 }, 166 numberList: { 167 tagName: "ol", 168 parse: false 169 }, 170 number: { 171 tagName: "li", 172 listAttribute: "numberList", 173 group: false, 174 nestable: true, 175 test(element) { 176 return tagName$1(element.parentNode) === attributes[this.listAttribute].tagName; 177 } 178 }, 179 attachmentGallery: { 180 tagName: "div", 181 exclusive: true, 182 terminal: true, 183 parse: false, 184 group: false 185 } 186 }; 187 const tagName$1 = element => { 188 var _element$tagName; 189 return element === null || element === void 0 || (_element$tagName = element.tagName) === null || _element$tagName === void 0 ? void 0 : _element$tagName.toLowerCase(); 190 }; 191 192 const androidVersionMatch = navigator.userAgent.match(/android\s([0-9]+.*Chrome)/i); 193 const androidVersion = androidVersionMatch && parseInt(androidVersionMatch[1]); 194 var browser$1 = { 195 // Android emits composition events when moving the cursor through existing text 196 // Introduced in Chrome 65: https://bugs.chromium.org/p/chromium/issues/detail?id=764439#c9 197 composesExistingText: /Android.*Chrome/.test(navigator.userAgent), 198 // Android 13, especially on Samsung keyboards, emits extra compositionend and beforeinput events 199 // that can make the input handler lose the current selection or enter an infinite input -> render -> input 200 // loop. 201 recentAndroid: androidVersion && androidVersion > 12, 202 samsungAndroid: androidVersion && navigator.userAgent.match(/Android.*SM-/), 203 // IE 11 activates resizing handles on editable elements that have "layout" 204 forcesObjectResizing: /Trident.*rv:11/.test(navigator.userAgent), 205 // https://www.w3.org/TR/input-events-1/ + https://www.w3.org/TR/input-events-2/ 206 supportsInputEvents: typeof InputEvent !== "undefined" && ["data", "getTargetRanges", "inputType"].every(prop => prop in InputEvent.prototype) 207 }; 208 209 var css$3 = { 210 attachment: "attachment", 211 attachmentCaption: "attachment__caption", 212 attachmentCaptionEditor: "attachment__caption-editor", 213 attachmentMetadata: "attachment__metadata", 214 attachmentMetadataContainer: "attachment__metadata-container", 215 attachmentName: "attachment__name", 216 attachmentProgress: "attachment__progress", 217 attachmentSize: "attachment__size", 218 attachmentToolbar: "attachment__toolbar", 219 attachmentGallery: "attachment-gallery" 220 }; 221 222 var dompurify = { 223 ADD_ATTR: ["language"], 224 SAFE_FOR_XML: false, 225 RETURN_DOM: true 226 }; 227 228 var lang$1 = { 229 attachFiles: "Attach Files", 230 bold: "Bold", 231 bullets: "Bullets", 232 byte: "Byte", 233 bytes: "Bytes", 234 captionPlaceholder: "Add a captionâ¦", 235 code: "Code", 236 heading1: "Heading", 237 indent: "Increase Level", 238 italic: "Italic", 239 link: "Link", 240 numbers: "Numbers", 241 outdent: "Decrease Level", 242 quote: "Quote", 243 redo: "Redo", 244 remove: "Remove", 245 strike: "Strikethrough", 246 undo: "Undo", 247 unlink: "Unlink", 248 url: "URL", 249 urlPlaceholder: "Enter a URLâ¦", 250 GB: "GB", 251 KB: "KB", 252 MB: "MB", 253 PB: "PB", 254 TB: "TB" 255 }; 256 257 /* eslint-disable 258 no-case-declarations, 259 */ 260 const sizes = [lang$1.bytes, lang$1.KB, lang$1.MB, lang$1.GB, lang$1.TB, lang$1.PB]; 261 var file_size_formatting = { 262 prefix: "IEC", 263 precision: 2, 264 formatter(number) { 265 switch (number) { 266 case 0: 267 return "0 ".concat(lang$1.bytes); 268 case 1: 269 return "1 ".concat(lang$1.byte); 270 default: 271 let base; 272 if (this.prefix === "SI") { 273 base = 1000; 274 } else if (this.prefix === "IEC") { 275 base = 1024; 276 } 277 const exp = Math.floor(Math.log(number) / Math.log(base)); 278 const humanSize = number / Math.pow(base, exp); 279 const string = humanSize.toFixed(this.precision); 280 const withoutInsignificantZeros = string.replace(/0*$/, "").replace(/\.$/, ""); 281 return "".concat(withoutInsignificantZeros, " ").concat(sizes[exp]); 282 } 283 } 284 }; 285 286 const ZERO_WIDTH_SPACE = "\uFEFF"; 287 const NON_BREAKING_SPACE = "\u00A0"; 288 const OBJECT_REPLACEMENT_CHARACTER = "\uFFFC"; 289 290 const extend = function (properties) { 291 for (const key in properties) { 292 const value = properties[key]; 293 this[key] = value; 294 } 295 return this; 296 }; 297 298 const html$2 = document.documentElement; 299 const match = html$2.matches; 300 const handleEvent = function (eventName) { 301 let { 302 onElement, 303 matchingSelector, 304 withCallback, 305 inPhase, 306 preventDefault, 307 times 308 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 309 const element = onElement ? onElement : html$2; 310 const selector = matchingSelector; 311 const useCapture = inPhase === "capturing"; 312 const handler = function (event) { 313 if (times != null && --times === 0) { 314 handler.destroy(); 315 } 316 const target = findClosestElementFromNode(event.target, { 317 matchingSelector: selector 318 }); 319 if (target != null) { 320 withCallback === null || withCallback === void 0 || withCallback.call(target, event, target); 321 if (preventDefault) { 322 event.preventDefault(); 323 } 324 } 325 }; 326 handler.destroy = () => element.removeEventListener(eventName, handler, useCapture); 327 element.addEventListener(eventName, handler, useCapture); 328 return handler; 329 }; 330 const handleEventOnce = function (eventName) { 331 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 332 options.times = 1; 333 return handleEvent(eventName, options); 334 }; 335 const createEvent = function (eventName) { 336 let { 337 bubbles, 338 cancelable, 339 attributes 340 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 341 bubbles = bubbles !== false; 342 cancelable = cancelable !== false; 343 const event = document.createEvent("Events"); 344 event.initEvent(eventName, bubbles, cancelable); 345 if (attributes != null) { 346 extend.call(event, attributes); 347 } 348 return event; 349 }; 350 const triggerEvent = function (eventName) { 351 let { 352 onElement, 353 bubbles, 354 cancelable, 355 attributes 356 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 357 const element = onElement != null ? onElement : html$2; 358 const event = createEvent(eventName, { 359 bubbles, 360 cancelable, 361 attributes 362 }); 363 return element.dispatchEvent(event); 364 }; 365 const elementMatchesSelector = function (element, selector) { 366 if ((element === null || element === void 0 ? void 0 : element.nodeType) === 1) { 367 return match.call(element, selector); 368 } 369 }; 370 const findClosestElementFromNode = function (node) { 371 let { 372 matchingSelector, 373 untilNode 374 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 375 while (node && node.nodeType !== Node.ELEMENT_NODE) { 376 node = node.parentNode; 377 } 378 if (node == null) { 379 return; 380 } 381 if (matchingSelector != null) { 382 if (node.closest && untilNode == null) { 383 return node.closest(matchingSelector); 384 } else { 385 while (node && node !== untilNode) { 386 if (elementMatchesSelector(node, matchingSelector)) { 387 return node; 388 } 389 node = node.parentNode; 390 } 391 } 392 } else { 393 return node; 394 } 395 }; 396 const findInnerElement = function (element) { 397 while ((_element = element) !== null && _element !== void 0 && _element.firstElementChild) { 398 var _element; 399 element = element.firstElementChild; 400 } 401 return element; 402 }; 403 const innerElementIsActive = element => document.activeElement !== element && elementContainsNode(element, document.activeElement); 404 const elementContainsNode = function (element, node) { 405 if (!element || !node) { 406 return; 407 } 408 while (node) { 409 if (node === element) { 410 return true; 411 } 412 node = node.parentNode; 413 } 414 }; 415 const findNodeFromContainerAndOffset = function (container, offset) { 416 if (!container) { 417 return; 418 } 419 if (container.nodeType === Node.TEXT_NODE) { 420 return container; 421 } else if (offset === 0) { 422 return container.firstChild != null ? container.firstChild : container; 423 } else { 424 return container.childNodes.item(offset - 1); 425 } 426 }; 427 const findElementFromContainerAndOffset = function (container, offset) { 428 const node = findNodeFromContainerAndOffset(container, offset); 429 return findClosestElementFromNode(node); 430 }; 431 const findChildIndexOfNode = function (node) { 432 var _node; 433 if (!((_node = node) !== null && _node !== void 0 && _node.parentNode)) { 434 return; 435 } 436 let childIndex = 0; 437 node = node.previousSibling; 438 while (node) { 439 childIndex++; 440 node = node.previousSibling; 441 } 442 return childIndex; 443 }; 444 const removeNode = node => { 445 var _node$parentNode; 446 return node === null || node === void 0 || (_node$parentNode = node.parentNode) === null || _node$parentNode === void 0 ? void 0 : _node$parentNode.removeChild(node); 447 }; 448 const walkTree = function (tree) { 449 let { 450 onlyNodesOfType, 451 usingFilter, 452 expandEntityReferences 453 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 454 const whatToShow = (() => { 455 switch (onlyNodesOfType) { 456 case "element": 457 return NodeFilter.SHOW_ELEMENT; 458 case "text": 459 return NodeFilter.SHOW_TEXT; 460 case "comment": 461 return NodeFilter.SHOW_COMMENT; 462 default: 463 return NodeFilter.SHOW_ALL; 464 } 465 })(); 466 return document.createTreeWalker(tree, whatToShow, usingFilter != null ? usingFilter : null, expandEntityReferences === true); 467 }; 468 const tagName = element => { 469 var _element$tagName; 470 return element === null || element === void 0 || (_element$tagName = element.tagName) === null || _element$tagName === void 0 ? void 0 : _element$tagName.toLowerCase(); 471 }; 472 const makeElement = function (tag) { 473 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 474 let key, value; 475 if (typeof tag === "object") { 476 options = tag; 477 tag = options.tagName; 478 } else { 479 options = { 480 attributes: options 481 }; 482 } 483 const element = document.createElement(tag); 484 if (options.editable != null) { 485 if (options.attributes == null) { 486 options.attributes = {}; 487 } 488 options.attributes.contenteditable = options.editable; 489 } 490 if (options.attributes) { 491 for (key in options.attributes) { 492 value = options.attributes[key]; 493 element.setAttribute(key, value); 494 } 495 } 496 if (options.style) { 497 for (key in options.style) { 498 value = options.style[key]; 499 element.style[key] = value; 500 } 501 } 502 if (options.data) { 503 for (key in options.data) { 504 value = options.data[key]; 505 element.dataset[key] = value; 506 } 507 } 508 if (options.className) { 509 options.className.split(" ").forEach(className => { 510 element.classList.add(className); 511 }); 512 } 513 if (options.textContent) { 514 element.textContent = options.textContent; 515 } 516 if (options.childNodes) { 517 [].concat(options.childNodes).forEach(childNode => { 518 element.appendChild(childNode); 519 }); 520 } 521 return element; 522 }; 523 let blockTagNames = undefined; 524 const getBlockTagNames = function () { 525 if (blockTagNames != null) { 526 return blockTagNames; 527 } 528 blockTagNames = []; 529 for (const key in attributes) { 530 const attributes$1 = attributes[key]; 531 if (attributes$1.tagName) { 532 blockTagNames.push(attributes$1.tagName); 533 } 534 } 535 return blockTagNames; 536 }; 537 const nodeIsBlockContainer = node => nodeIsBlockStartComment(node === null || node === void 0 ? void 0 : node.firstChild); 538 const nodeProbablyIsBlockContainer = function (node) { 539 return getBlockTagNames().includes(tagName(node)) && !getBlockTagNames().includes(tagName(node.firstChild)); 540 }; 541 const nodeIsBlockStart = function (node) { 542 let { 543 strict 544 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { 545 strict: true 546 }; 547 if (strict) { 548 return nodeIsBlockStartComment(node); 549 } else { 550 return nodeIsBlockStartComment(node) || !nodeIsBlockStartComment(node.firstChild) && nodeProbablyIsBlockContainer(node); 551 } 552 }; 553 const nodeIsBlockStartComment = node => nodeIsCommentNode(node) && (node === null || node === void 0 ? void 0 : node.data) === "block"; 554 const nodeIsCommentNode = node => (node === null || node === void 0 ? void 0 : node.nodeType) === Node.COMMENT_NODE; 555 const nodeIsCursorTarget = function (node) { 556 let { 557 name 558 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 559 if (!node) { 560 return; 561 } 562 if (nodeIsTextNode(node)) { 563 if (node.data === ZERO_WIDTH_SPACE) { 564 if (name) { 565 return node.parentNode.dataset.trixCursorTarget === name; 566 } else { 567 return true; 568 } 569 } 570 } else { 571 return nodeIsCursorTarget(node.firstChild); 572 } 573 }; 574 const nodeIsAttachmentElement = node => elementMatchesSelector(node, attachmentSelector); 575 const nodeIsEmptyTextNode = node => nodeIsTextNode(node) && (node === null || node === void 0 ? void 0 : node.data) === ""; 576 const nodeIsTextNode = node => (node === null || node === void 0 ? void 0 : node.nodeType) === Node.TEXT_NODE; 577 578 const input = { 579 level2Enabled: true, 580 getLevel() { 581 if (this.level2Enabled && browser$1.supportsInputEvents) { 582 return 2; 583 } else { 584 return 0; 585 } 586 }, 587 pickFiles(callback) { 588 const input = makeElement("input", { 589 type: "file", 590 multiple: true, 591 hidden: true, 592 id: this.fileInputId 593 }); 594 input.addEventListener("change", () => { 595 callback(input.files); 596 removeNode(input); 597 }); 598 removeNode(document.getElementById(this.fileInputId)); 599 document.body.appendChild(input); 600 input.click(); 601 } 602 }; 603 604 var key_names = { 605 8: "backspace", 606 9: "tab", 607 13: "return", 608 27: "escape", 609 37: "left", 610 39: "right", 611 46: "delete", 612 68: "d", 613 72: "h", 614 79: "o" 615 }; 616 617 var parser = { 618 removeBlankTableCells: false, 619 tableCellSeparator: " | ", 620 tableRowSeparator: "\n" 621 }; 622 623 var text_attributes = { 624 bold: { 625 tagName: "strong", 626 inheritable: true, 627 parser(element) { 628 const style = window.getComputedStyle(element); 629 return style.fontWeight === "bold" || style.fontWeight >= 600; 630 } 631 }, 632 italic: { 633 tagName: "em", 634 inheritable: true, 635 parser(element) { 636 const style = window.getComputedStyle(element); 637 return style.fontStyle === "italic"; 638 } 639 }, 640 href: { 641 groupTagName: "a", 642 parser(element) { 643 const matchingSelector = "a:not(".concat(attachmentSelector, ")"); 644 const link = element.closest(matchingSelector); 645 if (link) { 646 return link.getAttribute("href"); 647 } 648 } 649 }, 650 strike: { 651 tagName: "del", 652 inheritable: true 653 }, 654 frozen: { 655 style: { 656 backgroundColor: "highlight" 657 } 658 } 659 }; 660 661 var toolbar = { 662 getDefaultHTML() { 663 return "<div class=\"trix-button-row\">\n <span class=\"trix-button-group trix-button-group--text-tools\" data-trix-button-group=\"text-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-bold\" data-trix-attribute=\"bold\" data-trix-key=\"b\" title=\"".concat(lang$1.bold, "\" tabindex=\"-1\">").concat(lang$1.bold, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-italic\" data-trix-attribute=\"italic\" data-trix-key=\"i\" title=\"").concat(lang$1.italic, "\" tabindex=\"-1\">").concat(lang$1.italic, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-strike\" data-trix-attribute=\"strike\" title=\"").concat(lang$1.strike, "\" tabindex=\"-1\">").concat(lang$1.strike, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-link\" data-trix-attribute=\"href\" data-trix-action=\"link\" data-trix-key=\"k\" title=\"").concat(lang$1.link, "\" tabindex=\"-1\">").concat(lang$1.link, "</button>\n </span>\n\n <span class=\"trix-button-group trix-button-group--block-tools\" data-trix-button-group=\"block-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-heading-1\" data-trix-attribute=\"heading1\" title=\"").concat(lang$1.heading1, "\" tabindex=\"-1\">").concat(lang$1.heading1, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-quote\" data-trix-attribute=\"quote\" title=\"").concat(lang$1.quote, "\" tabindex=\"-1\">").concat(lang$1.quote, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-code\" data-trix-attribute=\"code\" title=\"").concat(lang$1.code, "\" tabindex=\"-1\">").concat(lang$1.code, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-bullet-list\" data-trix-attribute=\"bullet\" title=\"").concat(lang$1.bullets, "\" tabindex=\"-1\">").concat(lang$1.bullets, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-number-list\" data-trix-attribute=\"number\" title=\"").concat(lang$1.numbers, "\" tabindex=\"-1\">").concat(lang$1.numbers, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-decrease-nesting-level\" data-trix-action=\"decreaseNestingLevel\" title=\"").concat(lang$1.outdent, "\" tabindex=\"-1\">").concat(lang$1.outdent, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-increase-nesting-level\" data-trix-action=\"increaseNestingLevel\" title=\"").concat(lang$1.indent, "\" tabindex=\"-1\">").concat(lang$1.indent, "</button>\n </span>\n\n <span class=\"trix-button-group trix-button-group--file-tools\" data-trix-button-group=\"file-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-attach\" data-trix-action=\"attachFiles\" title=\"").concat(lang$1.attachFiles, "\" tabindex=\"-1\">").concat(lang$1.attachFiles, "</button>\n </span>\n\n <span class=\"trix-button-group-spacer\"></span>\n\n <span class=\"trix-button-group trix-button-group--history-tools\" data-trix-button-group=\"history-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-undo\" data-trix-action=\"undo\" data-trix-key=\"z\" title=\"").concat(lang$1.undo, "\" tabindex=\"-1\">").concat(lang$1.undo, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-redo\" data-trix-action=\"redo\" data-trix-key=\"shift+z\" title=\"").concat(lang$1.redo, "\" tabindex=\"-1\">").concat(lang$1.redo, "</button>\n </span>\n </div>\n\n <div class=\"trix-dialogs\" data-trix-dialogs>\n <div class=\"trix-dialog trix-dialog--link\" data-trix-dialog=\"href\" data-trix-dialog-attribute=\"href\">\n <div class=\"trix-dialog__link-fields\">\n <input type=\"url\" name=\"href\" class=\"trix-input trix-input--dialog\" placeholder=\"").concat(lang$1.urlPlaceholder, "\" aria-label=\"").concat(lang$1.url, "\" data-trix-validate-href required data-trix-input>\n <div class=\"trix-button-group\">\n <input type=\"button\" class=\"trix-button trix-button--dialog\" value=\"").concat(lang$1.link, "\" data-trix-method=\"setAttribute\">\n <input type=\"button\" class=\"trix-button trix-button--dialog\" value=\"").concat(lang$1.unlink, "\" data-trix-method=\"removeAttribute\">\n </div>\n </div>\n </div>\n </div>"); 664 } 665 }; 666 667 const undo = { 668 interval: 5000 669 }; 670 671 var config = /*#__PURE__*/Object.freeze({ 672 __proto__: null, 673 attachments: attachments, 674 blockAttributes: attributes, 675 browser: browser$1, 676 css: css$3, 677 dompurify: dompurify, 678 fileSize: file_size_formatting, 679 input: input, 680 keyNames: key_names, 681 lang: lang$1, 682 parser: parser, 683 textAttributes: text_attributes, 684 toolbar: toolbar, 685 undo: undo 686 }); 687 688 class BasicObject { 689 static proxyMethod(expression) { 690 const { 691 name, 692 toMethod, 693 toProperty, 694 optional 695 } = parseProxyMethodExpression(expression); 696 this.prototype[name] = function () { 697 let subject; 698 let object; 699 if (toMethod) { 700 if (optional) { 701 var _this$toMethod; 702 object = (_this$toMethod = this[toMethod]) === null || _this$toMethod === void 0 ? void 0 : _this$toMethod.call(this); 703 } else { 704 object = this[toMethod](); 705 } 706 } else if (toProperty) { 707 object = this[toProperty]; 708 } 709 if (optional) { 710 var _object; 711 subject = (_object = object) === null || _object === void 0 ? void 0 : _object[name]; 712 if (subject) { 713 return apply$1.call(subject, object, arguments); 714 } 715 } else { 716 subject = object[name]; 717 return apply$1.call(subject, object, arguments); 718 } 719 }; 720 } 721 } 722 const parseProxyMethodExpression = function (expression) { 723 const match = expression.match(proxyMethodExpressionPattern); 724 if (!match) { 725 throw new Error("can't parse @proxyMethod expression: ".concat(expression)); 726 } 727 const args = { 728 name: match[4] 729 }; 730 if (match[2] != null) { 731 args.toMethod = match[1]; 732 } else { 733 args.toProperty = match[1]; 734 } 735 if (match[3] != null) { 736 args.optional = true; 737 } 738 return args; 739 }; 740 const { 741 apply: apply$1 742 } = Function.prototype; 743 const proxyMethodExpressionPattern = new RegExp("\ 744^\ 745(.+?)\ 746(\\(\\))?\ 747(\\?)?\ 748\\.\ 749(.+?)\ 750$\ 751"); 752 753 var _Array$from, _$codePointAt$1, _$1, _String$fromCodePoint; 754 class UTF16String extends BasicObject { 755 static box() { 756 let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; 757 if (value instanceof this) { 758 return value; 759 } else { 760 return this.fromUCS2String(value === null || value === void 0 ? void 0 : value.toString()); 761 } 762 } 763 static fromUCS2String(ucs2String) { 764 return new this(ucs2String, ucs2decode(ucs2String)); 765 } 766 static fromCodepoints(codepoints) { 767 return new this(ucs2encode(codepoints), codepoints); 768 } 769 constructor(ucs2String, codepoints) { 770 super(...arguments); 771 this.ucs2String = ucs2String; 772 this.codepoints = codepoints; 773 this.length = this.codepoints.length; 774 this.ucs2Length = this.ucs2String.length; 775 } 776 offsetToUCS2Offset(offset) { 777 return ucs2encode(this.codepoints.slice(0, Math.max(0, offset))).length; 778 } 779 offsetFromUCS2Offset(ucs2Offset) { 780 return ucs2decode(this.ucs2String.slice(0, Math.max(0, ucs2Offset))).length; 781 } 782 slice() { 783 return this.constructor.fromCodepoints(this.codepoints.slice(...arguments)); 784 } 785 charAt(offset) { 786 return this.slice(offset, offset + 1); 787 } 788 isEqualTo(value) { 789 return this.constructor.box(value).ucs2String === this.ucs2String; 790 } 791 toJSON() { 792 return this.ucs2String; 793 } 794 getCacheKey() { 795 return this.ucs2String; 796 } 797 toString() { 798 return this.ucs2String; 799 } 800 } 801 const hasArrayFrom = ((_Array$from = Array.from) === null || _Array$from === void 0 ? void 0 : _Array$from.call(Array, "\ud83d\udc7c").length) === 1; 802 const hasStringCodePointAt$1 = ((_$codePointAt$1 = (_$1 = " ").codePointAt) === null || _$codePointAt$1 === void 0 ? void 0 : _$codePointAt$1.call(_$1, 0)) != null; 803 const hasStringFromCodePoint = ((_String$fromCodePoint = String.fromCodePoint) === null || _String$fromCodePoint === void 0 ? void 0 : _String$fromCodePoint.call(String, 32, 128124)) === " \ud83d\udc7c"; 804 805 // UCS-2 conversion helpers ported from Mathias Bynens' Punycode.js: 806 // https://github.com/bestiejs/punycode.js#punycodeucs2 807 808 let ucs2decode, ucs2encode; 809 810 // Creates an array containing the numeric code points of each Unicode 811 // character in the string. While JavaScript uses UCS-2 internally, 812 // this function will convert a pair of surrogate halves (each of which 813 // UCS-2 exposes as separate characters) into a single code point, 814 // matching UTF-16. 815 if (hasArrayFrom && hasStringCodePointAt$1) { 816 ucs2decode = string => Array.from(string).map(char => char.codePointAt(0)); 817 } else { 818 ucs2decode = function (string) { 819 const output = []; 820 let counter = 0; 821 const { 822 length 823 } = string; 824 while (counter < length) { 825 let value = string.charCodeAt(counter++); 826 if (0xd800 <= value && value <= 0xdbff && counter < length) { 827 // high surrogate, and there is a next character 828 const extra = string.charCodeAt(counter++); 829 if ((extra & 0xfc00) === 0xdc00) { 830 // low surrogate 831 value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000; 832 } else { 833 // unmatched surrogate; only append this code unit, in case the 834 // next code unit is the high surrogate of a surrogate pair 835 counter--; 836 } 837 } 838 output.push(value); 839 } 840 return output; 841 }; 842 } 843 844 // Creates a string based on an array of numeric code points. 845 if (hasStringFromCodePoint) { 846 ucs2encode = array => String.fromCodePoint(...Array.from(array || [])); 847 } else { 848 ucs2encode = function (array) { 849 const characters = (() => { 850 const result = []; 851 Array.from(array).forEach(value => { 852 let output = ""; 853 if (value > 0xffff) { 854 value -= 0x10000; 855 output += String.fromCharCode(value >>> 10 & 0x3ff | 0xd800); 856 value = 0xdc00 | value & 0x3ff; 857 } 858 result.push(output + String.fromCharCode(value)); 859 }); 860 return result; 861 })(); 862 return characters.join(""); 863 }; 864 } 865 866 let id$2 = 0; 867 class TrixObject extends BasicObject { 868 static fromJSONString(jsonString) { 869 return this.fromJSON(JSON.parse(jsonString)); 870 } 871 constructor() { 872 super(...arguments); 873 this.id = ++id$2; 874 } 875 hasSameConstructorAs(object) { 876 return this.constructor === (object === null || object === void 0 ? void 0 : object.constructor); 877 } 878 isEqualTo(object) { 879 return this === object; 880 } 881 inspect() { 882 const parts = []; 883 const contents = this.contentsForInspection() || {}; 884 for (const key in contents) { 885 const value = contents[key]; 886 parts.push("".concat(key, "=").concat(value)); 887 } 888 return "#<".concat(this.constructor.name, ":").concat(this.id).concat(parts.length ? " ".concat(parts.join(", ")) : "", ">"); 889 } 890 contentsForInspection() {} 891 toJSONString() { 892 return JSON.stringify(this); 893 } 894 toUTF16String() { 895 return UTF16String.box(this); 896 } 897 getCacheKey() { 898 return this.id.toString(); 899 } 900 } 901 902 /* eslint-disable 903 id-length, 904 */ 905 const arraysAreEqual = function () { 906 let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 907 let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 908 if (a.length !== b.length) { 909 return false; 910 } 911 for (let index = 0; index < a.length; index++) { 912 const value = a[index]; 913 if (value !== b[index]) { 914 return false; 915 } 916 } 917 return true; 918 }; 919 const arrayStartsWith = function () { 920 let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 921 let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 922 return arraysAreEqual(a.slice(0, b.length), b); 923 }; 924 const spliceArray = function (array) { 925 const result = array.slice(0); 926 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 927 args[_key - 1] = arguments[_key]; 928 } 929 result.splice(...args); 930 return result; 931 }; 932 const summarizeArrayChange = function () { 933 let oldArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 934 let newArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 935 const added = []; 936 const removed = []; 937 const existingValues = new Set(); 938 oldArray.forEach(value => { 939 existingValues.add(value); 940 }); 941 const currentValues = new Set(); 942 newArray.forEach(value => { 943 currentValues.add(value); 944 if (!existingValues.has(value)) { 945 added.push(value); 946 } 947 }); 948 oldArray.forEach(value => { 949 if (!currentValues.has(value)) { 950 removed.push(value); 951 } 952 }); 953 return { 954 added, 955 removed 956 }; 957 }; 958 959 // https://github.com/mathiasbynens/unicode-2.1.8/blob/master/Bidi_Class/Right_To_Left/regex.js 960 const RTL_PATTERN = /[\u05BE\u05C0\u05C3\u05D0-\u05EA\u05F0-\u05F4\u061B\u061F\u0621-\u063A\u0640-\u064A\u066D\u0671-\u06B7\u06BA-\u06BE\u06C0-\u06CE\u06D0-\u06D5\u06E5\u06E6\u200F\u202B\u202E\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE72\uFE74\uFE76-\uFEFC]/; 961 const getDirection = function () { 962 const input = makeElement("input", { 963 dir: "auto", 964 name: "x", 965 dirName: "x.dir" 966 }); 967 const textArea = makeElement("textarea", { 968 dir: "auto", 969 name: "y", 970 dirName: "y.dir" 971 }); 972 const form = makeElement("form"); 973 form.appendChild(input); 974 form.appendChild(textArea); 975 const supportsDirName = function () { 976 try { 977 return new FormData(form).has(textArea.dirName); 978 } catch (error) { 979 return false; 980 } 981 }(); 982 const supportsDirSelector = function () { 983 try { 984 return input.matches(":dir(ltr),:dir(rtl)"); 985 } catch (error) { 986 return false; 987 } 988 }(); 989 if (supportsDirName) { 990 return function (string) { 991 textArea.value = string; 992 return new FormData(form).get(textArea.dirName); 993 }; 994 } else if (supportsDirSelector) { 995 return function (string) { 996 input.value = string; 997 if (input.matches(":dir(rtl)")) { 998 return "rtl"; 999 } else { 1000 return "ltr"; 1001 } 1002 }; 1003 } else { 1004 return function (string) { 1005 const char = string.trim().charAt(0); 1006 if (RTL_PATTERN.test(char)) { 1007 return "rtl"; 1008 } else { 1009 return "ltr"; 1010 } 1011 }; 1012 } 1013 }(); 1014 1015 let allAttributeNames = null; 1016 let blockAttributeNames = null; 1017 let textAttributeNames = null; 1018 let listAttributeNames = null; 1019 const getAllAttributeNames = () => { 1020 if (!allAttributeNames) { 1021 allAttributeNames = getTextAttributeNames().concat(getBlockAttributeNames()); 1022 } 1023 return allAttributeNames; 1024 }; 1025 const getBlockConfig = attributeName => attributes[attributeName]; 1026 const getBlockAttributeNames = () => { 1027 if (!blockAttributeNames) { 1028 blockAttributeNames = Object.keys(attributes); 1029 } 1030 return blockAttributeNames; 1031 }; 1032 const getTextConfig = attributeName => text_attributes[attributeName]; 1033 const getTextAttributeNames = () => { 1034 if (!textAttributeNames) { 1035 textAttributeNames = Object.keys(text_attributes); 1036 } 1037 return textAttributeNames; 1038 }; 1039 const getListAttributeNames = () => { 1040 if (!listAttributeNames) { 1041 listAttributeNames = []; 1042 for (const key in attributes) { 1043 const { 1044 listAttribute 1045 } = attributes[key]; 1046 if (listAttribute != null) { 1047 listAttributeNames.push(listAttribute); 1048 } 1049 } 1050 } 1051 return listAttributeNames; 1052 }; 1053 1054 /* eslint-disable 1055 */ 1056 const installDefaultCSSForTagName = function (tagName, defaultCSS) { 1057 const styleElement = insertStyleElementForTagName(tagName); 1058 styleElement.textContent = defaultCSS.replace(/%t/g, tagName); 1059 }; 1060 const insertStyleElementForTagName = function (tagName) { 1061 const element = document.createElement("style"); 1062 element.setAttribute("type", "text/css"); 1063 element.setAttribute("data-tag-name", tagName.toLowerCase()); 1064 const nonce = getCSPNonce(); 1065 if (nonce) { 1066 element.setAttribute("nonce", nonce); 1067 } 1068 document.head.insertBefore(element, document.head.firstChild); 1069 return element; 1070 }; 1071 const getCSPNonce = function () { 1072 const element = getMetaElement("trix-csp-nonce") || getMetaElement("csp-nonce"); 1073 if (element) { 1074 const { 1075 nonce, 1076 content 1077 } = element; 1078 return nonce == "" ? content : nonce; 1079 } 1080 }; 1081 const getMetaElement = name => document.head.querySelector("meta[name=".concat(name, "]")); 1082 1083 const testTransferData = { 1084 "application/x-trix-feature-detection": "test" 1085 }; 1086 const dataTransferIsPlainText = function (dataTransfer) { 1087 const text = dataTransfer.getData("text/plain"); 1088 const html = dataTransfer.getData("text/html"); 1089 if (text && html) { 1090 const { 1091 body 1092 } = new DOMParser().parseFromString(html, "text/html"); 1093 if (body.textContent === text) { 1094 return !body.querySelector("*"); 1095 } 1096 } else { 1097 return text === null || text === void 0 ? void 0 : text.length; 1098 } 1099 }; 1100 const dataTransferIsMsOfficePaste = _ref => { 1101 let { 1102 dataTransfer 1103 } = _ref; 1104 return dataTransfer.types.includes("Files") && dataTransfer.types.includes("text/html") && dataTransfer.getData("text/html").includes("urn:schemas-microsoft-com:office:office"); 1105 }; 1106 const dataTransferIsWritable = function (dataTransfer) { 1107 if (!(dataTransfer !== null && dataTransfer !== void 0 && dataTransfer.setData)) return false; 1108 for (const key in testTransferData) { 1109 const value = testTransferData[key]; 1110 try { 1111 dataTransfer.setData(key, value); 1112 if (!dataTransfer.getData(key) === value) return false; 1113 } catch (error) { 1114 return false; 1115 } 1116 } 1117 return true; 1118 }; 1119 const keyEventIsKeyboardCommand = function () { 1120 if (/Mac|^iP/.test(navigator.platform)) { 1121 return event => event.metaKey; 1122 } else { 1123 return event => event.ctrlKey; 1124 } 1125 }(); 1126 function shouldRenderInmmediatelyToDealWithIOSDictation(inputEvent) { 1127 if (/iPhone|iPad/.test(navigator.userAgent)) { 1128 // Handle garbled content and duplicated newlines when using dictation on iOS 18+. Upon dictation completion, iOS sends 1129 // the list of insertText / insertParagraph events in a quick sequence. If we don't render 1130 // the editor synchronously, the internal range fails to update and results in garbled content or duplicated newlines. 1131 // 1132 // This workaround is necessary because iOS doesn't send composing events as expected while dictating: 1133 // https://bugs.webkit.org/show_bug.cgi?id=261764 1134 return !inputEvent.inputType || inputEvent.inputType === "insertParagraph"; 1135 } else { 1136 return false; 1137 } 1138 } 1139 1140 const defer = fn => setTimeout(fn, 1); 1141 1142 /* eslint-disable 1143 id-length, 1144 */ 1145 const copyObject = function () { 1146 let object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1147 const result = {}; 1148 for (const key in object) { 1149 const value = object[key]; 1150 result[key] = value; 1151 } 1152 return result; 1153 }; 1154 const objectsAreEqual = function () { 1155 let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1156 let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1157 if (Object.keys(a).length !== Object.keys(b).length) { 1158 return false; 1159 } 1160 for (const key in a) { 1161 const value = a[key]; 1162 if (value !== b[key]) { 1163 return false; 1164 } 1165 } 1166 return true; 1167 }; 1168 1169 const normalizeRange = function (range) { 1170 if (range == null) return; 1171 if (!Array.isArray(range)) { 1172 range = [range, range]; 1173 } 1174 return [copyValue(range[0]), copyValue(range[1] != null ? range[1] : range[0])]; 1175 }; 1176 const rangeIsCollapsed = function (range) { 1177 if (range == null) return; 1178 const [start, end] = normalizeRange(range); 1179 return rangeValuesAreEqual(start, end); 1180 }; 1181 const rangesAreEqual = function (leftRange, rightRange) { 1182 if (leftRange == null || rightRange == null) return; 1183 const [leftStart, leftEnd] = normalizeRange(leftRange); 1184 const [rightStart, rightEnd] = normalizeRange(rightRange); 1185 return rangeValuesAreEqual(leftStart, rightStart) && rangeValuesAreEqual(leftEnd, rightEnd); 1186 }; 1187 const copyValue = function (value) { 1188 if (typeof value === "number") { 1189 return value; 1190 } else { 1191 return copyObject(value); 1192 } 1193 }; 1194 const rangeValuesAreEqual = function (left, right) { 1195 if (typeof left === "number") { 1196 return left === right; 1197 } else { 1198 return objectsAreEqual(left, right); 1199 } 1200 }; 1201 1202 class SelectionChangeObserver extends BasicObject { 1203 constructor() { 1204 super(...arguments); 1205 this.update = this.update.bind(this); 1206 this.selectionManagers = []; 1207 } 1208 start() { 1209 if (!this.started) { 1210 this.started = true; 1211 document.addEventListener("selectionchange", this.update, true); 1212 } 1213 } 1214 stop() { 1215 if (this.started) { 1216 this.started = false; 1217 return document.removeEventListener("selectionchange", this.update, true); 1218 } 1219 } 1220 registerSelectionManager(selectionManager) { 1221 if (!this.selectionManagers.includes(selectionManager)) { 1222 this.selectionManagers.push(selectionManager); 1223 return this.start(); 1224 } 1225 } 1226 unregisterSelectionManager(selectionManager) { 1227 this.selectionManagers = this.selectionManagers.filter(sm => sm !== selectionManager); 1228 if (this.selectionManagers.length === 0) { 1229 return this.stop(); 1230 } 1231 } 1232 notifySelectionManagersOfSelectionChange() { 1233 return this.selectionManagers.map(selectionManager => selectionManager.selectionDidChange()); 1234 } 1235 update() { 1236 this.notifySelectionManagersOfSelectionChange(); 1237 } 1238 reset() { 1239 this.update(); 1240 } 1241 } 1242 const selectionChangeObserver = new SelectionChangeObserver(); 1243 const getDOMSelection = function () { 1244 const selection = window.getSelection(); 1245 if (selection.rangeCount > 0) { 1246 return selection; 1247 } 1248 }; 1249 const getDOMRange = function () { 1250 var _getDOMSelection; 1251 const domRange = (_getDOMSelection = getDOMSelection()) === null || _getDOMSelection === void 0 ? void 0 : _getDOMSelection.getRangeAt(0); 1252 if (domRange) { 1253 if (!domRangeIsPrivate(domRange)) { 1254 return domRange; 1255 } 1256 } 1257 }; 1258 const setDOMRange = function (domRange) { 1259 const selection = window.getSelection(); 1260 selection.removeAllRanges(); 1261 selection.addRange(domRange); 1262 return selectionChangeObserver.update(); 1263 }; 1264 1265 // In Firefox, clicking certain <input> elements changes the selection to a 1266 // private element used to draw its UI. Attempting to access properties of those 1267 // elements throws an error. 1268 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427 1269 const domRangeIsPrivate = domRange => nodeIsPrivate(domRange.startContainer) || nodeIsPrivate(domRange.endContainer); 1270 const nodeIsPrivate = node => !Object.getPrototypeOf(node); 1271 1272 /* eslint-disable 1273 id-length, 1274 no-useless-escape, 1275 */ 1276 const normalizeSpaces = string => string.replace(new RegExp("".concat(ZERO_WIDTH_SPACE), "g"), "").replace(new RegExp("".concat(NON_BREAKING_SPACE), "g"), " "); 1277 const normalizeNewlines = string => string.replace(/\r\n?/g, "\n"); 1278 const breakableWhitespacePattern = new RegExp("[^\\S".concat(NON_BREAKING_SPACE, "]")); 1279 const squishBreakableWhitespace = string => string 1280 // Replace all breakable whitespace characters with a space 1281 .replace(new RegExp("".concat(breakableWhitespacePattern.source), "g"), " ") 1282 // Replace two or more spaces with a single space 1283 .replace(/\ {2,}/g, " "); 1284 const summarizeStringChange = function (oldString, newString) { 1285 let added, removed; 1286 oldString = UTF16String.box(oldString); 1287 newString = UTF16String.box(newString); 1288 if (newString.length < oldString.length) { 1289 [removed, added] = utf16StringDifferences(oldString, newString); 1290 } else { 1291 [added, removed] = utf16StringDifferences(newString, oldString); 1292 } 1293 return { 1294 added, 1295 removed 1296 }; 1297 }; 1298 const utf16StringDifferences = function (a, b) { 1299 if (a.isEqualTo(b)) { 1300 return ["", ""]; 1301 } 1302 const diffA = utf16StringDifference(a, b); 1303 const { 1304 length 1305 } = diffA.utf16String; 1306 let diffB; 1307 if (length) { 1308 const { 1309 offset 1310 } = diffA; 1311 const codepoints = a.codepoints.slice(0, offset).concat(a.codepoints.slice(offset + length)); 1312 diffB = utf16StringDifference(b, UTF16String.fromCodepoints(codepoints)); 1313 } else { 1314 diffB = utf16StringDifference(b, a); 1315 } 1316 return [diffA.utf16String.toString(), diffB.utf16String.toString()]; 1317 }; 1318 const utf16StringDifference = function (a, b) { 1319 let leftIndex = 0; 1320 let rightIndexA = a.length; 1321 let rightIndexB = b.length; 1322 while (leftIndex < rightIndexA && a.charAt(leftIndex).isEqualTo(b.charAt(leftIndex))) { 1323 leftIndex++; 1324 } 1325 while (rightIndexA > leftIndex + 1 && a.charAt(rightIndexA - 1).isEqualTo(b.charAt(rightIndexB - 1))) { 1326 rightIndexA--; 1327 rightIndexB--; 1328 } 1329 return { 1330 utf16String: a.slice(leftIndex, rightIndexA), 1331 offset: leftIndex 1332 }; 1333 }; 1334 1335 class Hash extends TrixObject { 1336 static fromCommonAttributesOfObjects() { 1337 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 1338 if (!objects.length) { 1339 return new this(); 1340 } 1341 let hash = box(objects[0]); 1342 let keys = hash.getKeys(); 1343 objects.slice(1).forEach(object => { 1344 keys = hash.getKeysCommonToHash(box(object)); 1345 hash = hash.slice(keys); 1346 }); 1347 return hash; 1348 } 1349 static box(values) { 1350 return box(values); 1351 } 1352 constructor() { 1353 let values = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1354 super(...arguments); 1355 this.values = copy(values); 1356 } 1357 add(key, value) { 1358 return this.merge(object(key, value)); 1359 } 1360 remove(key) { 1361 return new Hash(copy(this.values, key)); 1362 } 1363 get(key) { 1364 return this.values[key]; 1365 } 1366 has(key) { 1367 return key in this.values; 1368 } 1369 merge(values) { 1370 return new Hash(merge(this.values, unbox(values))); 1371 } 1372 slice(keys) { 1373 const values = {}; 1374 Array.from(keys).forEach(key => { 1375 if (this.has(key)) { 1376 values[key] = this.values[key]; 1377 } 1378 }); 1379 return new Hash(values); 1380 } 1381 getKeys() { 1382 return Object.keys(this.values); 1383 } 1384 getKeysCommonToHash(hash) { 1385 hash = box(hash); 1386 return this.getKeys().filter(key => this.values[key] === hash.values[key]); 1387 } 1388 isEqualTo(values) { 1389 return arraysAreEqual(this.toArray(), box(values).toArray()); 1390 } 1391 isEmpty() { 1392 return this.getKeys().length === 0; 1393 } 1394 toArray() { 1395 if (!this.array) { 1396 const result = []; 1397 for (const key in this.values) { 1398 const value = this.values[key]; 1399 result.push(result.push(key, value)); 1400 } 1401 this.array = result.slice(0); 1402 } 1403 return this.array; 1404 } 1405 toObject() { 1406 return copy(this.values); 1407 } 1408 toJSON() { 1409 return this.toObject(); 1410 } 1411 contentsForInspection() { 1412 return { 1413 values: JSON.stringify(this.values) 1414 }; 1415 } 1416 } 1417 const object = function (key, value) { 1418 const result = {}; 1419 result[key] = value; 1420 return result; 1421 }; 1422 const merge = function (object, values) { 1423 const result = copy(object); 1424 for (const key in values) { 1425 const value = values[key]; 1426 result[key] = value; 1427 } 1428 return result; 1429 }; 1430 const copy = function (object, keyToRemove) { 1431 const result = {}; 1432 const sortedKeys = Object.keys(object).sort(); 1433 sortedKeys.forEach(key => { 1434 if (key !== keyToRemove) { 1435 result[key] = object[key]; 1436 } 1437 }); 1438 return result; 1439 }; 1440 const box = function (object) { 1441 if (object instanceof Hash) { 1442 return object; 1443 } else { 1444 return new Hash(object); 1445 } 1446 }; 1447 const unbox = function (object) { 1448 if (object instanceof Hash) { 1449 return object.values; 1450 } else { 1451 return object; 1452 } 1453 }; 1454 1455 class ObjectGroup { 1456 static groupObjects() { 1457 let ungroupedObjects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 1458 let { 1459 depth, 1460 asTree 1461 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1462 let group; 1463 if (asTree) { 1464 if (depth == null) { 1465 depth = 0; 1466 } 1467 } 1468 const objects = []; 1469 Array.from(ungroupedObjects).forEach(object => { 1470 var _object$canBeGrouped2; 1471 if (group) { 1472 var _object$canBeGrouped, _group$canBeGroupedWi, _group; 1473 if ((_object$canBeGrouped = object.canBeGrouped) !== null && _object$canBeGrouped !== void 0 && _object$canBeGrouped.call(object, depth) && (_group$canBeGroupedWi = (_group = group[group.length - 1]).canBeGroupedWith) !== null && _group$canBeGroupedWi !== void 0 && _group$canBeGroupedWi.call(_group, object, depth)) { 1474 group.push(object); 1475 return; 1476 } else { 1477 objects.push(new this(group, { 1478 depth, 1479 asTree 1480 })); 1481 group = null; 1482 } 1483 } 1484 if ((_object$canBeGrouped2 = object.canBeGrouped) !== null && _object$canBeGrouped2 !== void 0 && _object$canBeGrouped2.call(object, depth)) { 1485 group = [object]; 1486 } else { 1487 objects.push(object); 1488 } 1489 }); 1490 if (group) { 1491 objects.push(new this(group, { 1492 depth, 1493 asTree 1494 })); 1495 } 1496 return objects; 1497 } 1498 constructor() { 1499 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 1500 let { 1501 depth, 1502 asTree 1503 } = arguments.length > 1 ? arguments[1] : undefined; 1504 this.objects = objects; 1505 if (asTree) { 1506 this.depth = depth; 1507 this.objects = this.constructor.groupObjects(this.objects, { 1508 asTree, 1509 depth: this.depth + 1 1510 }); 1511 } 1512 } 1513 getObjects() { 1514 return this.objects; 1515 } 1516 getDepth() { 1517 return this.depth; 1518 } 1519 getCacheKey() { 1520 const keys = ["objectGroup"]; 1521 Array.from(this.getObjects()).forEach(object => { 1522 keys.push(object.getCacheKey()); 1523 }); 1524 return keys.join("/"); 1525 } 1526 } 1527 1528 class ObjectMap extends BasicObject { 1529 constructor() { 1530 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 1531 super(...arguments); 1532 this.objects = {}; 1533 Array.from(objects).forEach(object => { 1534 const hash = JSON.stringify(object); 1535 if (this.objects[hash] == null) { 1536 this.objects[hash] = object; 1537 } 1538 }); 1539 } 1540 find(object) { 1541 const hash = JSON.stringify(object); 1542 return this.objects[hash]; 1543 } 1544 } 1545 1546 class ElementStore { 1547 constructor(elements) { 1548 this.reset(elements); 1549 } 1550 add(element) { 1551 const key = getKey(element); 1552 this.elements[key] = element; 1553 } 1554 remove(element) { 1555 const key = getKey(element); 1556 const value = this.elements[key]; 1557 if (value) { 1558 delete this.elements[key]; 1559 return value; 1560 } 1561 } 1562 reset() { 1563 let elements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 1564 this.elements = {}; 1565 Array.from(elements).forEach(element => { 1566 this.add(element); 1567 }); 1568 return elements; 1569 } 1570 } 1571 const getKey = element => element.dataset.trixStoreKey; 1572 1573 class Operation extends BasicObject { 1574 isPerforming() { 1575 return this.performing === true; 1576 } 1577 hasPerformed() { 1578 return this.performed === true; 1579 } 1580 hasSucceeded() { 1581 return this.performed && this.succeeded; 1582 } 1583 hasFailed() { 1584 return this.performed && !this.succeeded; 1585 } 1586 getPromise() { 1587 if (!this.promise) { 1588 this.promise = new Promise((resolve, reject) => { 1589 this.performing = true; 1590 return this.perform((succeeded, result) => { 1591 this.succeeded = succeeded; 1592 this.performing = false; 1593 this.performed = true; 1594 if (this.succeeded) { 1595 resolve(result); 1596 } else { 1597 reject(result); 1598 } 1599 }); 1600 }); 1601 } 1602 return this.promise; 1603 } 1604 perform(callback) { 1605 return callback(false); 1606 } 1607 release() { 1608 var _this$promise, _this$promise$cancel; 1609 (_this$promise = this.promise) === null || _this$promise === void 0 || (_this$promise$cancel = _this$promise.cancel) === null || _this$promise$cancel === void 0 || _this$promise$cancel.call(_this$promise); 1610 this.promise = null; 1611 this.performing = null; 1612 this.performed = null; 1613 this.succeeded = null; 1614 } 1615 } 1616 Operation.proxyMethod("getPromise().then"); 1617 Operation.proxyMethod("getPromise().catch"); 1618 1619 class ObjectView extends BasicObject { 1620 constructor(object) { 1621 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1622 super(...arguments); 1623 this.object = object; 1624 this.options = options; 1625 this.childViews = []; 1626 this.rootView = this; 1627 } 1628 getNodes() { 1629 if (!this.nodes) { 1630 this.nodes = this.createNodes(); 1631 } 1632 return this.nodes.map(node => node.cloneNode(true)); 1633 } 1634 invalidate() { 1635 var _this$parentView; 1636 this.nodes = null; 1637 this.childViews = []; 1638 return (_this$parentView = this.parentView) === null || _this$parentView === void 0 ? void 0 : _this$parentView.invalidate(); 1639 } 1640 invalidateViewForObject(object) { 1641 var _this$findViewForObje; 1642 return (_this$findViewForObje = this.findViewForObject(object)) === null || _this$findViewForObje === void 0 ? void 0 : _this$findViewForObje.invalidate(); 1643 } 1644 findOrCreateCachedChildView(viewClass, object, options) { 1645 let view = this.getCachedViewForObject(object); 1646 if (view) { 1647 this.recordChildView(view); 1648 } else { 1649 view = this.createChildView(...arguments); 1650 this.cacheViewForObject(view, object); 1651 } 1652 return view; 1653 } 1654 createChildView(viewClass, object) { 1655 let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 1656 if (object instanceof ObjectGroup) { 1657 options.viewClass = viewClass; 1658 viewClass = ObjectGroupView; 1659 } 1660 const view = new viewClass(object, options); 1661 return this.recordChildView(view); 1662 } 1663 recordChildView(view) { 1664 view.parentView = this; 1665 view.rootView = this.rootView; 1666 this.childViews.push(view); 1667 return view; 1668 } 1669 getAllChildViews() { 1670 let views = []; 1671 this.childViews.forEach(childView => { 1672 views.push(childView); 1673 views = views.concat(childView.getAllChildViews()); 1674 }); 1675 return views; 1676 } 1677 findElement() { 1678 return this.findElementForObject(this.object); 1679 } 1680 findElementForObject(object) { 1681 const id = object === null || object === void 0 ? void 0 : object.id; 1682 if (id) { 1683 return this.rootView.element.querySelector("[data-trix-id='".concat(id, "']")); 1684 } 1685 } 1686 findViewForObject(object) { 1687 for (const view of this.getAllChildViews()) { 1688 if (view.object === object) { 1689 return view; 1690 } 1691 } 1692 } 1693 getViewCache() { 1694 if (this.rootView === this) { 1695 if (this.isViewCachingEnabled()) { 1696 if (!this.viewCache) { 1697 this.viewCache = {}; 1698 } 1699 return this.viewCache; 1700 } 1701 } else { 1702 return this.rootView.getViewCache(); 1703 } 1704 } 1705 isViewCachingEnabled() { 1706 return this.shouldCacheViews !== false; 1707 } 1708 enableViewCaching() { 1709 this.shouldCacheViews = true; 1710 } 1711 disableViewCaching() { 1712 this.shouldCacheViews = false; 1713 } 1714 getCachedViewForObject(object) { 1715 var _this$getViewCache; 1716 return (_this$getViewCache = this.getViewCache()) === null || _this$getViewCache === void 0 ? void 0 : _this$getViewCache[object.getCacheKey()]; 1717 } 1718 cacheViewForObject(view, object) { 1719 const cache = this.getViewCache(); 1720 if (cache) { 1721 cache[object.getCacheKey()] = view; 1722 } 1723 } 1724 garbageCollectCachedViews() { 1725 const cache = this.getViewCache(); 1726 if (cache) { 1727 const views = this.getAllChildViews().concat(this); 1728 const objectKeys = views.map(view => view.object.getCacheKey()); 1729 for (const key in cache) { 1730 if (!objectKeys.includes(key)) { 1731 delete cache[key]; 1732 } 1733 } 1734 } 1735 } 1736 } 1737 class ObjectGroupView extends ObjectView { 1738 constructor() { 1739 super(...arguments); 1740 this.objectGroup = this.object; 1741 this.viewClass = this.options.viewClass; 1742 delete this.options.viewClass; 1743 } 1744 getChildViews() { 1745 if (!this.childViews.length) { 1746 Array.from(this.objectGroup.getObjects()).forEach(object => { 1747 this.findOrCreateCachedChildView(this.viewClass, object, this.options); 1748 }); 1749 } 1750 return this.childViews; 1751 } 1752 createNodes() { 1753 const element = this.createContainerElement(); 1754 this.getChildViews().forEach(view => { 1755 Array.from(view.getNodes()).forEach(node => { 1756 element.appendChild(node); 1757 }); 1758 }); 1759 return [element]; 1760 } 1761 createContainerElement() { 1762 let depth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.objectGroup.getDepth(); 1763 return this.getChildViews()[0].createContainerElement(depth); 1764 } 1765 } 1766 1767 /*! @license DOMPurify 3.
vendor: 9,474 bytes, lines 1767-1962
17672.7 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.7/LICENSE */ 1768 1769 const { 1770 entries, 1771 setPrototypeOf, 1772 isFrozen, 1773 getPrototypeOf, 1774 getOwnPropertyDescriptor 1775 } = Object; 1776 let { 1777 freeze, 1778 seal, 1779 create 1780 } = Object; // eslint-disable-line import/no-mutable-exports 1781 let { 1782 apply, 1783 construct 1784 } = typeof Reflect !== 'undefined' && Reflect; 1785 if (!freeze) { 1786 freeze = function freeze(x) { 1787 return x; 1788 }; 1789 } 1790 if (!seal) { 1791 seal = function seal(x) { 1792 return x; 1793 }; 1794 } 1795 if (!apply) { 1796 apply = function apply(func, thisArg) { 1797 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { 1798 args[_key - 2] = arguments[_key]; 1799 } 1800 return func.apply(thisArg, args); 1801 }; 1802 } 1803 if (!construct) { 1804 construct = function construct(Func) { 1805 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 1806 args[_key2 - 1] = arguments[_key2]; 1807 } 1808 return new Func(...args); 1809 }; 1810 } 1811 const arrayForEach = unapply(Array.prototype.forEach); 1812 const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf); 1813 const arrayPop = unapply(Array.prototype.pop); 1814 const arrayPush = unapply(Array.prototype.push); 1815 const arraySplice = unapply(Array.prototype.splice); 1816 const stringToLowerCase = unapply(String.prototype.toLowerCase); 1817 const stringToString = unapply(String.prototype.toString); 1818 const stringMatch = unapply(String.prototype.match); 1819 const stringReplace = unapply(String.prototype.replace); 1820 const stringIndexOf = unapply(String.prototype.indexOf); 1821 const stringTrim = unapply(String.prototype.trim); 1822 const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty); 1823 const regExpTest = unapply(RegExp.prototype.test); 1824 const typeErrorCreate = unconstruct(TypeError); 1825 /** 1826 * Creates a new function that calls the given function with a specified thisArg and arguments. 1827 * 1828 * @param func - The function to be wrapped and called. 1829 * @returns A new function that calls the given function with a specified thisArg and arguments. 1830 */ 1831 function unapply(func) { 1832 return function (thisArg) { 1833 if (thisArg instanceof RegExp) { 1834 thisArg.lastIndex = 0; 1835 } 1836 for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { 1837 args[_key3 - 1] = arguments[_key3]; 1838 } 1839 return apply(func, thisArg, args); 1840 }; 1841 } 1842 /** 1843 * Creates a new function that constructs an instance of the given constructor function with the provided arguments. 1844 * 1845 * @param func - The constructor function to be wrapped and called. 1846 * @returns A new function that constructs an instance of the given constructor function with the provided arguments. 1847 */ 1848 function unconstruct(Func) { 1849 return function () { 1850 for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { 1851 args[_key4] = arguments[_key4]; 1852 } 1853 return construct(Func, args); 1854 }; 1855 } 1856 /** 1857 * Add properties to a lookup table 1858 * 1859 * @param set - The set to which elements will be added. 1860 * @param array - The array containing elements to be added to the set. 1861 * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set. 1862 * @returns The modified set with added elements. 1863 */ 1864 function addToSet(set, array) { 1865 let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase; 1866 if (setPrototypeOf) { 1867 // Make 'in' and truthy checks like Boolean(set.constructor) 1868 // independent of any properties defined on Object.prototype. 1869 // Prevent prototype setters from intercepting set as a this value. 1870 setPrototypeOf(set, null); 1871 } 1872 let l = array.length; 1873 while (l--) { 1874 let element = array[l]; 1875 if (typeof element === 'string') { 1876 const lcElement = transformCaseFunc(element); 1877 if (lcElement !== element) { 1878 // Config presets (e.g. tags.js, attrs.js) are immutable. 1879 if (!isFrozen(array)) { 1880 array[l] = lcElement; 1881 } 1882 element = lcElement; 1883 } 1884 } 1885 set[element] = true; 1886 } 1887 return set; 1888 } 1889 /** 1890 * Clean up an array to harden against CSPP 1891 * 1892 * @param array - The array to be cleaned. 1893 * @returns The cleaned version of the array 1894 */ 1895 function cleanArray(array) { 1896 for (let index = 0; index < array.length; index++) { 1897 const isPropertyExist = objectHasOwnProperty(array, index); 1898 if (!isPropertyExist) { 1899 array[index] = null; 1900 } 1901 } 1902 return array; 1903 } 1904 /** 1905 * Shallow clone an object 1906 * 1907 * @param object - The object to be cloned. 1908 * @returns A new object that copies the original. 1909 */ 1910 function clone(object) { 1911 const newObject = create(null); 1912 for (const [property, value] of entries(object)) { 1913 const isPropertyExist = objectHasOwnProperty(object, property); 1914 if (isPropertyExist) { 1915 if (Array.isArray(value)) { 1916 newObject[property] = cleanArray(value); 1917 } else if (value && typeof value === 'object' && value.constructor === Object) { 1918 newObject[property] = clone(value); 1919 } else { 1920 newObject[property] = value; 1921 } 1922 } 1923 } 1924 return newObject; 1925 } 1926 /** 1927 * This method automatically checks if the prop is function or getter and behaves accordingly. 1928 * 1929 * @param object - The object to look up the getter function in its prototype chain. 1930 * @param prop - The property name for which to find the getter function. 1931 * @returns The getter function found in the prototype chain or a fallback function. 1932 */ 1933 function lookupGetter(object, prop) { 1934 while (object !== null) { 1935 const desc = getOwnPropertyDescriptor(object, prop); 1936 if (desc) { 1937 if (desc.get) { 1938 return unapply(desc.get); 1939 } 1940 if (typeof desc.value === 'function') { 1941 return unapply(desc.value); 1942 } 1943 } 1944 object = getPrototypeOf(object); 1945 } 1946 function fallbackValue() { 1947 return null; 1948 } 1949 return fallbackValue; 1950 } 1951 const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']); 1952 const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'slot', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']); 1953 const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); 1954 // List of SVG elements that are disallowed by default. 1955 // We still need to know them so that we can do namespace 1956 // checks properly in case one wants to add them to 1957 // allow-list. 1958 const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']); 1959 const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']); 1960 // Similarly to SVG, we want to know all MathML elements, 1961 // even those that we disallow by default. 1962 const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'n
1962one']); 1963 const text = freeze(['#text']); 1964 const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']); 1965 const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']); 1966 const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'n
vendor: 8,803 bytes, lines 1966-2181
1966otation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']); 1967 const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']); 1968 1969 // eslint-disable-next-line unicorn/better-regex 1970 const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode 1971 const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm); 1972 const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex 1973 const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape 1974 const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape 1975 const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape 1976 ); 1977 const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); 1978 const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex 1979 ); 1980 const DOCTYPE_NAME = seal(/^html$/i); 1981 const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i); 1982 var EXPRESSIONS = /*#__PURE__*/Object.freeze({ 1983 __proto__: null, 1984 ARIA_ATTR: ARIA_ATTR, 1985 ATTR_WHITESPACE: ATTR_WHITESPACE, 1986 CUSTOM_ELEMENT: CUSTOM_ELEMENT, 1987 DATA_ATTR: DATA_ATTR, 1988 DOCTYPE_NAME: DOCTYPE_NAME, 1989 ERB_EXPR: ERB_EXPR, 1990 IS_ALLOWED_URI: IS_ALLOWED_URI, 1991 IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA, 1992 MUSTACHE_EXPR: MUSTACHE_EXPR, 1993 TMPLIT_EXPR: TMPLIT_EXPR 1994 }); 1995 1996 /* eslint-disable @typescript-eslint/indent */ 1997 // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType 1998 const NODE_TYPE = { 1999 element: 1, 2000 attribute: 2, 2001 text: 3, 2002 cdataSection: 4, 2003 entityReference: 5, 2004 // Deprecated 2005 entityNode: 6, 2006 // Deprecated 2007 progressingInstruction: 7, 2008 comment: 8, 2009 document: 9, 2010 documentType: 10, 2011 documentFragment: 11, 2012 notation: 12 // Deprecated 2013 }; 2014 const getGlobal = function getGlobal() { 2015 return typeof window === 'undefined' ? null : window; 2016 }; 2017 /** 2018 * Creates a no-op policy for internal use only. 2019 * Don't export this function outside this module! 2020 * @param trustedTypes The policy factory. 2021 * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix). 2022 * @return The policy created (or null, if Trusted Types 2023 * are not supported or creating the policy failed). 2024 */ 2025 const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) { 2026 if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') { 2027 return null; 2028 } 2029 // Allow the callers to control the unique policy name 2030 // by adding a data-tt-policy-suffix to the script element with the DOMPurify. 2031 // Policy creation with duplicate names throws in Trusted Types. 2032 let suffix = null; 2033 const ATTR_NAME = 'data-tt-policy-suffix'; 2034 if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) { 2035 suffix = purifyHostElement.getAttribute(ATTR_NAME); 2036 } 2037 const policyName = 'dompurify' + (suffix ? '#' + suffix : ''); 2038 try { 2039 return trustedTypes.createPolicy(policyName, { 2040 createHTML(html) { 2041 return html; 2042 }, 2043 createScriptURL(scriptUrl) { 2044 return scriptUrl; 2045 } 2046 }); 2047 } catch (_) { 2048 // Policy creation failed (most likely another DOMPurify script has 2049 // already run). Skip creating the policy, as this will only cause errors 2050 // if TT are enforced. 2051 console.warn('TrustedTypes policy ' + policyName + ' could not be created.'); 2052 return null; 2053 } 2054 }; 2055 const _createHooksMap = function _createHooksMap() { 2056 return { 2057 afterSanitizeAttributes: [], 2058 afterSanitizeElements: [], 2059 afterSanitizeShadowDOM: [], 2060 beforeSanitizeAttributes: [], 2061 beforeSanitizeElements: [], 2062 beforeSanitizeShadowDOM: [], 2063 uponSanitizeAttribute: [], 2064 uponSanitizeElement: [], 2065 uponSanitizeShadowNode: [] 2066 }; 2067 }; 2068 function createDOMPurify() { 2069 let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal(); 2070 const DOMPurify = root => createDOMPurify(root); 2071 DOMPurify.version = '3.2.7'; 2072 DOMPurify.removed = []; 2073 if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) { 2074 // Not running in a browser, provide a factory function 2075 // so that you can pass your own Window 2076 DOMPurify.isSupported = false; 2077 return DOMPurify; 2078 } 2079 let { 2080 document 2081 } = window; 2082 const originalDocument = document; 2083 const currentScript = originalDocument.currentScript; 2084 const { 2085 DocumentFragment, 2086 HTMLTemplateElement, 2087 Node, 2088 Element, 2089 NodeFilter, 2090 NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap, 2091 HTMLFormElement, 2092 DOMParser, 2093 trustedTypes 2094 } = window; 2095 const ElementPrototype = Element.prototype; 2096 const cloneNode = lookupGetter(ElementPrototype, 'cloneNode'); 2097 const remove = lookupGetter(ElementPrototype, 'remove'); 2098 const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling'); 2099 const getChildNodes = lookupGetter(ElementPrototype, 'childNodes'); 2100 const getParentNode = lookupGetter(ElementPrototype, 'parentNode'); 2101 // As per issue #47, the web-components registry is inherited by a 2102 // new document created via createHTMLDocument. As per the spec 2103 // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries) 2104 // a new empty registry is used when creating a template contents owner 2105 // document, so we use that as our parent document to ensure nothing 2106 // is inherited. 2107 if (typeof HTMLTemplateElement === 'function') { 2108 const template = document.createElement('template'); 2109 if (template.content && template.content.ownerDocument) { 2110 document = template.content.ownerDocument; 2111 } 2112 } 2113 let trustedTypesPolicy; 2114 let emptyHTML = ''; 2115 const { 2116 implementation, 2117 createNodeIterator, 2118 createDocumentFragment, 2119 getElementsByTagName 2120 } = document; 2121 const { 2122 importNode 2123 } = originalDocument; 2124 let hooks = _createHooksMap(); 2125 /** 2126 * Expose whether this browser supports running the full DOMPurify. 2127 */ 2128 DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined; 2129 const { 2130 MUSTACHE_EXPR, 2131 ERB_EXPR, 2132 TMPLIT_EXPR, 2133 DATA_ATTR, 2134 ARIA_ATTR, 2135 IS_SCRIPT_OR_DATA, 2136 ATTR_WHITESPACE, 2137 CUSTOM_ELEMENT 2138 } = EXPRESSIONS; 2139 let { 2140 IS_ALLOWED_URI: IS_ALLOWED_URI$1 2141 } = EXPRESSIONS; 2142 /** 2143 * We consider the elements and attributes below to be safe. Ideally 2144 * don't add any new ones but feel free to remove unwanted ones. 2145 */ 2146 /* allowed element names */ 2147 let ALLOWED_TAGS = null; 2148 const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]); 2149 /* Allowed attribute names */ 2150 let ALLOWED_ATTR = null; 2151 const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]); 2152 /* 2153 * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements. 2154 * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements) 2155 * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list) 2156 * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`. 2157 */ 2158 let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, { 2159 tagNameCheck: { 2160 writable: true, 2161 configurable: false, 2162 enumerable: true, 2163 value: null 2164 }, 2165 attributeNameCheck: { 2166 writable: true, 2167 configurable: false, 2168 enumerable: true, 2169 value: null 2170 }, 2171 allowCustomizedBuiltInElements: { 2172 writable: true, 2173 configurable: false, 2174 enumerable: true, 2175 value: false 2176 } 2177 })); 2178 /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */ 2179 let FORBID_TAGS = null; 2180 /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */ 2181 let FORBID_ATTR = null
vendor: 3,330 bytes, lines 2181-2245
2181; 2182 /* Decide if ARIA attributes are okay */ 2183 let ALLOW_ARIA_ATTR = true; 2184 /* Decide if custom data attributes are okay */ 2185 let ALLOW_DATA_ATTR = true; 2186 /* Decide if unknown protocols are okay */ 2187 let ALLOW_UNKNOWN_PROTOCOLS = false; 2188 /* Decide if self-closing tags in attributes are allowed. 2189 * Usually removed due to a mXSS issue in jQuery 3.0 */ 2190 let ALLOW_SELF_CLOSE_IN_ATTR = true; 2191 /* Output should be safe for common template engines. 2192 * This means, DOMPurify removes data attributes, mustaches and ERB 2193 */ 2194 let SAFE_FOR_TEMPLATES = false; 2195 /* Output should be safe even for XML used within HTML and alike. 2196 * This means, DOMPurify removes comments when containing risky content. 2197 */ 2198 let SAFE_FOR_XML = true; 2199 /* Decide if document with <html>... should be returned */ 2200 let WHOLE_DOCUMENT = false; 2201 /* Track whether config is already set on this instance of DOMPurify. */ 2202 let SET_CONFIG = false; 2203 /* Decide if all elements (e.g. style, script) must be children of 2204 * document.body. By default, browsers might move them to document.head */ 2205 let FORCE_BODY = false; 2206 /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html 2207 * string (or a TrustedHTML object if Trusted Types are supported). 2208 * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead 2209 */ 2210 let RETURN_DOM = false; 2211 /* Decide if a DOM `DocumentFragment` should be returned, instead of a html 2212 * string (or a TrustedHTML object if Trusted Types are supported) */ 2213 let RETURN_DOM_FRAGMENT = false; 2214 /* Try to return a Trusted Type object instead of a string, return a string in 2215 * case Trusted Types are not supported */ 2216 let RETURN_TRUSTED_TYPE = false; 2217 /* Output should be free from DOM clobbering attacks? 2218 * This sanitizes markups named with colliding, clobberable built-in DOM APIs. 2219 */ 2220 let SANITIZE_DOM = true; 2221 /* Achieve full DOM Clobbering protection by isolating the namespace of named 2222 * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules. 2223 * 2224 * HTML/DOM spec rules that enable DOM Clobbering: 2225 * - Named Access on Window (§7.3.3) 2226 * - DOM Tree Accessors (§3.1.5) 2227 * - Form Element Parent-Child Relations (§4.10.3) 2228 * - Iframe srcdoc / Nested WindowProxies (§4.8.5) 2229 * - HTMLCollection (§4.2.10.2) 2230 * 2231 * Namespace isolation is implemented by prefixing `id` and `name` attributes 2232 * with a constant string, i.e., `user-content-` 2233 */ 2234 let SANITIZE_NAMED_PROPS = false; 2235 const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-'; 2236 /* Keep element content when removing element? */ 2237 let KEEP_CONTENT = true; 2238 /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead 2239 * of importing it into a new Document and returning a sanitized copy */ 2240 let IN_PLACE = false; 2241 /* Allow usage of profiles like html, svg and mathMl */ 2242 let USE_PROFILES = {}; 2243 /* Tags to ignore content of when KEEP_CONTENT is true */ 2244 let FORBID_CONTENTS = null; 2245 const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'n
vendor: 5,875 bytes, lines 2245-2332
2245oscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']); 2246 /* Tags that are safe for data: URIs */ 2247 let DATA_URI_TAGS = null; 2248 const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']); 2249 /* Attributes safe for values like "javascript:" */ 2250 let URI_SAFE_ATTRIBUTES = null; 2251 const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']); 2252 const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; 2253 const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; 2254 const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; 2255 /* Document namespace */ 2256 let NAMESPACE = HTML_NAMESPACE; 2257 let IS_EMPTY_INPUT = false; 2258 /* Allowed XHTML+XML namespaces */ 2259 let ALLOWED_NAMESPACES = null; 2260 const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString); 2261 let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']); 2262 let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']); 2263 // Certain elements are allowed in both SVG and HTML 2264 // namespace. We need to specify them explicitly 2265 // so that they don't get erroneously deleted from 2266 // HTML namespace. 2267 const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']); 2268 /* Parsing of strict XHTML documents */ 2269 let PARSER_MEDIA_TYPE = null; 2270 const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html']; 2271 const DEFAULT_PARSER_MEDIA_TYPE = 'text/html'; 2272 let transformCaseFunc = null; 2273 /* Keep a reference to config to pass to hooks */ 2274 let CONFIG = null; 2275 /* Ideally, do not touch anything below this line */ 2276 /* ______________________________________________ */ 2277 const formElement = document.createElement('form'); 2278 const isRegexOrFunction = function isRegexOrFunction(testValue) { 2279 return testValue instanceof RegExp || testValue instanceof Function; 2280 }; 2281 /** 2282 * _parseConfig 2283 * 2284 * @param cfg optional config literal 2285 */ 2286 // eslint-disable-next-line complexity 2287 const _parseConfig = function _parseConfig() { 2288 let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 2289 if (CONFIG && CONFIG === cfg) { 2290 return; 2291 } 2292 /* Shield configuration object from tampering */ 2293 if (!cfg || typeof cfg !== 'object') { 2294 cfg = {}; 2295 } 2296 /* Shield configuration object from prototype pollution */ 2297 cfg = clone(cfg); 2298 PARSER_MEDIA_TYPE = 2299 // eslint-disable-next-line unicorn/prefer-includes 2300 SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE; 2301 // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is. 2302 transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase; 2303 /* Set configuration parameters */ 2304 ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS; 2305 ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR; 2306 ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES; 2307 URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES; 2308 DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS; 2309 FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS; 2310 FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({}); 2311 FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({}); 2312 USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false; 2313 ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true 2314 ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true 2315 ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false 2316 ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true 2317 SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false 2318 SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true 2319 WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false 2320 RETURN_DOM = cfg.RETURN_DOM || false; // Default false 2321 RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false 2322 RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false 2323 FORCE_BODY = cfg.FORCE_BODY || false; // Default false 2324 SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true 2325 SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false 2326 KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true 2327 IN_PLACE = cfg.IN_PLACE || false; // Default false 2328 IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI; 2329 NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; 2330 MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS; 2331 HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS; 2332 CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING ||
vendor: 1,622 bytes, lines 2332-2371
2332{}; 2333 if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) { 2334 CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck; 2335 } 2336 if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) { 2337 CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck; 2338 } 2339 if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') { 2340 CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements; 2341 } 2342 if (SAFE_FOR_TEMPLATES) { 2343 ALLOW_DATA_ATTR = false; 2344 } 2345 if (RETURN_DOM_FRAGMENT) { 2346 RETURN_DOM = true; 2347 } 2348 /* Parse profile info */ 2349 if (USE_PROFILES) { 2350 ALLOWED_TAGS = addToSet({}, text); 2351 ALLOWED_ATTR = []; 2352 if (USE_PROFILES.html === true) { 2353 addToSet(ALLOWED_TAGS, html$1); 2354 addToSet(ALLOWED_ATTR, html); 2355 } 2356 if (USE_PROFILES.svg === true) { 2357 addToSet(ALLOWED_TAGS, svg$1); 2358 addToSet(ALLOWED_ATTR, svg); 2359 addToSet(ALLOWED_ATTR, xml); 2360 } 2361 if (USE_PROFILES.svgFilters === true) { 2362 addToSet(ALLOWED_TAGS, svgFilters); 2363 addToSet(ALLOWED_ATTR, svg); 2364 addToSet(ALLOWED_ATTR, xml); 2365 } 2366 if (USE_PROFILES.mathMl === true) { 2367 addToSet(ALLOWED_TAGS, mathMl$1); 2368 addToSet(ALLOWED_ATTR, mathMl); 2369 addToSet(ALLOWED_ATTR, xml); 2370 } 2371 }
vendor: 5,664 bytes, lines 2372-2499
2372 /* Merge configuration parameters */ 2373 if (cfg.ADD_TAGS) { 2374 if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { 2375 ALLOWED_TAGS = clone(ALLOWED_TAGS); 2376 } 2377 addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc); 2378 } 2379 if (cfg.ADD_ATTR) { 2380 if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { 2381 ALLOWED_ATTR = clone(ALLOWED_ATTR); 2382 } 2383 addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc); 2384 } 2385 if (cfg.ADD_URI_SAFE_ATTR) { 2386 addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc); 2387 } 2388 if (cfg.FORBID_CONTENTS) { 2389 if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { 2390 FORBID_CONTENTS = clone(FORBID_CONTENTS); 2391 } 2392 addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc); 2393 } 2394 /* Add #text in case KEEP_CONTENT is set to true */ 2395 if (KEEP_CONTENT) { 2396 ALLOWED_TAGS['#text'] = true; 2397 } 2398 /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */ 2399 if (WHOLE_DOCUMENT) { 2400 addToSet(ALLOWED_TAGS, ['html', 'head', 'body']); 2401 } 2402 /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */ 2403 if (ALLOWED_TAGS.table) { 2404 addToSet(ALLOWED_TAGS, ['tbody']); 2405 delete FORBID_TAGS.tbody; 2406 } 2407 if (cfg.TRUSTED_TYPES_POLICY) { 2408 if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') { 2409 throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.'); 2410 } 2411 if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') { 2412 throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.'); 2413 } 2414 // Overwrite existing TrustedTypes policy. 2415 trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY; 2416 // Sign local variables required by `sanitize`. 2417 emptyHTML = trustedTypesPolicy.createHTML(''); 2418 } else { 2419 // Uninitialized policy, attempt to initialize the internal dompurify policy. 2420 if (trustedTypesPolicy === undefined) { 2421 trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript); 2422 } 2423 // If creating the internal policy succeeded sign internal variables. 2424 if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') { 2425 emptyHTML = trustedTypesPolicy.createHTML(''); 2426 } 2427 } 2428 // Prevent further manipulation of configuration. 2429 // Not available in IE8, Safari 5, etc. 2430 if (freeze) { 2431 freeze(cfg); 2432 } 2433 CONFIG = cfg; 2434 }; 2435 /* Keep track of all possible SVG and MathML tags 2436 * so that we can perform the namespace checks 2437 * correctly. */ 2438 const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]); 2439 const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]); 2440 /** 2441 * @param element a DOM element whose namespace is being checked 2442 * @returns Return false if the element has a 2443 * namespace that a spec-compliant parser would never 2444 * return. Return true otherwise. 2445 */ 2446 const _checkValidNamespace = function _checkValidNamespace(element) { 2447 let parent = getParentNode(element); 2448 // In JSDOM, if we're inside shadow DOM, then parentNode 2449 // can be null. We just simulate parent in this case. 2450 if (!parent || !parent.tagName) { 2451 parent = { 2452 namespaceURI: NAMESPACE, 2453 tagName: 'template' 2454 }; 2455 } 2456 const tagName = stringToLowerCase(element.tagName); 2457 const parentTagName = stringToLowerCase(parent.tagName); 2458 if (!ALLOWED_NAMESPACES[element.namespaceURI]) { 2459 return false; 2460 } 2461 if (element.namespaceURI === SVG_NAMESPACE) { 2462 // The only way to switch from HTML namespace to SVG 2463 // is via <svg>. If it happens via any other tag, then 2464 // it should be killed. 2465 if (parent.namespaceURI === HTML_NAMESPACE) { 2466 return tagName === 'svg'; 2467 } 2468 // The only way to switch from MathML to SVG is via` 2469 // svg if parent is either <annotation-xml> or MathML 2470 // text integration points. 2471 if (parent.namespaceURI === MATHML_NAMESPACE) { 2472 return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]); 2473 } 2474 // We only allow elements that are defined in SVG 2475 // spec. All others are disallowed in SVG namespace. 2476 return Boolean(ALL_SVG_TAGS[tagName]); 2477 } 2478 if (element.namespaceURI === MATHML_NAMESPACE) { 2479 // The only way to switch from HTML namespace to MathML 2480 // is via <math>. If it happens via any other tag, then 2481 // it should be killed. 2482 if (parent.namespaceURI === HTML_NAMESPACE) { 2483 return tagName === 'math'; 2484 } 2485 // The only way to switch from SVG to MathML is via 2486 // <math> and HTML integration points 2487 if (parent.namespaceURI === SVG_NAMESPACE) { 2488 return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName]; 2489 } 2490 // We only allow elements that are defined in MathML 2491 // spec. All others are disallowed in MathML namespace. 2492 return Boolean(ALL_MATHML_TAGS[tagName]); 2493 } 2494 if (element.namespaceURI === HTML_NAMESPACE) { 2495 // The only way to switch from SVG to HTML is via 2496 // HTML integration points, and from MathML to HTML 2497 // is via MathML text integration points 2498 if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) { 2499 return false;
2500 } 2501 if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) { 2502 return false; 2503 } 2504 // We disallow tags that are specific for MathML 2505 // or SVG and should never appear in HTML namespace 2506 return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]); 2507 } 2508 // For XHTML and XML documents that support custom namespaces 2509 if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) { 2510 return true; 2511 } 2512 // The code should never reach this place (this means 2513 // that the element somehow got namespace that is not 2514 // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES). 2515 // Return false just in case. 2516 return false; 2517 }; 2518 /** 2519 * _forceRemove 2520 * 2521 * @param node a DOM node 2522 */ 2523 const _forceRemove = function _forceRemove(node) { 2524 arrayPush(DOMPurify.removed, { 2525 element: node 2526 }); 2527 try {
vendor: 6,975 bytes, lines 2528-2695
2528 // eslint-disable-next-line unicorn/prefer-dom-node-remove 2529 getParentNode(node).removeChild(node); 2530 } catch (_) { 2531 remove(node); 2532 } 2533 }; 2534 /** 2535 * _removeAttribute 2536 * 2537 * @param name an Attribute name 2538 * @param element a DOM node 2539 */ 2540 const _removeAttribute = function _removeAttribute(name, element) { 2541 try { 2542 arrayPush(DOMPurify.removed, { 2543 attribute: element.getAttributeNode(name), 2544 from: element 2545 }); 2546 } catch (_) { 2547 arrayPush(DOMPurify.removed, { 2548 attribute: null, 2549 from: element 2550 }); 2551 } 2552 element.removeAttribute(name); 2553 // We void attribute values for unremovable "is" attributes 2554 if (name === 'is') { 2555 if (RETURN_DOM || RETURN_DOM_FRAGMENT) { 2556 try { 2557 _forceRemove(element); 2558 } catch (_) {} 2559 } else { 2560 try { 2561 element.setAttribute(name, ''); 2562 } catch (_) {} 2563 } 2564 } 2565 }; 2566 /** 2567 * _initDocument 2568 * 2569 * @param dirty - a string of dirty markup 2570 * @return a DOM, filled with the dirty markup 2571 */ 2572 const _initDocument = function _initDocument(dirty) { 2573 /* Create a HTML document */ 2574 let doc = null; 2575 let leadingWhitespace = null; 2576 if (FORCE_BODY) { 2577 dirty = '<remove></remove>' + dirty; 2578 } else { 2579 /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */ 2580 const matches = stringMatch(dirty, /^[\r\n\t ]+/); 2581 leadingWhitespace = matches && matches[0]; 2582 } 2583 if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) { 2584 // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict) 2585 dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>'; 2586 } 2587 const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; 2588 /* 2589 * Use the DOMParser API by default, fallback later if needs be 2590 * DOMParser not work for svg when has multiple root element. 2591 */ 2592 if (NAMESPACE === HTML_NAMESPACE) { 2593 try { 2594 doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE); 2595 } catch (_) {} 2596 } 2597 /* Use createHTMLDocument in case DOMParser is not available */ 2598 if (!doc || !doc.documentElement) { 2599 doc = implementation.createDocument(NAMESPACE, 'template', null); 2600 try { 2601 doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload; 2602 } catch (_) { 2603 // Syntax error if dirtyPayload is invalid xml 2604 } 2605 } 2606 const body = doc.body || doc.documentElement; 2607 if (dirty && leadingWhitespace) { 2608 body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null); 2609 } 2610 /* Work on whole document or just its body */ 2611 if (NAMESPACE === HTML_NAMESPACE) { 2612 return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0]; 2613 } 2614 return WHOLE_DOCUMENT ? doc.documentElement : body; 2615 }; 2616 /** 2617 * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document. 2618 * 2619 * @param root The root element or node to start traversing on. 2620 * @return The created NodeIterator 2621 */ 2622 const _createNodeIterator = function _createNodeIterator(root) { 2623 return createNodeIterator.call(root.ownerDocument || root, root, 2624 // eslint-disable-next-line no-bitwise 2625 NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null); 2626 }; 2627 /** 2628 * _isClobbered 2629 * 2630 * @param element element to check for clobbering attacks 2631 * @return true if clobbered, false if safe 2632 */ 2633 const _isClobbered = function _isClobbered(element) { 2634 return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function'); 2635 }; 2636 /** 2637 * Checks whether the given object is a DOM node. 2638 * 2639 * @param value object to check whether it's a DOM node 2640 * @return true is object is a DOM node 2641 */ 2642 const _isNode = function _isNode(value) { 2643 return typeof Node === 'function' && value instanceof Node; 2644 }; 2645 function _executeHooks(hooks, currentNode, data) { 2646 arrayForEach(hooks, hook => { 2647 hook.call(DOMPurify, currentNode, data, CONFIG); 2648 }); 2649 } 2650 /** 2651 * _sanitizeElements 2652 * 2653 * @protect nodeName 2654 * @protect textContent 2655 * @protect removeChild 2656 * @param currentNode to check for permission to exist 2657 * @return true if node was killed, false if left alive 2658 */ 2659 const _sanitizeElements = function _sanitizeElements(currentNode) { 2660 let content = null; 2661 /* Execute a hook if present */ 2662 _executeHooks(hooks.beforeSanitizeElements, currentNode, null); 2663 /* Check if element is clobbered or can clobber */ 2664 if (_isClobbered(currentNode)) { 2665 _forceRemove(currentNode); 2666 return true; 2667 } 2668 /* Now let's check the element's type and name */ 2669 const tagName = transformCaseFunc(currentNode.nodeName); 2670 /* Execute a hook if present */ 2671 _executeHooks(hooks.uponSanitizeElement, currentNode, { 2672 tagName, 2673 allowedTags: ALLOWED_TAGS 2674 }); 2675 /* Detect mXSS attempts abusing namespace confusion */ 2676 if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) { 2677 _forceRemove(currentNode); 2678 return true; 2679 } 2680 /* Remove any occurrence of processing instructions */ 2681 if (currentNode.nodeType === NODE_TYPE.progressingInstruction) { 2682 _forceRemove(currentNode); 2683 return true; 2684 } 2685 /* Remove any kind of possibly harmful comments */ 2686 if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) { 2687 _forceRemove(currentNode); 2688 return true; 2689 } 2690 /* Remove element if anything forbids its presence */ 2691 if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { 2692 /* Check if we have a custom element to handle */ 2693 if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) { 2694 if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) { 2695 return false;
vendor: 4,720 bytes, lines 2696-2772
2696 } 2697 if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) { 2698 return false; 2699 } 2700 } 2701 /* Keep content except for bad-listed elements */ 2702 if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) { 2703 const parentNode = getParentNode(currentNode) || currentNode.parentNode; 2704 const childNodes = getChildNodes(currentNode) || currentNode.childNodes; 2705 if (childNodes && parentNode) { 2706 const childCount = childNodes.length; 2707 for (let i = childCount - 1; i >= 0; --i) { 2708 const childClone = cloneNode(childNodes[i], true); 2709 childClone.__removalCount = (currentNode.__removalCount || 0) + 1; 2710 parentNode.insertBefore(childClone, getNextSibling(currentNode)); 2711 } 2712 } 2713 } 2714 _forceRemove(currentNode); 2715 return true; 2716 } 2717 /* Check whether element has a valid namespace */ 2718 if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) { 2719 _forceRemove(currentNode); 2720 return true; 2721 } 2722 /* Make sure that older browsers don't get fallback-tag mXSS */ 2723 if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) { 2724 _forceRemove(currentNode); 2725 return true; 2726 } 2727 /* Sanitize element content to be template-safe */ 2728 if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) { 2729 /* Get the element's text content */ 2730 content = currentNode.textContent; 2731 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => { 2732 content = stringReplace(content, expr, ' '); 2733 }); 2734 if (currentNode.textContent !== content) { 2735 arrayPush(DOMPurify.removed, { 2736 element: currentNode.cloneNode() 2737 }); 2738 currentNode.textContent = content; 2739 } 2740 } 2741 /* Execute a hook if present */ 2742 _executeHooks(hooks.afterSanitizeElements, currentNode, null); 2743 return false; 2744 }; 2745 /** 2746 * _isValidAttribute 2747 * 2748 * @param lcTag Lowercase tag name of containing element. 2749 * @param lcName Lowercase attribute name. 2750 * @param value Attribute value. 2751 * @return Returns true if `value` is valid, otherwise false. 2752 */ 2753 // eslint-disable-next-line complexity 2754 const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) { 2755 /* Make sure attribute cannot clobber */ 2756 if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) { 2757 return false; 2758 } 2759 /* Allow valid data-* attributes: At least one character after "-" 2760 (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes) 2761 XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804) 2762 We don't need to check the value; it's always URI safe. */ 2763 if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ;else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ;else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) { 2764 if ( 2765 // First condition does a very basic check if a) it's basically a valid custom element tagname AND 2766 // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck 2767 // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck 2768 _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) || 2769 // Alternative, second condition checks if it's an `is`-attribute, AND 2770 // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck 2771 lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ;else { 2772 return false;
vendor: 11,116 bytes, lines 2773-3046
2773 } 2774 /* Check value is safe. First, is attr inert? If so, is safe */ 2775 } else if (URI_SAFE_ATTRIBUTES[lcName]) ;else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ;else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ;else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ;else if (value) { 2776 return false; 2777 } else ; 2778 return true; 2779 }; 2780 /** 2781 * _isBasicCustomElement 2782 * checks if at least one dash is included in tagName, and it's not the first char 2783 * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name 2784 * 2785 * @param tagName name of the tag of the node to sanitize 2786 * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false. 2787 */ 2788 const _isBasicCustomElement = function _isBasicCustomElement(tagName) { 2789 return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT); 2790 }; 2791 /** 2792 * _sanitizeAttributes 2793 * 2794 * @protect attributes 2795 * @protect nodeName 2796 * @protect removeAttribute 2797 * @protect setAttribute 2798 * 2799 * @param currentNode to sanitize 2800 */ 2801 const _sanitizeAttributes = function _sanitizeAttributes(currentNode) { 2802 /* Execute a hook if present */ 2803 _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null); 2804 const { 2805 attributes 2806 } = currentNode; 2807 /* Check if we have attributes; if not we might have a text node */ 2808 if (!attributes || _isClobbered(currentNode)) { 2809 return; 2810 } 2811 const hookEvent = { 2812 attrName: '', 2813 attrValue: '', 2814 keepAttr: true, 2815 allowedAttributes: ALLOWED_ATTR, 2816 forceKeepAttr: undefined 2817 }; 2818 let l = attributes.length; 2819 /* Go backwards over all attributes; safely remove bad ones */ 2820 while (l--) { 2821 const attr = attributes[l]; 2822 const { 2823 name, 2824 namespaceURI, 2825 value: attrValue 2826 } = attr; 2827 const lcName = transformCaseFunc(name); 2828 const initValue = attrValue; 2829 let value = name === 'value' ? initValue : stringTrim(initValue); 2830 /* Execute a hook if present */ 2831 hookEvent.attrName = lcName; 2832 hookEvent.attrValue = value; 2833 hookEvent.keepAttr = true; 2834 hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set 2835 _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent); 2836 value = hookEvent.attrValue; 2837 /* Full DOM Clobbering protection via namespace isolation, 2838 * Prefix id and name attributes with `user-content-` 2839 */ 2840 if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) { 2841 // Remove the attribute with this value 2842 _removeAttribute(name, currentNode); 2843 // Prefix the value and later re-create the attribute with the sanitized value 2844 value = SANITIZE_NAMED_PROPS_PREFIX + value; 2845 } 2846 /* Work around a security issue with comments inside attributes */ 2847 if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title|textarea)/i, value)) { 2848 _removeAttribute(name, currentNode); 2849 continue; 2850 } 2851 /* Make sure we cannot easily use animated hrefs, even if animations are allowed */ 2852 if (lcName === 'attributename' && stringMatch(value, 'href')) { 2853 _removeAttribute(name, currentNode); 2854 continue; 2855 } 2856 /* Did the hooks approve of the attribute? */ 2857 if (hookEvent.forceKeepAttr) { 2858 continue; 2859 } 2860 /* Did the hooks approve of the attribute? */ 2861 if (!hookEvent.keepAttr) { 2862 _removeAttribute(name, currentNode); 2863 continue; 2864 } 2865 /* Work around a security issue in jQuery 3.0 */ 2866 if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) { 2867 _removeAttribute(name, currentNode); 2868 continue; 2869 } 2870 /* Sanitize attribute content to be template-safe */ 2871 if (SAFE_FOR_TEMPLATES) { 2872 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => { 2873 value = stringReplace(value, expr, ' '); 2874 }); 2875 } 2876 /* Is `value` valid for this attribute? */ 2877 const lcTag = transformCaseFunc(currentNode.nodeName); 2878 if (!_isValidAttribute(lcTag, lcName, value)) { 2879 _removeAttribute(name, currentNode); 2880 continue; 2881 } 2882 /* Handle attributes that require Trusted Types */ 2883 if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') { 2884 if (namespaceURI) ;else { 2885 switch (trustedTypes.getAttributeType(lcTag, lcName)) { 2886 case 'TrustedHTML': 2887 { 2888 value = trustedTypesPolicy.createHTML(value); 2889 break; 2890 } 2891 case 'TrustedScriptURL': 2892 { 2893 value = trustedTypesPolicy.createScriptURL(value); 2894 break; 2895 } 2896 } 2897 } 2898 } 2899 /* Handle invalid data-* attribute set by try-catching it */ 2900 if (value !== initValue) { 2901 try { 2902 if (namespaceURI) { 2903 currentNode.setAttributeNS(namespaceURI, name, value); 2904 } else { 2905 /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */ 2906 currentNode.setAttribute(name, value); 2907 } 2908 if (_isClobbered(currentNode)) { 2909 _forceRemove(currentNode); 2910 } else { 2911 arrayPop(DOMPurify.removed); 2912 } 2913 } catch (_) { 2914 _removeAttribute(name, currentNode); 2915 } 2916 } 2917 } 2918 /* Execute a hook if present */ 2919 _executeHooks(hooks.afterSanitizeAttributes, currentNode, null); 2920 }; 2921 /** 2922 * _sanitizeShadowDOM 2923 * 2924 * @param fragment to iterate over recursively 2925 */ 2926 const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) { 2927 let shadowNode = null; 2928 const shadowIterator = _createNodeIterator(fragment); 2929 /* Execute a hook if present */ 2930 _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null); 2931 while (shadowNode = shadowIterator.nextNode()) { 2932 /* Execute a hook if present */ 2933 _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null); 2934 /* Sanitize tags and elements */ 2935 _sanitizeElements(shadowNode); 2936 /* Check attributes next */ 2937 _sanitizeAttributes(shadowNode); 2938 /* Deep shadow DOM detected */ 2939 if (shadowNode.content instanceof DocumentFragment) { 2940 _sanitizeShadowDOM(shadowNode.content); 2941 } 2942 } 2943 /* Execute a hook if present */ 2944 _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null); 2945 }; 2946 // eslint-disable-next-line complexity 2947 DOMPurify.sanitize = function (dirty) { 2948 let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 2949 let body = null; 2950 let importedNode = null; 2951 let currentNode = null; 2952 let returnNode = null; 2953 /* Make sure we have a string to sanitize. 2954 DO NOT return early, as this will return the wrong type if 2955 the user has requested a DOM object rather than a string */ 2956 IS_EMPTY_INPUT = !dirty; 2957 if (IS_EMPTY_INPUT) { 2958 dirty = '<!-->'; 2959 } 2960 /* Stringify, in case dirty is an object */ 2961 if (typeof dirty !== 'string' && !_isNode(dirty)) { 2962 if (typeof dirty.toString === 'function') { 2963 dirty = dirty.toString(); 2964 if (typeof dirty !== 'string') { 2965 throw typeErrorCreate('dirty is not a string, aborting'); 2966 } 2967 } else { 2968 throw typeErrorCreate('toString is not a function'); 2969 } 2970 } 2971 /* Return dirty HTML if DOMPurify cannot run */ 2972 if (!DOMPurify.isSupported) { 2973 return dirty; 2974 } 2975 /* Assign config vars */ 2976 if (!SET_CONFIG) { 2977 _parseConfig(cfg); 2978 } 2979 /* Clean up removed elements */ 2980 DOMPurify.removed = []; 2981 /* Check if dirty is correctly typed for IN_PLACE */ 2982 if (typeof dirty === 'string') { 2983 IN_PLACE = false; 2984 } 2985 if (IN_PLACE) { 2986 /* Do some early pre-sanitization to avoid unsafe root nodes */ 2987 if (dirty.nodeName) { 2988 const tagName = transformCaseFunc(dirty.nodeName); 2989 if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { 2990 throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place'); 2991 } 2992 } 2993 } else if (dirty instanceof Node) { 2994 /* If dirty is a DOM element, append to an empty document to avoid 2995 elements being stripped by the parser */ 2996 body = _initDocument('<!---->'); 2997 importedNode = body.ownerDocument.importNode(dirty, true); 2998 if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') { 2999 /* Node is already a body, use as is */ 3000 body = importedNode; 3001 } else if (importedNode.nodeName === 'HTML') { 3002 body = importedNode; 3003 } else { 3004 // eslint-disable-next-line unicorn/prefer-dom-node-append 3005 body.appendChild(importedNode); 3006 } 3007 } else { 3008 /* Exit directly if we have nothing to do */ 3009 if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && 3010 // eslint-disable-next-line unicorn/prefer-includes 3011 dirty.indexOf('<') === -1) { 3012 return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty; 3013 } 3014 /* Initialize the document to work on */ 3015 body = _initDocument(dirty); 3016 /* Check we have a DOM node from the data */ 3017 if (!body) { 3018 return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : ''; 3019 } 3020 } 3021 /* Remove first element node (ours) if FORCE_BODY is set */ 3022 if (body && FORCE_BODY) { 3023 _forceRemove(body.firstChild); 3024 } 3025 /* Get node iterator */ 3026 const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body); 3027 /* Now start iterating over the created document */ 3028 while (currentNode = nodeIterator.nextNode()) { 3029 /* Sanitize tags and elements */ 3030 _sanitizeElements(currentNode); 3031 /* Check attributes next */ 3032 _sanitizeAttributes(currentNode); 3033 /* Shadow DOM detected, sanitize it */ 3034 if (currentNode.content instanceof DocumentFragment) { 3035 _sanitizeShadowDOM(currentNode.content); 3036 } 3037 } 3038 /* If we sanitized `dirty` in-place, return it. */ 3039 if (IN_PLACE) { 3040 return dirty; 3041 } 3042 /* Return sanitized string or DOM */ 3043 if (RETURN_DOM) { 3044 if (RETURN_DOM_FRAGMENT) { 3045 returnNode = createDocumentFragment.call(body.ownerDocument); 3046 while (body.firstChild) {
vendor: 2,944 bytes, lines 3047-3119
3047 // eslint-disable-next-line unicorn/prefer-dom-node-append 3048 returnNode.appendChild(body.firstChild); 3049 } 3050 } else { 3051 returnNode = body; 3052 } 3053 if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) { 3054 /* 3055 AdoptNode() is not used because internal state is not reset 3056 (e.g. the past names map of a HTMLFormElement), this is safe 3057 in theory but we would rather not risk another attack vector. 3058 The state that is cloned by importNode() is explicitly defined 3059 by the specs. 3060 */ 3061 returnNode = importNode.call(originalDocument, returnNode, true); 3062 } 3063 return returnNode; 3064 } 3065 let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML; 3066 /* Serialize doctype if allowed */ 3067 if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) { 3068 serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML; 3069 } 3070 /* Sanitize final string template-safe */ 3071 if (SAFE_FOR_TEMPLATES) { 3072 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => { 3073 serializedHTML = stringReplace(serializedHTML, expr, ' '); 3074 }); 3075 } 3076 return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML; 3077 }; 3078 DOMPurify.setConfig = function () { 3079 let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 3080 _parseConfig(cfg); 3081 SET_CONFIG = true; 3082 }; 3083 DOMPurify.clearConfig = function () { 3084 CONFIG = null; 3085 SET_CONFIG = false; 3086 }; 3087 DOMPurify.isValidAttribute = function (tag, attr, value) { 3088 /* Initialize shared config vars if necessary. */ 3089 if (!CONFIG) { 3090 _parseConfig({}); 3091 } 3092 const lcTag = transformCaseFunc(tag); 3093 const lcName = transformCaseFunc(attr); 3094 return _isValidAttribute(lcTag, lcName, value); 3095 }; 3096 DOMPurify.addHook = function (entryPoint, hookFunction) { 3097 if (typeof hookFunction !== 'function') { 3098 return; 3099 } 3100 arrayPush(hooks[entryPoint], hookFunction); 3101 }; 3102 DOMPurify.removeHook = function (entryPoint, hookFunction) { 3103 if (hookFunction !== undefined) { 3104 const index = arrayLastIndexOf(hooks[entryPoint], hookFunction); 3105 return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0]; 3106 } 3107 return arrayPop(hooks[entryPoint]); 3108 }; 3109 DOMPurify.removeHooks = function (entryPoint) { 3110 hooks[entryPoint] = []; 3111 }; 3112 DOMPurify.removeAllHooks = function () { 3113 hooks = _createHooksMap(); 3114 }; 3115 return DOMPurify; 3116 } 3117 var purify = createDOMPurify(); 3118 3119 purify.addHook("uponSanitizeAttribute", function (node, data) {
vendor: 130,367 bytes, lines 3119-6860
3119 3120 const allowedAttributePattern = /^data-trix-/; 3121 if (allowedAttributePattern.test(data.attrName)) { 3122 data.forceKeepAttr = true; 3123 } 3124 }); 3125 const DEFAULT_ALLOWED_ATTRIBUTES = "style href src width height language class".split(" "); 3126 const DEFAULT_FORBIDDEN_PROTOCOLS = "javascript:".split(" "); 3127 const DEFAULT_FORBIDDEN_ELEMENTS = "script iframe form noscript".split(" "); 3128 class HTMLSanitizer extends BasicObject { 3129 static setHTML(element, html, options) { 3130 const sanitizedElement = new this(html, options).sanitize(); 3131 const sanitizedHtml = sanitizedElement.getHTML ? sanitizedElement.getHTML() : sanitizedElement.outerHTML; 3132 element.innerHTML = sanitizedHtml; 3133 } 3134 static sanitize(html, options) { 3135 const sanitizer = new this(html, options); 3136 sanitizer.sanitize(); 3137 return sanitizer; 3138 } 3139 constructor(html) { 3140 let { 3141 allowedAttributes, 3142 forbiddenProtocols, 3143 forbiddenElements, 3144 purifyOptions 3145 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 3146 super(...arguments); 3147 this.allowedAttributes = allowedAttributes || DEFAULT_ALLOWED_ATTRIBUTES; 3148 this.forbiddenProtocols = forbiddenProtocols || DEFAULT_FORBIDDEN_PROTOCOLS; 3149 this.forbiddenElements = forbiddenElements || DEFAULT_FORBIDDEN_ELEMENTS; 3150 this.purifyOptions = purifyOptions || {}; 3151 this.body = createBodyElementForHTML(html); 3152 } 3153 sanitize() { 3154 this.sanitizeElements(); 3155 this.normalizeListElementNesting(); 3156 const purifyConfig = Object.assign({}, dompurify, this.purifyOptions); 3157 purify.setConfig(purifyConfig); 3158 this.body = purify.sanitize(this.body); 3159 return this.body; 3160 } 3161 getHTML() { 3162 return this.body.innerHTML; 3163 } 3164 getBody() { 3165 return this.body; 3166 } 3167 3168 // Private 3169 3170 sanitizeElements() { 3171 const walker = walkTree(this.body); 3172 const nodesToRemove = []; 3173 while (walker.nextNode()) { 3174 const node = walker.currentNode; 3175 switch (node.nodeType) { 3176 case Node.ELEMENT_NODE: 3177 if (this.elementIsRemovable(node)) { 3178 nodesToRemove.push(node); 3179 } else { 3180 this.sanitizeElement(node); 3181 } 3182 break; 3183 case Node.COMMENT_NODE: 3184 nodesToRemove.push(node); 3185 break; 3186 } 3187 } 3188 nodesToRemove.forEach(node => removeNode(node)); 3189 return this.body; 3190 } 3191 sanitizeElement(element) { 3192 if (element.hasAttribute("href")) { 3193 if (this.forbiddenProtocols.includes(element.protocol)) { 3194 element.removeAttribute("href"); 3195 } 3196 } 3197 Array.from(element.attributes).forEach(_ref => { 3198 let { 3199 name 3200 } = _ref; 3201 if (!this.allowedAttributes.includes(name) && name.indexOf("data-trix") !== 0) { 3202 element.removeAttribute(name); 3203 } 3204 }); 3205 return element; 3206 } 3207 normalizeListElementNesting() { 3208 Array.from(this.body.querySelectorAll("ul,ol")).forEach(listElement => { 3209 const previousElement = listElement.previousElementSibling; 3210 if (previousElement) { 3211 if (tagName(previousElement) === "li") { 3212 previousElement.appendChild(listElement); 3213 } 3214 } 3215 }); 3216 return this.body; 3217 } 3218 elementIsRemovable(element) { 3219 if ((element === null || element === void 0 ? void 0 : element.nodeType) !== Node.ELEMENT_NODE) return; 3220 return this.elementIsForbidden(element) || this.elementIsntSerializable(element); 3221 } 3222 elementIsForbidden(element) { 3223 return this.forbiddenElements.includes(tagName(element)); 3224 } 3225 elementIsntSerializable(element) { 3226 return element.getAttribute("data-trix-serialize") === "false" && !nodeIsAttachmentElement(element); 3227 } 3228 } 3229 const createBodyElementForHTML = function () { 3230 let html = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; 3231 // Remove everything after </html> 3232 html = html.replace(/<\/html[^>]*>[^]*$/i, "</html>"); 3233 const doc = document.implementation.createHTMLDocument(""); 3234 doc.documentElement.innerHTML = html; 3235 Array.from(doc.head.querySelectorAll("style")).forEach(element => { 3236 doc.body.appendChild(element); 3237 }); 3238 return doc.body; 3239 }; 3240 3241 const { 3242 css: css$2 3243 } = config; 3244 class AttachmentView extends ObjectView { 3245 constructor() { 3246 super(...arguments); 3247 this.attachment = this.object; 3248 this.attachment.uploadProgressDelegate = this; 3249 this.attachmentPiece = this.options.piece; 3250 } 3251 createContentNodes() { 3252 return []; 3253 } 3254 createNodes() { 3255 let innerElement; 3256 const figure = innerElement = makeElement({ 3257 tagName: "figure", 3258 className: this.getClassName(), 3259 data: this.getData(), 3260 editable: false 3261 }); 3262 const href = this.getHref(); 3263 if (href) { 3264 innerElement = makeElement({ 3265 tagName: "a", 3266 editable: false, 3267 attributes: { 3268 href, 3269 tabindex: -1 3270 } 3271 }); 3272 figure.appendChild(innerElement); 3273 } 3274 if (this.attachment.hasContent()) { 3275 HTMLSanitizer.setHTML(innerElement, this.attachment.getContent()); 3276 } else { 3277 this.createContentNodes().forEach(node => { 3278 innerElement.appendChild(node); 3279 }); 3280 } 3281 innerElement.appendChild(this.createCaptionElement()); 3282 if (this.attachment.isPending()) { 3283 this.progressElement = makeElement({ 3284 tagName: "progress", 3285 attributes: { 3286 class: css$2.attachmentProgress, 3287 value: this.attachment.getUploadProgress(), 3288 max: 100 3289 }, 3290 data: { 3291 trixMutable: true, 3292 trixStoreKey: ["progressElement", this.attachment.id].join("/") 3293 } 3294 }); 3295 figure.appendChild(this.progressElement); 3296 } 3297 return [createCursorTarget("left"), figure, createCursorTarget("right")]; 3298 } 3299 createCaptionElement() { 3300 const figcaption = makeElement({ 3301 tagName: "figcaption", 3302 className: css$2.attachmentCaption 3303 }); 3304 const caption = this.attachmentPiece.getCaption(); 3305 if (caption) { 3306 figcaption.classList.add("".concat(css$2.attachmentCaption, "--edited")); 3307 figcaption.textContent = caption; 3308 } else { 3309 let name, size; 3310 const captionConfig = this.getCaptionConfig(); 3311 if (captionConfig.name) { 3312 name = this.attachment.getFilename(); 3313 } 3314 if (captionConfig.size) { 3315 size = this.attachment.getFormattedFilesize(); 3316 } 3317 if (name) { 3318 const nameElement = makeElement({ 3319 tagName: "span", 3320 className: css$2.attachmentName, 3321 textContent: name 3322 }); 3323 figcaption.appendChild(nameElement); 3324 } 3325 if (size) { 3326 if (name) { 3327 figcaption.appendChild(document.createTextNode(" ")); 3328 } 3329 const sizeElement = makeElement({ 3330 tagName: "span", 3331 className: css$2.attachmentSize, 3332 textContent: size 3333 }); 3334 figcaption.appendChild(sizeElement); 3335 } 3336 } 3337 return figcaption; 3338 } 3339 getClassName() { 3340 const names = [css$2.attachment, "".concat(css$2.attachment, "--").concat(this.attachment.getType())]; 3341 const extension = this.attachment.getExtension(); 3342 if (extension) { 3343 names.push("".concat(css$2.attachment, "--").concat(extension)); 3344 } 3345 return names.join(" "); 3346 } 3347 getData() { 3348 const data = { 3349 trixAttachment: JSON.stringify(this.attachment), 3350 trixContentType: this.attachment.getContentType(), 3351 trixId: this.attachment.id 3352 }; 3353 const { 3354 attributes 3355 } = this.attachmentPiece; 3356 if (!attributes.isEmpty()) { 3357 data.trixAttributes = JSON.stringify(attributes); 3358 } 3359 if (this.attachment.isPending()) { 3360 data.trixSerialize = false; 3361 } 3362 return data; 3363 } 3364 getHref() { 3365 if (!htmlContainsTagName(this.attachment.getContent(), "a")) { 3366 const href = this.attachment.getHref(); 3367 if (href && purify.isValidAttribute("a", "href", href)) { 3368 return href; 3369 } 3370 } 3371 } 3372 getCaptionConfig() { 3373 var _config$attachments$t; 3374 const type = this.attachment.getType(); 3375 const captionConfig = copyObject((_config$attachments$t = attachments[type]) === null || _config$attachments$t === void 0 ? void 0 : _config$attachments$t.caption); 3376 if (type === "file") { 3377 captionConfig.name = true; 3378 } 3379 return captionConfig; 3380 } 3381 findProgressElement() { 3382 var _this$findElement; 3383 return (_this$findElement = this.findElement()) === null || _this$findElement === void 0 ? void 0 : _this$findElement.querySelector("progress"); 3384 } 3385 3386 // Attachment delegate 3387 3388 attachmentDidChangeUploadProgress() { 3389 const value = this.attachment.getUploadProgress(); 3390 const progressElement = this.findProgressElement(); 3391 if (progressElement) { 3392 progressElement.value = value; 3393 } 3394 } 3395 } 3396 const createCursorTarget = name => makeElement({ 3397 tagName: "span", 3398 textContent: ZERO_WIDTH_SPACE, 3399 data: { 3400 trixCursorTarget: name, 3401 trixSerialize: false 3402 } 3403 }); 3404 const htmlContainsTagName = function (html, tagName) { 3405 const div = makeElement("div"); 3406 HTMLSanitizer.setHTML(div, html || ""); 3407 return div.querySelector(tagName); 3408 }; 3409 3410 class PreviewableAttachmentView extends AttachmentView { 3411 constructor() { 3412 super(...arguments); 3413 this.attachment.previewDelegate = this; 3414 } 3415 createContentNodes() { 3416 this.image = makeElement({ 3417 tagName: "img", 3418 attributes: { 3419 src: "" 3420 }, 3421 data: { 3422 trixMutable: true 3423 } 3424 }); 3425 this.refresh(this.image); 3426 return [this.image]; 3427 } 3428 createCaptionElement() { 3429 const figcaption = super.createCaptionElement(...arguments); 3430 if (!figcaption.textContent) { 3431 figcaption.setAttribute("data-trix-placeholder", lang$1.captionPlaceholder); 3432 } 3433 return figcaption; 3434 } 3435 refresh(image) { 3436 if (!image) { 3437 var _this$findElement; 3438 image = (_this$findElement = this.findElement()) === null || _this$findElement === void 0 ? void 0 : _this$findElement.querySelector("img"); 3439 } 3440 if (image) { 3441 return this.updateAttributesForImage(image); 3442 } 3443 } 3444 updateAttributesForImage(image) { 3445 const url = this.attachment.getURL(); 3446 const previewURL = this.attachment.getPreviewURL(); 3447 image.src = previewURL || url; 3448 if (previewURL === url) { 3449 image.removeAttribute("data-trix-serialized-attributes"); 3450 } else { 3451 const serializedAttributes = JSON.stringify({ 3452 src: url 3453 }); 3454 image.setAttribute("data-trix-serialized-attributes", serializedAttributes); 3455 } 3456 const width = this.attachment.getWidth(); 3457 const height = this.attachment.getHeight(); 3458 const alt = this.attachment.getAttribute("alt"); 3459 if (width != null) { 3460 image.width = width; 3461 } 3462 if (height != null) { 3463 image.height = height; 3464 } 3465 if (alt != null) { 3466 image.alt = alt; 3467 } 3468 const storeKey = ["imageElement", this.attachment.id, image.src, image.width, image.height].join("/"); 3469 image.dataset.trixStoreKey = storeKey; 3470 } 3471 3472 // Attachment delegate 3473 3474 attachmentDidChangeAttributes() { 3475 this.refresh(this.image); 3476 return this.refresh(); 3477 } 3478 } 3479 3480 /* eslint-disable 3481 no-useless-escape, 3482 no-var, 3483 */ 3484 class PieceView extends ObjectView { 3485 constructor() { 3486 super(...arguments); 3487 this.piece = this.object; 3488 this.attributes = this.piece.getAttributes(); 3489 this.textConfig = this.options.textConfig; 3490 this.context = this.options.context; 3491 if (this.piece.attachment) { 3492 this.attachment = this.piece.attachment; 3493 } else { 3494 this.string = this.piece.toString(); 3495 } 3496 } 3497 createNodes() { 3498 let nodes = this.attachment ? this.createAttachmentNodes() : this.createStringNodes(); 3499 const element = this.createElement(); 3500 if (element) { 3501 const innerElement = findInnerElement(element); 3502 Array.from(nodes).forEach(node => { 3503 innerElement.appendChild(node); 3504 }); 3505 nodes = [element]; 3506 } 3507 return nodes; 3508 } 3509 createAttachmentNodes() { 3510 const constructor = this.attachment.isPreviewable() ? PreviewableAttachmentView : AttachmentView; 3511 const view = this.createChildView(constructor, this.piece.attachment, { 3512 piece: this.piece 3513 }); 3514 return view.getNodes(); 3515 } 3516 createStringNodes() { 3517 var _this$textConfig; 3518 if ((_this$textConfig = this.textConfig) !== null && _this$textConfig !== void 0 && _this$textConfig.plaintext) { 3519 return [document.createTextNode(this.string)]; 3520 } else { 3521 const nodes = []; 3522 const iterable = this.string.split("\n"); 3523 for (let index = 0; index < iterable.length; index++) { 3524 const substring = iterable[index]; 3525 if (index > 0) { 3526 const element = makeElement("br"); 3527 nodes.push(element); 3528 } 3529 if (substring.length) { 3530 const node = document.createTextNode(this.preserveSpaces(substring)); 3531 nodes.push(node); 3532 } 3533 } 3534 return nodes; 3535 } 3536 } 3537 createElement() { 3538 let element, key, value; 3539 const styles = {}; 3540 for (key in this.attributes) { 3541 value = this.attributes[key]; 3542 const config = getTextConfig(key); 3543 if (config) { 3544 if (config.tagName) { 3545 var innerElement; 3546 const pendingElement = makeElement(config.tagName); 3547 if (innerElement) { 3548 innerElement.appendChild(pendingElement); 3549 innerElement = pendingElement; 3550 } else { 3551 element = innerElement = pendingElement; 3552 } 3553 } 3554 if (config.styleProperty) { 3555 styles[config.styleProperty] = value; 3556 } 3557 if (config.style) { 3558 for (key in config.style) { 3559 value = config.style[key]; 3560 styles[key] = value; 3561 } 3562 } 3563 } 3564 } 3565 if (Object.keys(styles).length) { 3566 if (!element) { 3567 element = makeElement("span"); 3568 } 3569 for (key in styles) { 3570 value = styles[key]; 3571 element.style[key] = value; 3572 } 3573 } 3574 return element; 3575 } 3576 createContainerElement() { 3577 for (const key in this.attributes) { 3578 const value = this.attributes[key]; 3579 const config = getTextConfig(key); 3580 if (config) { 3581 if (config.groupTagName) { 3582 const attributes = {}; 3583 attributes[key] = value; 3584 return makeElement(config.groupTagName, attributes); 3585 } 3586 } 3587 } 3588 } 3589 preserveSpaces(string) { 3590 if (this.context.isLast) { 3591 string = string.replace(/\ $/, NON_BREAKING_SPACE); 3592 } 3593 string = string.replace(/(\S)\ {3}(\S)/g, "$1 ".concat(NON_BREAKING_SPACE, " $2")).replace(/\ {2}/g, "".concat(NON_BREAKING_SPACE, " ")).replace(/\ {2}/g, " ".concat(NON_BREAKING_SPACE)); 3594 if (this.context.isFirst || this.context.followsWhitespace) { 3595 string = string.replace(/^\ /, NON_BREAKING_SPACE); 3596 } 3597 return string; 3598 } 3599 } 3600 3601 /* eslint-disable 3602 no-var, 3603 */ 3604 class TextView extends ObjectView { 3605 constructor() { 3606 super(...arguments); 3607 this.text = this.object; 3608 this.textConfig = this.options.textConfig; 3609 } 3610 createNodes() { 3611 const nodes = []; 3612 const pieces = ObjectGroup.groupObjects(this.getPieces()); 3613 const lastIndex = pieces.length - 1; 3614 for (let index = 0; index < pieces.length; index++) { 3615 const piece = pieces[index]; 3616 const context = {}; 3617 if (index === 0) { 3618 context.isFirst = true; 3619 } 3620 if (index === lastIndex) { 3621 context.isLast = true; 3622 } 3623 if (endsWithWhitespace(previousPiece)) { 3624 context.followsWhitespace = true; 3625 } 3626 const view = this.findOrCreateCachedChildView(PieceView, piece, { 3627 textConfig: this.textConfig, 3628 context 3629 }); 3630 nodes.push(...Array.from(view.getNodes() || [])); 3631 var previousPiece = piece; 3632 } 3633 return nodes; 3634 } 3635 getPieces() { 3636 return Array.from(this.text.getPieces()).filter(piece => !piece.hasAttribute("blockBreak")); 3637 } 3638 } 3639 const endsWithWhitespace = piece => /\s$/.test(piece === null || piece === void 0 ? void 0 : piece.toString()); 3640 3641 const { 3642 css: css$1 3643 } = config; 3644 class BlockView extends ObjectView { 3645 constructor() { 3646 super(...arguments); 3647 this.block = this.object; 3648 this.attributes = this.block.getAttributes(); 3649 } 3650 createNodes() { 3651 const comment = document.createComment("block"); 3652 const nodes = [comment]; 3653 if (this.block.isEmpty()) { 3654 nodes.push(makeElement("br")); 3655 } else { 3656 var _getBlockConfig; 3657 const textConfig = (_getBlockConfig = getBlockConfig(this.block.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.text; 3658 const textView = this.findOrCreateCachedChildView(TextView, this.block.text, { 3659 textConfig 3660 }); 3661 nodes.push(...Array.from(textView.getNodes() || [])); 3662 if (this.shouldAddExtraNewlineElement()) { 3663 nodes.push(makeElement("br")); 3664 } 3665 } 3666 if (this.attributes.length) { 3667 return nodes; 3668 } else { 3669 let attributes$1; 3670 const { 3671 tagName 3672 } = attributes.default; 3673 if (this.block.isRTL()) { 3674 attributes$1 = { 3675 dir: "rtl" 3676 }; 3677 } 3678 const element = makeElement({ 3679 tagName, 3680 attributes: attributes$1 3681 }); 3682 nodes.forEach(node => element.appendChild(node)); 3683 return [element]; 3684 } 3685 } 3686 createContainerElement(depth) { 3687 const attributes = {}; 3688 let className; 3689 const attributeName = this.attributes[depth]; 3690 const { 3691 tagName, 3692 htmlAttributes = [] 3693 } = getBlockConfig(attributeName); 3694 if (depth === 0 && this.block.isRTL()) { 3695 Object.assign(attributes, { 3696 dir: "rtl" 3697 }); 3698 } 3699 if (attributeName === "attachmentGallery") { 3700 const size = this.block.getBlockBreakPosition(); 3701 className = "".concat(css$1.attachmentGallery, " ").concat(css$1.attachmentGallery, "--").concat(size); 3702 } 3703 Object.entries(this.block.htmlAttributes).forEach(_ref => { 3704 let [name, value] = _ref; 3705 if (htmlAttributes.includes(name)) { 3706 attributes[name] = value; 3707 } 3708 }); 3709 return makeElement({ 3710 tagName, 3711 className, 3712 attributes 3713 }); 3714 } 3715 3716 // A single <br> at the end of a block element has no visual representation 3717 // so add an extra one. 3718 shouldAddExtraNewlineElement() { 3719 return /\n\n$/.test(this.block.toString()); 3720 } 3721 } 3722 3723 class DocumentView extends ObjectView { 3724 static render(document) { 3725 const element = makeElement("div"); 3726 const view = new this(document, { 3727 element 3728 }); 3729 view.render(); 3730 view.sync(); 3731 return element; 3732 } 3733 constructor() { 3734 super(...arguments); 3735 this.element = this.options.element; 3736 this.elementStore = new ElementStore(); 3737 this.setDocument(this.object); 3738 } 3739 setDocument(document) { 3740 if (!document.isEqualTo(this.document)) { 3741 this.document = this.object = document; 3742 } 3743 } 3744 render() { 3745 this.childViews = []; 3746 this.shadowElement = makeElement("div"); 3747 if (!this.document.isEmpty()) { 3748 const objects = ObjectGroup.groupObjects(this.document.getBlocks(), { 3749 asTree: true 3750 }); 3751 Array.from(objects).forEach(object => { 3752 const view = this.findOrCreateCachedChildView(BlockView, object); 3753 Array.from(view.getNodes()).map(node => this.shadowElement.appendChild(node)); 3754 }); 3755 } 3756 } 3757 isSynced() { 3758 return elementsHaveEqualHTML(this.shadowElement, this.element); 3759 } 3760 sync() { 3761 const render = (element, documentFragment) => { 3762 while (element.lastChild) { 3763 element.removeChild(element.lastChild); 3764 } 3765 element.appendChild(documentFragment); 3766 }; 3767 const event = createEvent("trix-before-render", { 3768 cancelable: false, 3769 attributes: { 3770 render 3771 } 3772 }); 3773 this.element.dispatchEvent(event); 3774 const fragment = this.createDocumentFragmentForSync(); 3775 event.render(this.element, fragment); 3776 return this.didSync(); 3777 } 3778 3779 // Private 3780 3781 didSync() { 3782 this.elementStore.reset(findStoredElements(this.element)); 3783 return defer(() => this.garbageCollectCachedViews()); 3784 } 3785 createDocumentFragmentForSync() { 3786 const fragment = document.createDocumentFragment(); 3787 Array.from(this.shadowElement.childNodes).forEach(node => { 3788 fragment.appendChild(node.cloneNode(true)); 3789 }); 3790 Array.from(findStoredElements(fragment)).forEach(element => { 3791 const storedElement = this.elementStore.remove(element); 3792 if (storedElement) { 3793 element.parentNode.replaceChild(storedElement, element); 3794 } 3795 }); 3796 return fragment; 3797 } 3798 } 3799 const findStoredElements = element => element.querySelectorAll("[data-trix-store-key]"); 3800 const elementsHaveEqualHTML = (element, otherElement) => ignoreSpaces(element.innerHTML) === ignoreSpaces(otherElement.innerHTML); 3801 const ignoreSpaces = html => html.replace(/ /g, " "); 3802 3803 function _AsyncGenerator(e) { 3804 var r, t; 3805 function resume(r, t) { 3806 try { 3807 var n = e[r](t), 3808 o = n.value, 3809 u = o instanceof _OverloadYield; 3810 Promise.resolve(u ? o.v : o).then(function (t) { 3811 if (u) { 3812 var i = "return" === r ? "return" : "next"; 3813 if (!o.k || t.done) return resume(i, t); 3814 t = e[i](t).value; 3815 } 3816 settle(n.done ? "return" : "normal", t); 3817 }, function (e) { 3818 resume("throw", e); 3819 }); 3820 } catch (e) { 3821 settle("throw", e); 3822 } 3823 } 3824 function settle(e, n) { 3825 switch (e) { 3826 case "return": 3827 r.resolve({ 3828 value: n, 3829 done: !0 3830 }); 3831 break; 3832 case "throw": 3833 r.reject(n); 3834 break; 3835 default: 3836 r.resolve({ 3837 value: n, 3838 done: !1 3839 }); 3840 } 3841 (r = r.next) ? resume(r.key, r.arg) : t = null; 3842 } 3843 this._invoke = function (e, n) { 3844 return new Promise(function (o, u) { 3845 var i = { 3846 key: e, 3847 arg: n, 3848 resolve: o, 3849 reject: u, 3850 next: null 3851 }; 3852 t ? t = t.next = i : (r = t = i, resume(e, n)); 3853 }); 3854 }, "function" != typeof e.return && (this.return = void 0); 3855 } 3856 _AsyncGenerator.prototype["function" == typeof Symbol && Symbol.asyncIterator || "@@asyncIterator"] = function () { 3857 return this; 3858 }, _AsyncGenerator.prototype.next = function (e) { 3859 return this._invoke("next", e); 3860 }, _AsyncGenerator.prototype.throw = function (e) { 3861 return this._invoke("throw", e); 3862 }, _AsyncGenerator.prototype.return = function (e) { 3863 return this._invoke("return", e); 3864 }; 3865 function _OverloadYield(t, e) { 3866 this.v = t, this.k = e; 3867 } 3868 function old_createMetadataMethodsForProperty(e, t, a, r) { 3869 return { 3870 getMetadata: function (o) { 3871 old_assertNotFinished(r, "getMetadata"), old_assertMetadataKey(o); 3872 var i = e[o]; 3873 if (void 0 !== i) if (1 === t) { 3874 var n = i.public; 3875 if (void 0 !== n) return n[a]; 3876 } else if (2 === t) { 3877 var l = i.private; 3878 if (void 0 !== l) return l.get(a); 3879 } else if (Object.hasOwnProperty.call(i, "constructor")) return i.constructor; 3880 }, 3881 setMetadata: function (o, i) { 3882 old_assertNotFinished(r, "setMetadata"), old_assertMetadataKey(o); 3883 var n = e[o]; 3884 if (void 0 === n && (n = e[o] = {}), 1 === t) { 3885 var l = n.public; 3886 void 0 === l && (l = n.public = {}), l[a] = i; 3887 } else if (2 === t) { 3888 var s = n.priv; 3889 void 0 === s && (s = n.private = new Map()), s.set(a, i); 3890 } else n.constructor = i; 3891 } 3892 }; 3893 } 3894 function old_convertMetadataMapToFinal(e, t) { 3895 var a = e[Symbol.metadata || Symbol.for("Symbol.metadata")], 3896 r = Object.getOwnPropertySymbols(t); 3897 if (0 !== r.length) { 3898 for (var o = 0; o < r.length; o++) { 3899 var i = r[o], 3900 n = t[i], 3901 l = a ? a[i] : null, 3902 s = n.public, 3903 c = l ? l.public : null; 3904 s && c && Object.setPrototypeOf(s, c); 3905 var d = n.private; 3906 if (d) { 3907 var u = Array.from(d.values()), 3908 f = l ? l.private : null; 3909 f && (u = u.concat(f)), n.private = u; 3910 } 3911 l && Object.setPrototypeOf(n, l); 3912 } 3913 a && Object.setPrototypeOf(t, a), e[Symbol.metadata || Symbol.for("Symbol.metadata")] = t; 3914 } 3915 } 3916 function old_createAddInitializerMethod(e, t) { 3917 return function (a) { 3918 old_assertNotFinished(t, "addInitializer"), old_assertCallable(a, "An initializer"), e.push(a); 3919 }; 3920 } 3921 function old_memberDec(e, t, a, r, o, i, n, l, s) { 3922 var c; 3923 switch (i) { 3924 case 1: 3925 c = "accessor"; 3926 break; 3927 case 2: 3928 c = "method"; 3929 break; 3930 case 3: 3931 c = "getter"; 3932 break; 3933 case 4: 3934 c = "setter"; 3935 break; 3936 default: 3937 c = "field"; 3938 } 3939 var d, 3940 u, 3941 f = { 3942 kind: c, 3943 name: l ? "#" + t : _toPropertyKey(t), 3944 isStatic: n, 3945 isPrivate: l 3946 }, 3947 p = { 3948 v: !1 3949 }; 3950 if (0 !== i && (f.addInitializer = old_createAddInitializerMethod(o, p)), l) { 3951 d = 2, u = Symbol(t); 3952 var v = {}; 3953 0 === i ? (v.get = a.get, v.set = a.set) : 2 === i ? v.get = function () { 3954 return a.value; 3955 } : (1 !== i && 3 !== i || (v.get = function () { 3956 return a.get.call(this); 3957 }), 1 !== i && 4 !== i || (v.set = function (e) { 3958 a.set.call(this, e); 3959 })), f.access = v; 3960 } else d = 1, u = t; 3961 try { 3962 return e(s, Object.assign(f, old_createMetadataMethodsForProperty(r, d, u, p))); 3963 } finally { 3964 p.v = !0; 3965 } 3966 } 3967 function old_assertNotFinished(e, t) { 3968 if (e.v) throw new Error("attempted to call " + t + " after decoration was finished"); 3969 } 3970 function old_assertMetadataKey(e) { 3971 if ("symbol" != typeof e) throw new TypeError("Metadata keys must be symbols, received: " + e); 3972 } 3973 function old_assertCallable(e, t) { 3974 if ("function" != typeof e) throw new TypeError(t + " must be a function"); 3975 } 3976 function old_assertValidReturnValue(e, t) { 3977 var a = typeof t; 3978 if (1 === e) { 3979 if ("object" !== a || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); 3980 void 0 !== t.get && old_assertCallable(t.get, "accessor.get"), void 0 !== t.set && old_assertCallable(t.set, "accessor.set"), void 0 !== t.init && old_assertCallable(t.init, "accessor.init"), void 0 !== t.initializer && old_assertCallable(t.initializer, "accessor.initializer"); 3981 } else if ("function" !== a) throw new TypeError((0 === e ? "field" : 10 === e ? "class" : "method") + " decorators must return a function or void 0"); 3982 } 3983 function old_getInit(e) { 3984 var t; 3985 return null == (t = e.init) && (t = e.initializer) && "undefined" != typeof console && console.warn(".initializer has been renamed to .init as of March 2022"), t; 3986 } 3987 function old_applyMemberDec(e, t, a, r, o, i, n, l, s) { 3988 var c, 3989 d, 3990 u, 3991 f, 3992 p, 3993 v, 3994 y, 3995 h = a[0]; 3996 if (n ? (0 === o || 1 === o ? (c = { 3997 get: a[3], 3998 set: a[4] 3999 }, u = "get") : 3 === o ? (c = { 4000 get: a[3] 4001 }, u = "get") : 4 === o ? (c = { 4002 set: a[3] 4003 }, u = "set") : c = { 4004 value: a[3] 4005 }, 0 !== o && (1 === o && _setFunctionName(a[4], "#" + r, "set"), _setFunctionName(a[3], "#" + r, u))) : 0 !== o && (c = Object.getOwnPropertyDescriptor(t, r)), 1 === o ? f = { 4006 get: c.get, 4007 set: c.set 4008 } : 2 === o ? f = c.value : 3 === o ? f = c.get : 4 === o && (f = c.set), "function" == typeof h) void 0 !== (p = old_memberDec(h, r, c, l, s, o, i, n, f)) && (old_assertValidReturnValue(o, p), 0 === o ? d = p : 1 === o ? (d = old_getInit(p), v = p.get || f.get, y = p.set || f.set, f = { 4009 get: v, 4010 set: y 4011 }) : f = p);else for (var m = h.length - 1; m >= 0; m--) { 4012 var b; 4013 void 0 !== (p = old_memberDec(h[m], r, c, l, s, o, i, n, f)) && (old_assertValidReturnValue(o, p), 0 === o ? b = p : 1 === o ? (b = old_getInit(p), v = p.get || f.get, y = p.set || f.set, f = { 4014 get: v, 4015 set: y 4016 }) : f = p, void 0 !== b && (void 0 === d ? d = b : "function" == typeof d ? d = [d, b] : d.push(b))); 4017 } 4018 if (0 === o || 1 === o) { 4019 if (void 0 === d) d = function (e, t) { 4020 return t; 4021 };else if ("function" != typeof d) { 4022 var g = d; 4023 d = function (e, t) { 4024 for (var a = t, r = 0; r < g.length; r++) a = g[r].call(e, a); 4025 return a; 4026 }; 4027 } else { 4028 var _ = d; 4029 d = function (e, t) { 4030 return _.call(e, t); 4031 }; 4032 } 4033 e.push(d); 4034 } 4035 0 !== o && (1 === o ? (c.get = f.get, c.set = f.set) : 2 === o ? c.value = f : 3 === o ? c.get = f : 4 === o && (c.set = f), n ? 1 === o ? (e.push(function (e, t) { 4036 return f.get.call(e, t); 4037 }), e.push(function (e, t) { 4038 return f.set.call(e, t); 4039 })) : 2 === o ? e.push(f) : e.push(function (e, t) { 4040 return f.call(e, t); 4041 }) : Object.defineProperty(t, r, c)); 4042 } 4043 function old_applyMemberDecs(e, t, a, r, o) { 4044 for (var i, n, l = new Map(), s = new Map(), c = 0; c < o.length; c++) { 4045 var d = o[c]; 4046 if (Array.isArray(d)) { 4047 var u, 4048 f, 4049 p, 4050 v = d[1], 4051 y = d[2], 4052 h = d.length > 3, 4053 m = v >= 5; 4054 if (m ? (u = t, f = r, 0 != (v -= 5) && (p = n = n || [])) : (u = t.prototype, f = a, 0 !== v && (p = i = i || [])), 0 !== v && !h) { 4055 var b = m ? s : l, 4056 g = b.get(y) || 0; 4057 if (!0 === g || 3 === g && 4 !== v || 4 === g && 3 !== v) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + y); 4058 !g && v > 2 ? b.set(y, v) : b.set(y, !0); 4059 } 4060 old_applyMemberDec(e, u, d, y, v, m, h, f, p); 4061 } 4062 } 4063 old_pushInitializers(e, i), old_pushInitializers(e, n); 4064 } 4065 function old_pushInitializers(e, t) { 4066 t && e.push(function (e) { 4067 for (var a = 0; a < t.length; a++) t[a].call(e); 4068 return e; 4069 }); 4070 } 4071 function old_applyClassDecs(e, t, a, r) { 4072 if (r.length > 0) { 4073 for (var o = [], i = t, n = t.name, l = r.length - 1; l >= 0; l--) { 4074 var s = { 4075 v: !1 4076 }; 4077 try { 4078 var c = Object.assign({ 4079 kind: "class", 4080 name: n, 4081 addInitializer: old_createAddInitializerMethod(o, s) 4082 }, old_createMetadataMethodsForProperty(a, 0, n, s)), 4083 d = r[l](i, c); 4084 } finally { 4085 s.v = !0; 4086 } 4087 void 0 !== d && (old_assertValidReturnValue(10, d), i = d); 4088 } 4089 e.push(i, function () { 4090 for (var e = 0; e < o.length; e++) o[e].call(i); 4091 }); 4092 } 4093 } 4094 function _applyDecs(e, t, a) { 4095 var r = [], 4096 o = {}, 4097 i = {}; 4098 return old_applyMemberDecs(r, e, i, o, t), old_convertMetadataMapToFinal(e.prototype, i), old_applyClassDecs(r, e, o, a), old_convertMetadataMapToFinal(e, o), r; 4099 } 4100 function applyDecs2203Factory() { 4101 function createAddInitializerMethod(e, t) { 4102 return function (r) { 4103 !function (e, t) { 4104 if (e.v) throw new Error("attempted to call addInitializer after decoration was finished"); 4105 }(t), assertCallable(r, "An initializer"), e.push(r); 4106 }; 4107 } 4108 function memberDec(e, t, r, a, n, i, s, o) { 4109 var c; 4110 switch (n) { 4111 case 1: 4112 c = "accessor"; 4113 break; 4114 case 2: 4115 c = "method"; 4116 break; 4117 case 3: 4118 c = "getter"; 4119 break; 4120 case 4: 4121 c = "setter"; 4122 break; 4123 default: 4124 c = "field"; 4125 } 4126 var l, 4127 u, 4128 f = { 4129 kind: c, 4130 name: s ? "#" + t : t, 4131 static: i, 4132 private: s 4133 }, 4134 p = { 4135 v: !1 4136 }; 4137 0 !== n && (f.addInitializer = createAddInitializerMethod(a, p)), 0 === n ? s ? (l = r.get, u = r.set) : (l = function () { 4138 return this[t]; 4139 }, u = function (e) { 4140 this[t] = e; 4141 }) : 2 === n ? l = function () { 4142 return r.value; 4143 } : (1 !== n && 3 !== n || (l = function () { 4144 return r.get.call(this); 4145 }), 1 !== n && 4 !== n || (u = function (e) { 4146 r.set.call(this, e); 4147 })), f.access = l && u ? { 4148 get: l, 4149 set: u 4150 } : l ? { 4151 get: l 4152 } : { 4153 set: u 4154 }; 4155 try { 4156 return e(o, f); 4157 } finally { 4158 p.v = !0; 4159 } 4160 } 4161 function assertCallable(e, t) { 4162 if ("function" != typeof e) throw new TypeError(t + " must be a function"); 4163 } 4164 function assertValidReturnValue(e, t) { 4165 var r = typeof t; 4166 if (1 === e) { 4167 if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); 4168 void 0 !== t.get && assertCallable(t.get, "accessor.get"), void 0 !== t.set && assertCallable(t.set, "accessor.set"), void 0 !== t.init && assertCallable(t.init, "accessor.init"); 4169 } else if ("function" !== r) throw new TypeError((0 === e ? "field" : 10 === e ? "class" : "method") + " decorators must return a function or void 0"); 4170 } 4171 function applyMemberDec(e, t, r, a, n, i, s, o) { 4172 var c, 4173 l, 4174 u, 4175 f, 4176 p, 4177 d, 4178 h = r[0]; 4179 if (s ? c = 0 === n || 1 === n ? { 4180 get: r[3], 4181 set: r[4] 4182 } : 3 === n ? { 4183 get: r[3] 4184 } : 4 === n ? { 4185 set: r[3] 4186 } : { 4187 value: r[3] 4188 } : 0 !== n && (c = Object.getOwnPropertyDescriptor(t, a)), 1 === n ? u = { 4189 get: c.get, 4190 set: c.set 4191 } : 2 === n ? u = c.value : 3 === n ? u = c.get : 4 === n && (u = c.set), "function" == typeof h) void 0 !== (f = memberDec(h, a, c, o, n, i, s, u)) && (assertValidReturnValue(n, f), 0 === n ? l = f : 1 === n ? (l = f.init, p = f.get || u.get, d = f.set || u.set, u = { 4192 get: p, 4193 set: d 4194 }) : u = f);else for (var v = h.length - 1; v >= 0; v--) { 4195 var g; 4196 void 0 !== (f = memberDec(h[v], a, c, o, n, i, s, u)) && (assertValidReturnValue(n, f), 0 === n ? g = f : 1 === n ? (g = f.init, p = f.get || u.get, d = f.set || u.set, u = { 4197 get: p, 4198 set: d 4199 }) : u = f, void 0 !== g && (void 0 === l ? l = g : "function" == typeof l ? l = [l, g] : l.push(g))); 4200 } 4201 if (0 === n || 1 === n) { 4202 if (void 0 === l) l = function (e, t) { 4203 return t; 4204 };else if ("function" != typeof l) { 4205 var y = l; 4206 l = function (e, t) { 4207 for (var r = t, a = 0; a < y.length; a++) r = y[a].call(e, r); 4208 return r; 4209 }; 4210 } else { 4211 var m = l; 4212 l = function (e, t) { 4213 return m.call(e, t); 4214 }; 4215 } 4216 e.push(l); 4217 } 4218 0 !== n && (1 === n ? (c.get = u.get, c.set = u.set) : 2 === n ? c.value = u : 3 === n ? c.get = u : 4 === n && (c.set = u), s ? 1 === n ? (e.push(function (e, t) { 4219 return u.get.call(e, t); 4220 }), e.push(function (e, t) { 4221 return u.set.call(e, t); 4222 })) : 2 === n ? e.push(u) : e.push(function (e, t) { 4223 return u.call(e, t); 4224 }) : Object.defineProperty(t, a, c)); 4225 } 4226 function pushInitializers(e, t) { 4227 t && e.push(function (e) { 4228 for (var r = 0; r < t.length; r++) t[r].call(e); 4229 return e; 4230 }); 4231 } 4232 return function (e, t, r) { 4233 var a = []; 4234 return function (e, t, r) { 4235 for (var a, n, i = new Map(), s = new Map(), o = 0; o < r.length; o++) { 4236 var c = r[o]; 4237 if (Array.isArray(c)) { 4238 var l, 4239 u, 4240 f = c[1], 4241 p = c[2], 4242 d = c.length > 3, 4243 h = f >= 5; 4244 if (h ? (l = t, 0 != (f -= 5) && (u = n = n || [])) : (l = t.prototype, 0 !== f && (u = a = a || [])), 0 !== f && !d) { 4245 var v = h ? s : i, 4246 g = v.get(p) || 0; 4247 if (!0 === g || 3 === g && 4 !== f || 4 === g && 3 !== f) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + p); 4248 !g && f > 2 ? v.set(p, f) : v.set(p, !0); 4249 } 4250 applyMemberDec(e, l, c, p, f, h, d, u); 4251 } 4252 } 4253 pushInitializers(e, a), pushInitializers(e, n); 4254 }(a, e, t), function (e, t, r) { 4255 if (r.length > 0) { 4256 for (var a = [], n = t, i = t.name, s = r.length - 1; s >= 0; s--) { 4257 var o = { 4258 v: !1 4259 }; 4260 try { 4261 var c = r[s](n, { 4262 kind: "class", 4263 name: i, 4264 addInitializer: createAddInitializerMethod(a, o) 4265 }); 4266 } finally { 4267 o.v = !0; 4268 } 4269 void 0 !== c && (assertValidReturnValue(10, c), n = c); 4270 } 4271 e.push(n, function () { 4272 for (var e = 0; e < a.length; e++) a[e].call(n); 4273 }); 4274 } 4275 }(a, e, r), a; 4276 }; 4277 } 4278 var applyDecs2203Impl; 4279 function _applyDecs2203(e, t, r) { 4280 return (applyDecs2203Impl = applyDecs2203Impl || applyDecs2203Factory())(e, t, r); 4281 } 4282 function applyDecs2203RFactory() { 4283 function createAddInitializerMethod(e, t) { 4284 return function (r) { 4285 !function (e, t) { 4286 if (e.v) throw new Error("attempted to call addInitializer after decoration was finished"); 4287 }(t), assertCallable(r, "An initializer"), e.push(r); 4288 }; 4289 } 4290 function memberDec(e, t, r, n, a, i, o, s) { 4291 var c; 4292 switch (a) { 4293 case 1: 4294 c = "accessor"; 4295 break; 4296 case 2: 4297 c = "method"; 4298 break; 4299 case 3: 4300 c = "getter"; 4301 break; 4302 case 4: 4303 c = "setter"; 4304 break; 4305 default: 4306 c = "field"; 4307 } 4308 var l, 4309 u, 4310 f = { 4311 kind: c, 4312 name: o ? "#" + t : _toPropertyKey(t), 4313 static: i, 4314 private: o 4315 }, 4316 p = { 4317 v: !1 4318 }; 4319 0 !== a && (f.addInitializer = createAddInitializerMethod(n, p)), 0 === a ? o ? (l = r.get, u = r.set) : (l = function () { 4320 return this[t]; 4321 }, u = function (e) { 4322 this[t] = e; 4323 }) : 2 === a ? l = function () { 4324 return r.value; 4325 } : (1 !== a && 3 !== a || (l = function () { 4326 return r.get.call(this); 4327 }), 1 !== a && 4 !== a || (u = function (e) { 4328 r.set.call(this, e); 4329 })), f.access = l && u ? { 4330 get: l, 4331 set: u 4332 } : l ? { 4333 get: l 4334 } : { 4335 set: u 4336 }; 4337 try { 4338 return e(s, f); 4339 } finally { 4340 p.v = !0; 4341 } 4342 } 4343 function assertCallable(e, t) { 4344 if ("function" != typeof e) throw new TypeError(t + " must be a function"); 4345 } 4346 function assertValidReturnValue(e, t) { 4347 var r = typeof t; 4348 if (1 === e) { 4349 if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); 4350 void 0 !== t.get && assertCallable(t.get, "accessor.get"), void 0 !== t.set && assertCallable(t.set, "accessor.set"), void 0 !== t.init && assertCallable(t.init, "accessor.init"); 4351 } else if ("function" !== r) throw new TypeError((0 === e ? "field" : 10 === e ? "class" : "method") + " decorators must return a function or void 0"); 4352 } 4353 function applyMemberDec(e, t, r, n, a, i, o, s) { 4354 var c, 4355 l, 4356 u, 4357 f, 4358 p, 4359 d, 4360 h, 4361 v = r[0]; 4362 if (o ? (0 === a || 1 === a ? (c = { 4363 get: r[3], 4364 set: r[4] 4365 }, u = "get") : 3 === a ? (c = { 4366 get: r[3] 4367 }, u = "get") : 4 === a ? (c = { 4368 set: r[3] 4369 }, u = "set") : c = { 4370 value: r[3] 4371 }, 0 !== a && (1 === a && _setFunctionName(r[4], "#" + n, "set"), _setFunctionName(r[3], "#" + n, u))) : 0 !== a && (c = Object.getOwnPropertyDescriptor(t, n)), 1 === a ? f = { 4372 get: c.get, 4373 set: c.set 4374 } : 2 === a ? f = c.value : 3 === a ? f = c.get : 4 === a && (f = c.set), "function" == typeof v) void 0 !== (p = memberDec(v, n, c, s, a, i, o, f)) && (assertValidReturnValue(a, p), 0 === a ? l = p : 1 === a ? (l = p.init, d = p.get || f.get, h = p.set || f.set, f = { 4375 get: d, 4376 set: h 4377 }) : f = p);else for (var g = v.length - 1; g >= 0; g--) { 4378 var y; 4379 void 0 !== (p = memberDec(v[g], n, c, s, a, i, o, f)) && (assertValidReturnValue(a, p), 0 === a ? y = p : 1 === a ? (y = p.init, d = p.get || f.get, h = p.set || f.set, f = { 4380 get: d, 4381 set: h 4382 }) : f = p, void 0 !== y && (void 0 === l ? l = y : "function" == typeof l ? l = [l, y] : l.push(y))); 4383 } 4384 if (0 === a || 1 === a) { 4385 if (void 0 === l) l = function (e, t) { 4386 return t; 4387 };else if ("function" != typeof l) { 4388 var m = l; 4389 l = function (e, t) { 4390 for (var r = t, n = 0; n < m.length; n++) r = m[n].call(e, r); 4391 return r; 4392 }; 4393 } else { 4394 var b = l; 4395 l = function (e, t) { 4396 return b.call(e, t); 4397 }; 4398 } 4399 e.push(l); 4400 } 4401 0 !== a && (1 === a ? (c.get = f.get, c.set = f.set) : 2 === a ? c.value = f : 3 === a ? c.get = f : 4 === a && (c.set = f), o ? 1 === a ? (e.push(function (e, t) { 4402 return f.get.call(e, t); 4403 }), e.push(function (e, t) { 4404 return f.set.call(e, t); 4405 })) : 2 === a ? e.push(f) : e.push(function (e, t) { 4406 return f.call(e, t); 4407 }) : Object.defineProperty(t, n, c)); 4408 } 4409 function applyMemberDecs(e, t) { 4410 for (var r, n, a = [], i = new Map(), o = new Map(), s = 0; s < t.length; s++) { 4411 var c = t[s]; 4412 if (Array.isArray(c)) { 4413 var l, 4414 u, 4415 f = c[1], 4416 p = c[2], 4417 d = c.length > 3, 4418 h = f >= 5; 4419 if (h ? (l = e, 0 != (f -= 5) && (u = n = n || [])) : (l = e.prototype, 0 !== f && (u = r = r || [])), 0 !== f && !d) { 4420 var v = h ? o : i, 4421 g = v.get(p) || 0; 4422 if (!0 === g || 3 === g && 4 !== f || 4 === g && 3 !== f) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + p); 4423 !g && f > 2 ? v.set(p, f) : v.set(p, !0); 4424 } 4425 applyMemberDec(a, l, c, p, f, h, d, u); 4426 } 4427 } 4428 return pushInitializers(a, r), pushInitializers(a, n), a; 4429 } 4430 function pushInitializers(e, t) { 4431 t && e.push(function (e) { 4432 for (var r = 0; r < t.length; r++) t[r].call(e); 4433 return e; 4434 }); 4435 } 4436 return function (e, t, r) { 4437 return { 4438 e: applyMemberDecs(e, t), 4439 get c() { 4440 return function (e, t) { 4441 if (t.length > 0) { 4442 for (var r = [], n = e, a = e.name, i = t.length - 1; i >= 0; i--) { 4443 var o = { 4444 v: !1 4445 }; 4446 try { 4447 var s = t[i](n, { 4448 kind: "class", 4449 name: a, 4450 addInitializer: createAddInitializerMethod(r, o) 4451 }); 4452 } finally { 4453 o.v = !0; 4454 } 4455 void 0 !== s && (assertValidReturnValue(10, s), n = s); 4456 } 4457 return [n, function () { 4458 for (var e = 0; e < r.length; e++) r[e].call(n); 4459 }]; 4460 } 4461 }(e, r); 4462 } 4463 }; 4464 }; 4465 } 4466 function _applyDecs2203R(e, t, r) { 4467 return (_applyDecs2203R = applyDecs2203RFactory())(e, t, r); 4468 } 4469 function applyDecs2301Factory() { 4470 function createAddInitializerMethod(e, t) { 4471 return function (r) { 4472 !function (e, t) { 4473 if (e.v) throw new Error("attempted to call addInitializer after decoration was finished"); 4474 }(t), assertCallable(r, "An initializer"), e.push(r); 4475 }; 4476 } 4477 function assertInstanceIfPrivate(e, t) { 4478 if (!e(t)) throw new TypeError("Attempted to access private element on non-instance"); 4479 } 4480 function memberDec(e, t, r, n, a, i, s, o, c) { 4481 var u; 4482 switch (a) { 4483 case 1: 4484 u = "accessor"; 4485 break; 4486 case 2: 4487 u = "method"; 4488 break; 4489 case 3: 4490 u = "getter"; 4491 break; 4492 case 4: 4493 u = "setter"; 4494 break; 4495 default: 4496 u = "field"; 4497 } 4498 var l, 4499 f, 4500 p = { 4501 kind: u, 4502 name: s ? "#" + t : _toPropertyKey(t), 4503 static: i, 4504 private: s 4505 }, 4506 d = { 4507 v: !1 4508 }; 4509 if (0 !== a && (p.addInitializer = createAddInitializerMethod(n, d)), s || 0 !== a && 2 !== a) { 4510 if (2 === a) l = function (e) { 4511 return assertInstanceIfPrivate(c, e), r.value; 4512 };else { 4513 var h = 0 === a || 1 === a; 4514 (h || 3 === a) && (l = s ? function (e) { 4515 return assertInstanceIfPrivate(c, e), r.get.call(e); 4516 } : function (e) { 4517 return r.get.call(e); 4518 }), (h || 4 === a) && (f = s ? function (e, t) { 4519 assertInstanceIfPrivate(c, e), r.set.call(e, t); 4520 } : function (e, t) { 4521 r.set.call(e, t); 4522 }); 4523 } 4524 } else l = function (e) { 4525 return e[t]; 4526 }, 0 === a && (f = function (e, r) { 4527 e[t] = r; 4528 }); 4529 var v = s ? c.bind() : function (e) { 4530 return t in e; 4531 }; 4532 p.access = l && f ? { 4533 get: l, 4534 set: f, 4535 has: v 4536 } : l ? { 4537 get: l, 4538 has: v 4539 } : { 4540 set: f, 4541 has: v 4542 }; 4543 try { 4544 return e(o, p); 4545 } finally { 4546 d.v = !0; 4547 } 4548 } 4549 function assertCallable(e, t) { 4550 if ("function" != typeof e) throw new TypeError(t + " must be a function"); 4551 } 4552 function assertValidReturnValue(e, t) { 4553 var r = typeof t; 4554 if (1 === e) { 4555 if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); 4556 void 0 !== t.get && assertCallable(t.get, "accessor.get"), void 0 !== t.set && assertCallable(t.set, "accessor.set"), void 0 !== t.init && assertCallable(t.init, "accessor.init"); 4557 } else if ("function" !== r) throw new TypeError((0 === e ? "field" : 10 === e ? "class" : "method") + " decorators must return a function or void 0"); 4558 } 4559 function curryThis2(e) { 4560 return function (t) { 4561 e(this, t); 4562 }; 4563 } 4564 function applyMemberDec(e, t, r, n, a, i, s, o, c) { 4565 var u, 4566 l, 4567 f, 4568 p, 4569 d, 4570 h, 4571 v, 4572 y, 4573 g = r[0]; 4574 if (s ? (0 === a || 1 === a ? (u = { 4575 get: (d = r[3], function () { 4576 return d(this); 4577 }), 4578 set: curryThis2(r[4]) 4579 }, f = "get") : 3 === a ? (u = { 4580 get: r[3] 4581 }, f = "get") : 4 === a ? (u = { 4582 set: r[3] 4583 }, f = "set") : u = { 4584 value: r[3] 4585 }, 0 !== a && (1 === a && _setFunctionName(u.set, "#" + n, "set"), _setFunctionName(u[f || "value"], "#" + n, f))) : 0 !== a && (u = Object.getOwnPropertyDescriptor(t, n)), 1 === a ? p = { 4586 get: u.get, 4587 set: u.set 4588 } : 2 === a ? p = u.value : 3 === a ? p = u.get : 4 === a && (p = u.set), "function" == typeof g) void 0 !== (h = memberDec(g, n, u, o, a, i, s, p, c)) && (assertValidReturnValue(a, h), 0 === a ? l = h : 1 === a ? (l = h.init, v = h.get || p.get, y = h.set || p.set, p = { 4589 get: v, 4590 set: y 4591 }) : p = h);else for (var m = g.length - 1; m >= 0; m--) { 4592 var b; 4593 void 0 !== (h = memberDec(g[m], n, u, o, a, i, s, p, c)) && (assertValidReturnValue(a, h), 0 === a ? b = h : 1 === a ? (b = h.init, v = h.get || p.get, y = h.set || p.set, p = { 4594 get: v, 4595 set: y 4596 }) : p = h, void 0 !== b && (void 0 === l ? l = b : "function" == typeof l ? l = [l, b] : l.push(b))); 4597 } 4598 if (0 === a || 1 === a) { 4599 if (void 0 === l) l = function (e, t) { 4600 return t; 4601 };else if ("function" != typeof l) { 4602 var I = l; 4603 l = function (e, t) { 4604 for (var r = t, n = 0; n < I.length; n++) r = I[n].call(e, r); 4605 return r; 4606 }; 4607 } else { 4608 var w = l; 4609 l = function (e, t) { 4610 return w.call(e, t); 4611 }; 4612 } 4613 e.push(l); 4614 } 4615 0 !== a && (1 === a ? (u.get = p.get, u.set = p.set) : 2 === a ? u.value = p : 3 === a ? u.get = p : 4 === a && (u.set = p), s ? 1 === a ? (e.push(function (e, t) { 4616 return p.get.call(e, t); 4617 }), e.push(function (e, t) { 4618 return p.set.call(e, t); 4619 })) : 2 === a ? e.push(p) : e.push(function (e, t) { 4620 return p.call(e, t); 4621 }) : Object.defineProperty(t, n, u)); 4622 } 4623 function applyMemberDecs(e, t, r) { 4624 for (var n, a, i, s = [], o = new Map(), c = new Map(), u = 0; u < t.length; u++) { 4625 var l = t[u]; 4626 if (Array.isArray(l)) { 4627 var f, 4628 p, 4629 d = l[1], 4630 h = l[2], 4631 v = l.length > 3, 4632 y = d >= 5, 4633 g = r; 4634 if (y ? (f = e, 0 != (d -= 5) && (p = a = a || []), v && !i && (i = function (t) { 4635 return _checkInRHS(t) === e; 4636 }), g = i) : (f = e.prototype, 0 !== d && (p = n = n || [])), 0 !== d && !v) { 4637 var m = y ? c : o, 4638 b = m.get(h) || 0; 4639 if (!0 === b || 3 === b && 4 !== d || 4 === b && 3 !== d) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + h); 4640 !b && d > 2 ? m.set(h, d) : m.set(h, !0); 4641 } 4642 applyMemberDec(s, f, l, h, d, y, v, p, g); 4643 } 4644 } 4645 return pushInitializers(s, n), pushInitializers(s, a), s; 4646 } 4647 function pushInitializers(e, t) { 4648 t && e.push(function (e) { 4649 for (var r = 0; r < t.length; r++) t[r].call(e); 4650 return e; 4651 }); 4652 } 4653 return function (e, t, r, n) { 4654 return { 4655 e: applyMemberDecs(e, t, n), 4656 get c() { 4657 return function (e, t) { 4658 if (t.length > 0) { 4659 for (var r = [], n = e, a = e.name, i = t.length - 1; i >= 0; i--) { 4660 var s = { 4661 v: !1 4662 }; 4663 try { 4664 var o = t[i](n, { 4665 kind: "class", 4666 name: a, 4667 addInitializer: createAddInitializerMethod(r, s) 4668 }); 4669 } finally { 4670 s.v = !0; 4671 } 4672 void 0 !== o && (assertValidReturnValue(10, o), n = o); 4673 } 4674 return [n, function () { 4675 for (var e = 0; e < r.length; e++) r[e].call(n); 4676 }]; 4677 } 4678 }(e, r); 4679 } 4680 }; 4681 }; 4682 } 4683 function _applyDecs2301(e, t, r, n) { 4684 return (_applyDecs2301 = applyDecs2301Factory())(e, t, r, n); 4685 } 4686 function _applyDecs2305(e, t, r, n, o, a) { 4687 function i(e, t, r) { 4688 return function (n, o) { 4689 return r && r(n), e[t].call(n, o); 4690 }; 4691 } 4692 function c(e, t) { 4693 for (var r = 0; r < e.length; r++) e[r].call(t); 4694 return t; 4695 } 4696 function s(e, t, r, n) { 4697 if ("function" != typeof e && (n || void 0 !== e)) throw new TypeError(t + " must " + (r || "be") + " a function" + (n ? "" : " or undefined")); 4698 return e; 4699 } 4700 function applyDec(e, t, r, n, o, a, c, u, l, f, p, d, h) { 4701 function m(e) { 4702 if (!h(e)) throw new TypeError("Attempted to access private element on non-instance"); 4703 } 4704 var y, 4705 v = t[0], 4706 g = t[3], 4707 b = !u; 4708 if (!b) { 4709 r || Array.isArray(v) || (v = [v]); 4710 var w = {}, 4711 S = [], 4712 A = 3 === o ? "get" : 4 === o || d ? "set" : "value"; 4713 f ? (p || d ? w = { 4714 get: _setFunctionName(function () { 4715 return g(this); 4716 }, n, "get"), 4717 set: function (e) { 4718 t[4](this, e); 4719 } 4720 } : w[A] = g, p || _setFunctionName(w[A], n, 2 === o ? "" : A)) : p || (w = Object.getOwnPropertyDescriptor(e, n)); 4721 } 4722 for (var P = e, j = v.length - 1; j >= 0; j -= r ? 2 : 1) { 4723 var D = v[j], 4724 E = r ? v[j - 1] : void 0, 4725 I = {}, 4726 O = { 4727 kind: ["field", "accessor", "method", "getter", "setter", "class"][o], 4728 name: n, 4729 metadata: a, 4730 addInitializer: function (e, t) { 4731 if (e.v) throw new Error("attempted to call addInitializer after decoration was finished"); 4732 s(t, "An initializer", "be", !0), c.push(t); 4733 }.bind(null, I) 4734 }; 4735 try { 4736 if (b) (y = s(D.call(E, P, O), "class decorators", "return")) && (P = y);else { 4737 var k, F; 4738 O.static = l, O.private = f, f ? 2 === o ? k = function (e) { 4739 return m(e), w.value; 4740 } : (o < 4 && (k = i(w, "get", m)), 3 !== o && (F = i(w, "set", m))) : (k = function (e) { 4741 return e[n]; 4742 }, (o < 2 || 4 === o) && (F = function (e, t) { 4743 e[n] = t; 4744 })); 4745 var N = O.access = { 4746 has: f ? h.bind() : function (e) { 4747 return n in e; 4748 } 4749 }; 4750 if (k && (N.get = k), F && (N.set = F), P = D.call(E, d ? { 4751 get: w.get, 4752 set: w.set 4753 } : w[A], O), d) { 4754 if ("object" == typeof P && P) (y = s(P.get, "accessor.get")) && (w.get = y), (y = s(P.set, "accessor.set")) && (w.set = y), (y = s(P.init, "accessor.init")) && S.push(y);else if (void 0 !== P) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); 4755 } else s(P, (p ? "field" : "method") + " decorators", "return") && (p ? S.push(P) : w[A] = P); 4756 } 4757 } finally { 4758 I.v = !0; 4759 } 4760 } 4761 return (p || d) && u.push(function (e, t) { 4762 for (var r = S.length - 1; r >= 0; r--) t = S[r].call(e, t); 4763 return t; 4764 }), p || b || (f ? d ? u.push(i(w, "get"), i(w, "set")) : u.push(2 === o ? w[A] : i.call.bind(w[A])) : Object.defineProperty(e, n, w)), P; 4765 } 4766 function u(e, t) { 4767 return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), { 4768 configurable: !0, 4769 enumerable: !0, 4770 value: t 4771 }); 4772 } 4773 if (arguments.length >= 6) var l = a[Symbol.metadata || Symbol.for("Symbol.metadata")]; 4774 var f = Object.create(null == l ? null : l), 4775 p = function (e, t, r, n) { 4776 var o, 4777 a, 4778 i = [], 4779 s = function (t) { 4780 return _checkInRHS(t) === e; 4781 }, 4782 u = new Map(); 4783 function l(e) { 4784 e && i.push(c.bind(null, e)); 4785 } 4786 for (var f = 0; f < t.length; f++) { 4787 var p = t[f]; 4788 if (Array.isArray(p)) { 4789 var d = p[1], 4790 h = p[2], 4791 m = p.length > 3, 4792 y = 16 & d, 4793 v = !!(8 & d), 4794 g = 0 == (d &= 7), 4795 b = h + "/" + v; 4796 if (!g && !m) { 4797 var w = u.get(b); 4798 if (!0 === w || 3 === w && 4 !== d || 4 === w && 3 !== d) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + h); 4799 u.set(b, !(d > 2) || d); 4800 } 4801 applyDec(v ? e : e.prototype, p, y, m ? "#" + h : _toPropertyKey(h), d, n, v ? a = a || [] : o = o || [], i, v, m, g, 1 === d, v && m ? s : r); 4802 } 4803 } 4804 return l(o), l(a), i; 4805 }(e, t, o, f); 4806 return r.length || u(e, f), { 4807 e: p, 4808 get c() { 4809 var t = []; 4810 return r.length && [u(applyDec(e, [r], n, e.name, 5, f, t), f), c.bind(null, t, e)]; 4811 } 4812 }; 4813 } 4814 function _asyncGeneratorDelegate(t) { 4815 var e = {}, 4816 n = !1; 4817 function pump(e, r) { 4818 return n = !0, r = new Promise(function (n) { 4819 n(t[e](r)); 4820 }), { 4821 done: !1, 4822 value: new _OverloadYield(r, 1) 4823 }; 4824 } 4825 return e["undefined" != typeof Symbol && Symbol.iterator || "@@iterator"] = function () { 4826 return this; 4827 }, e.next = function (t) { 4828 return n ? (n = !1, t) : pump("next", t); 4829 }, "function" == typeof t.throw && (e.throw = function (t) { 4830 if (n) throw n = !1, t; 4831 return pump("throw", t); 4832 }), "function" == typeof t.return && (e.return = function (t) { 4833 return n ? (n = !1, t) : pump("return", t); 4834 }), e; 4835 } 4836 function _asyncIterator(r) { 4837 var n, 4838 t, 4839 o, 4840 e = 2; 4841 for ("undefined" != typeof Symbol && (t = Symbol.asyncIterator, o = Symbol.iterator); e--;) { 4842 if (t && null != (n = r[t])) return n.call(r); 4843 if (o && null != (n = r[o])) return new AsyncFromSyncIterator(n.call(r)); 4844 t = "@@asyncIterator", o = "@@iterator"; 4845 } 4846 throw new TypeError("Object is not async iterable"); 4847 } 4848 function AsyncFromSyncIterator(r) { 4849 function AsyncFromSyncIteratorContinuation(r) { 4850 if (Object(r) !== r) return Promise.reject(new TypeError(r + " is not an object.")); 4851 var n = r.done; 4852 return Promise.resolve(r.value).then(function (r) { 4853 return { 4854 value: r, 4855 done: n 4856 }; 4857 }); 4858 } 4859 return AsyncFromSyncIterator = function (r) { 4860 this.s = r, this.n = r.next; 4861 }, AsyncFromSyncIterator.prototype = { 4862 s: null, 4863 n: null, 4864 next: function () { 4865 return AsyncFromSyncIteratorContinuation(this.n.apply(this.s, arguments)); 4866 }, 4867 return: function (r) { 4868 var n = this.s.return; 4869 return void 0 === n ? Promise.resolve({ 4870 value: r, 4871 done: !0 4872 }) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments)); 4873 }, 4874 throw: function (r) { 4875 var n = this.s.return; 4876 return void 0 === n ? Promise.reject(r) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments)); 4877 } 4878 }, new AsyncFromSyncIterator(r); 4879 } 4880 function _awaitAsyncGenerator(e) { 4881 return new _OverloadYield(e, 0); 4882 } 4883 function _callSuper(t, o, e) { 4884 return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); 4885 } 4886 function _checkInRHS(e) { 4887 if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); 4888 return e; 4889 } 4890 function _construct(t, e, r) { 4891 if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); 4892 var o = [null]; 4893 o.push.apply(o, e); 4894 var p = new (t.bind.apply(t, o))(); 4895 return r && _setPrototypeOf(p, r.prototype), p; 4896 } 4897 function _defineAccessor(e, r, n, t) { 4898 var c = { 4899 configurable: !0, 4900 enumerable: !0 4901 }; 4902 return c[e] = t, Object.defineProperty(r, n, c); 4903 } 4904 function dispose_SuppressedError(r, e) { 4905 return "undefined" != typeof SuppressedError ? dispose_SuppressedError = SuppressedError : (dispose_SuppressedError = function (r, e) { 4906 this.suppressed = e, this.error = r, this.stack = new Error().stack; 4907 }, dispose_SuppressedError.prototype = Object.create(Error.prototype, { 4908 constructor: { 4909 value: dispose_SuppressedError, 4910 writable: !0, 4911 configurable: !0 4912 } 4913 })), new dispose_SuppressedError(r, e); 4914 } 4915 function _dispose(r, e, s) { 4916 function next() { 4917 for (; r.length > 0;) try { 4918 var o = r.pop(), 4919 p = o.d.call(o.v); 4920 if (o.a) return Promise.resolve(p).then(next, err); 4921 } catch (r) { 4922 return err(r); 4923 } 4924 if (s) throw e; 4925 } 4926 function err(r) { 4927 return e = s ? new dispose_SuppressedError(e, r) : r, s = !0, next(); 4928 } 4929 return next(); 4930 } 4931 function _importDeferProxy(e) { 4932 var t = null, 4933 constValue = function (e) { 4934 return function () { 4935 return e; 4936 }; 4937 }, 4938 proxy = function (r) { 4939 return function (n, o, f) { 4940 return null === t && (t = e()), r(t, o, f); 4941 }; 4942 }; 4943 return new Proxy({}, { 4944 defineProperty: constValue(!1), 4945 deleteProperty: constValue(!1), 4946 get: proxy(Reflect.get), 4947 getOwnPropertyDescriptor: proxy(Reflect.getOwnPropertyDescriptor), 4948 getPrototypeOf: constValue(null), 4949 isExtensible: constValue(!1), 4950 has: proxy(Reflect.has), 4951 ownKeys: proxy(Reflect.ownKeys), 4952 preventExtensions: constValue(!0), 4953 set: constValue(!1), 4954 setPrototypeOf: constValue(!1) 4955 }); 4956 } 4957 function _getRequireWildcardCache(e) { 4958 if ("function" != typeof WeakMap) return null; 4959 var r = new WeakMap(), 4960 t = new WeakMap(); 4961 return (_getRequireWildcardCache = function (e) { 4962 return e ? t : r; 4963 })(e); 4964 } 4965 function _interopRequireWildcard(e, r) { 4966 if (!r && e && e.__esModule) return e; 4967 if (null === e || "object" != typeof e && "function" != typeof e) return { 4968 default: e 4969 }; 4970 var t = _getRequireWildcardCache(r); 4971 if (t && t.has(e)) return t.get(e); 4972 var n = { 4973 __proto__: null 4974 }, 4975 a = Object.defineProperty && Object.getOwnPropertyDescriptor; 4976 for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { 4977 var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; 4978 i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; 4979 } 4980 return n.default = e, t && t.set(e, n), n; 4981 } 4982 function _isNativeReflectConstruct() { 4983 try { 4984 var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); 4985 } catch (t) {} 4986 return (_isNativeReflectConstruct = function () { 4987 return !!t; 4988 })(); 4989 } 4990 function _iterableToArrayLimit(r, l) { 4991 var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; 4992 if (null != t) { 4993 var e, 4994 n, 4995 i, 4996 u, 4997 a = [], 4998 f = !0, 4999 o = !1; 5000 try { 5001 if (i = (t = t.call(r)).next, 0 === l) { 5002 if (Object(t) !== t) return; 5003 f = !1; 5004 } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); 5005 } catch (r) { 5006 o = !0, n = r; 5007 } finally { 5008 try { 5009 if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; 5010 } finally { 5011 if (o) throw n; 5012 } 5013 } 5014 return a; 5015 } 5016 } 5017 function _iterableToArrayLimitLoose(e, r) { 5018 var t = e && ("undefined" != typeof Symbol && e[Symbol.iterator] || e["@@iterator"]); 5019 if (null != t) { 5020 var o, 5021 l = []; 5022 for (t = t.call(e); e.length < r && !(o = t.next()).done;) l.push(o.value); 5023 return l; 5024 } 5025 } 5026 var REACT_ELEMENT_TYPE; 5027 function _jsx(e, r, E, l) { 5028 REACT_ELEMENT_TYPE || (REACT_ELEMENT_TYPE = "function" == typeof Symbol && Symbol.for && Symbol.for("react.element") || 60103); 5029 var o = e && e.defaultProps, 5030 n = arguments.length - 3; 5031 if (r || 0 === n || (r = { 5032 children: void 0 5033 }), 1 === n) r.children = l;else if (n > 1) { 5034 for (var t = new Array(n), f = 0; f < n; f++) t[f] = arguments[f + 3]; 5035 r.children = t; 5036 } 5037 if (r && o) for (var i in o) void 0 === r[i] && (r[i] = o[i]);else r || (r = o || {}); 5038 return { 5039 $$typeof: REACT_ELEMENT_TYPE, 5040 type: e, 5041 key: void 0 === E ? null : "" + E, 5042 ref: null, 5043 props: r, 5044 _owner: null 5045 }; 5046 } 5047 function ownKeys(e, r) { 5048 var t = Object.keys(e); 5049 if (Object.getOwnPropertySymbols) { 5050 var o = Object.getOwnPropertySymbols(e); 5051 r && (o = o.filter(function (r) { 5052 return Object.getOwnPropertyDescriptor(e, r).enumerable; 5053 })), t.push.apply(t, o); 5054 } 5055 return t; 5056 } 5057 function _objectSpread2(e) { 5058 for (var r = 1; r < arguments.length; r++) { 5059 var t = null != arguments[r] ? arguments[r] : {}; 5060 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { 5061 _defineProperty(e, r, t[r]); 5062 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { 5063 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); 5064 }); 5065 } 5066 return e; 5067 } 5068 function _regeneratorRuntime() { 5069 "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ 5070 _regeneratorRuntime = function () { 5071 return e; 5072 }; 5073 var t, 5074 e = {}, 5075 r = Object.prototype, 5076 n = r.hasOwnProperty, 5077 o = Object.defineProperty || function (t, e, r) { 5078 t[e] = r.value; 5079 }, 5080 i = "function" == typeof Symbol ? Symbol : {}, 5081 a = i.iterator || "@@iterator", 5082 c = i.asyncIterator || "@@asyncIterator", 5083 u = i.toStringTag || "@@toStringTag"; 5084 function define(t, e, r) { 5085 return Object.defineProperty(t, e, { 5086 value: r, 5087 enumerable: !0, 5088 configurable: !0, 5089 writable: !0 5090 }), t[e]; 5091 } 5092 try { 5093 define({}, ""); 5094 } catch (t) { 5095 define = function (t, e, r) { 5096 return t[e] = r; 5097 }; 5098 } 5099 function wrap(t, e, r, n) { 5100 var i = e && e.prototype instanceof Generator ? e : Generator, 5101 a = Object.create(i.prototype), 5102 c = new Context(n || []); 5103 return o(a, "_invoke", { 5104 value: makeInvokeMethod(t, r, c) 5105 }), a; 5106 } 5107 function tryCatch(t, e, r) { 5108 try { 5109 return { 5110 type: "normal", 5111 arg: t.call(e, r) 5112 }; 5113 } catch (t) { 5114 return { 5115 type: "throw", 5116 arg: t 5117 }; 5118 } 5119 } 5120 e.wrap = wrap; 5121 var h = "suspendedStart", 5122 l = "suspendedYield", 5123 f = "executing", 5124 s = "completed", 5125 y = {}; 5126 function Generator() {} 5127 function GeneratorFunction() {} 5128 function GeneratorFunctionPrototype() {} 5129 var p = {}; 5130 define(p, a, function () { 5131 return this; 5132 }); 5133 var d = Object.getPrototypeOf, 5134 v = d && d(d(values([]))); 5135 v && v !== r && n.call(v, a) && (p = v); 5136 var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); 5137 function defineIteratorMethods(t) { 5138 ["next", "throw", "return"].forEach(function (e) { 5139 define(t, e, function (t) { 5140 return this._invoke(e, t); 5141 }); 5142 }); 5143 } 5144 function AsyncIterator(t, e) { 5145 function invoke(r, o, i, a) { 5146 var c = tryCatch(t[r], t, o); 5147 if ("throw" !== c.type) { 5148 var u = c.arg, 5149 h = u.value; 5150 return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { 5151 invoke("next", t, i, a); 5152 }, function (t) { 5153 invoke("throw", t, i, a); 5154 }) : e.resolve(h).then(function (t) { 5155 u.value = t, i(u); 5156 }, function (t) { 5157 return invoke("throw", t, i, a); 5158 }); 5159 } 5160 a(c.arg); 5161 } 5162 var r; 5163 o(this, "_invoke", { 5164 value: function (t, n) { 5165 function callInvokeWithMethodAndArg() { 5166 return new e(function (e, r) { 5167 invoke(t, n, e, r); 5168 }); 5169 } 5170 return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); 5171 } 5172 }); 5173 } 5174 function makeInvokeMethod(e, r, n) { 5175 var o = h; 5176 return function (i, a) { 5177 if (o === f) throw new Error("Generator is already running"); 5178 if (o === s) { 5179 if ("throw" === i) throw a; 5180 return { 5181 value: t, 5182 done: !0 5183 }; 5184 } 5185 for (n.method = i, n.arg = a;;) { 5186 var c = n.delegate; 5187 if (c) { 5188 var u = maybeInvokeDelegate(c, n); 5189 if (u) { 5190 if (u === y) continue; 5191 return u; 5192 } 5193 } 5194 if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { 5195 if (o === h) throw o = s, n.arg; 5196 n.dispatchException(n.arg); 5197 } else "return" === n.method && n.abrupt("return", n.arg); 5198 o = f; 5199 var p = tryCatch(e, r, n); 5200 if ("normal" === p.type) { 5201 if (o = n.done ? s : l, p.arg === y) continue; 5202 return { 5203 value: p.arg, 5204 done: n.done 5205 }; 5206 } 5207 "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); 5208 } 5209 }; 5210 } 5211 function maybeInvokeDelegate(e, r) { 5212 var n = r.method, 5213 o = e.iterator[n]; 5214 if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; 5215 var i = tryCatch(o, e.iterator, r.arg); 5216 if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; 5217 var a = i.arg; 5218 return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); 5219 } 5220 function pushTryEntry(t) { 5221 var e = { 5222 tryLoc: t[0] 5223 }; 5224 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); 5225 } 5226 function resetTryEntry(t) { 5227 var e = t.completion || {}; 5228 e.type = "normal", delete e.arg, t.completion = e; 5229 } 5230 function Context(t) { 5231 this.tryEntries = [{ 5232 tryLoc: "root" 5233 }], t.forEach(pushTryEntry, this), this.reset(!0); 5234 } 5235 function values(e) { 5236 if (e || "" === e) { 5237 var r = e[a]; 5238 if (r) return r.call(e); 5239 if ("function" == typeof e.next) return e; 5240 if (!isNaN(e.length)) { 5241 var o = -1, 5242 i = function next() { 5243 for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; 5244 return next.value = t, next.done = !0, next; 5245 }; 5246 return i.next = i; 5247 } 5248 } 5249 throw new TypeError(typeof e + " is not iterable"); 5250 } 5251 return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { 5252 value: GeneratorFunctionPrototype, 5253 configurable: !0 5254 }), o(GeneratorFunctionPrototype, "constructor", { 5255 value: GeneratorFunction, 5256 configurable: !0 5257 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { 5258 var e = "function" == typeof t && t.constructor; 5259 return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); 5260 }, e.mark = function (t) { 5261 return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; 5262 }, e.awrap = function (t) { 5263 return { 5264 __await: t 5265 }; 5266 }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { 5267 return this; 5268 }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { 5269 void 0 === i && (i = Promise); 5270 var a = new AsyncIterator(wrap(t, r, n, o), i); 5271 return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { 5272 return t.done ? t.value : a.next(); 5273 }); 5274 }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { 5275 return this; 5276 }), define(g, "toString", function () { 5277 return "[object Generator]"; 5278 }), e.keys = function (t) { 5279 var e = Object(t), 5280 r = []; 5281 for (var n in e) r.push(n); 5282 return r.reverse(), function next() { 5283 for (; r.length;) { 5284 var t = r.pop(); 5285 if (t in e) return next.value = t, next.done = !1, next; 5286 } 5287 return next.done = !0, next; 5288 }; 5289 }, e.values = values, Context.prototype = { 5290 constructor: Context, 5291 reset: function (e) { 5292 if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); 5293 }, 5294 stop: function () { 5295 this.done = !0; 5296 var t = this.tryEntries[0].completion; 5297 if ("throw" === t.type) throw t.arg; 5298 return this.rval; 5299 }, 5300 dispatchException: function (e) { 5301 if (this.done) throw e; 5302 var r = this; 5303 function handle(n, o) { 5304 return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; 5305 } 5306 for (var o = this.tryEntries.length - 1; o >= 0; --o) { 5307 var i = this.tryEntries[o], 5308 a = i.completion; 5309 if ("root" === i.tryLoc) return handle("end"); 5310 if (i.tryLoc <= this.prev) { 5311 var c = n.call(i, "catchLoc"), 5312 u = n.call(i, "finallyLoc"); 5313 if (c && u) { 5314 if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); 5315 if (this.prev < i.finallyLoc) return handle(i.finallyLoc); 5316 } else if (c) { 5317 if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); 5318 } else { 5319 if (!u) throw new Error("try statement without catch or finally"); 5320 if (this.prev < i.finallyLoc) return handle(i.finallyLoc); 5321 } 5322 } 5323 } 5324 }, 5325 abrupt: function (t, e) { 5326 for (var r = this.tryEntries.length - 1; r >= 0; --r) { 5327 var o = this.tryEntries[r]; 5328 if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { 5329 var i = o; 5330 break; 5331 } 5332 } 5333 i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); 5334 var a = i ? i.completion : {}; 5335 return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); 5336 }, 5337 complete: function (t, e) { 5338 if ("throw" === t.type) throw t.arg; 5339 return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; 5340 }, 5341 finish: function (t) { 5342 for (var e = this.tryEntries.length - 1; e >= 0; --e) { 5343 var r = this.tryEntries[e]; 5344 if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; 5345 } 5346 }, 5347 catch: function (t) { 5348 for (var e = this.tryEntries.length - 1; e >= 0; --e) { 5349 var r = this.tryEntries[e]; 5350 if (r.tryLoc === t) { 5351 var n = r.completion; 5352 if ("throw" === n.type) { 5353 var o = n.arg; 5354 resetTryEntry(r); 5355 } 5356 return o; 5357 } 5358 } 5359 throw new Error("illegal catch attempt"); 5360 }, 5361 delegateYield: function (e, r, n) { 5362 return this.delegate = { 5363 iterator: values(e), 5364 resultName: r, 5365 nextLoc: n 5366 }, "next" === this.method && (this.arg = t), y; 5367 } 5368 }, e; 5369 } 5370 function _setFunctionName(e, t, n) { 5371 "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); 5372 try { 5373 Object.defineProperty(e, "name", { 5374 configurable: !0, 5375 value: n ? n + " " + t : t 5376 }); 5377 } catch (e) {} 5378 return e; 5379 } 5380 function _toPrimitive(t, r) { 5381 if ("object" != typeof t || !t) return t; 5382 var e = t[Symbol.toPrimitive]; 5383 if (void 0 !== e) { 5384 var i = e.call(t, r || "default"); 5385 if ("object" != typeof i) return i; 5386 throw new TypeError("@@toPrimitive must return a primitive value."); 5387 } 5388 return ("string" === r ? String : Number)(t); 5389 } 5390 function _toPropertyKey(t) { 5391 var i = _toPrimitive(t, "string"); 5392 return "symbol" == typeof i ? i : String(i); 5393 } 5394 function _typeof(o) { 5395 "@babel/helpers - typeof"; 5396 5397 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { 5398 return typeof o; 5399 } : function (o) { 5400 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; 5401 }, _typeof(o); 5402 } 5403 function _using(o, n, e) { 5404 if (null == n) return n; 5405 if (Object(n) !== n) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined."); 5406 if (e) var r = n[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]; 5407 if (null == r && (r = n[Symbol.dispose || Symbol.for("Symbol.dispose")]), "function" != typeof r) throw new TypeError("Property [Symbol.dispose] is not a function."); 5408 return o.push({ 5409 v: n, 5410 d: r, 5411 a: e 5412 }), n; 5413 } 5414 function _usingCtx() { 5415 var r = "function" == typeof SuppressedError ? SuppressedError : function (r, n) { 5416 var e = new Error(); 5417 return e.name = "SuppressedError", e.suppressed = n, e.error = r, e; 5418 }, 5419 n = {}, 5420 e = []; 5421 function using(r, n) { 5422 if (null != n) { 5423 if (Object(n) !== n) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined."); 5424 if (r) var o = n[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]; 5425 if (null == o && (o = n[Symbol.dispose || Symbol.for("Symbol.dispose")]), "function" != typeof o) throw new TypeError("Property [Symbol.dispose] is not a function."); 5426 e.push({ 5427 v: n, 5428 d: o, 5429 a: r 5430 }); 5431 } 5432 return n; 5433 } 5434 return { 5435 e: n, 5436 u: using.bind(null, !1), 5437 a: using.bind(null, !0), 5438 d: function () { 5439 var o = this.e; 5440 function next() { 5441 for (; r = e.pop();) try { 5442 var r, 5443 t = r.d.call(r.v); 5444 if (r.a) return Promise.resolve(t).then(next, err); 5445 } catch (r) { 5446 return err(r); 5447 } 5448 if (o !== n) throw o; 5449 } 5450 function err(e) { 5451 return o = o !== n ? new r(o, e) : e, next(); 5452 } 5453 return next(); 5454 } 5455 }; 5456 } 5457 function _wrapRegExp() { 5458 _wrapRegExp = function (e, r) { 5459 return new BabelRegExp(e, void 0, r); 5460 }; 5461 var e = RegExp.prototype, 5462 r = new WeakMap(); 5463 function BabelRegExp(e, t, p) { 5464 var o = new RegExp(e, t); 5465 return r.set(o, p || r.get(e)), _setPrototypeOf(o, BabelRegExp.prototype); 5466 } 5467 function buildGroups(e, t) { 5468 var p = r.get(t); 5469 return Object.keys(p).reduce(function (r, t) { 5470 var o = p[t]; 5471 if ("number" == typeof o) r[t] = e[o];else { 5472 for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++; 5473 r[t] = e[o[i]]; 5474 } 5475 return r; 5476 }, Object.create(null)); 5477 } 5478 return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) { 5479 var t = e.exec.call(this, r); 5480 if (t) { 5481 t.groups = buildGroups(t, this); 5482 var p = t.indices; 5483 p && (p.groups = buildGroups(p, this)); 5484 } 5485 return t; 5486 }, BabelRegExp.prototype[Symbol.replace] = function (t, p) { 5487 if ("string" == typeof p) { 5488 var o = r.get(this); 5489 return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)>/g, function (e, r) { 5490 var t = o[r]; 5491 return "$" + (Array.isArray(t) ? t.join("$") : t); 5492 })); 5493 } 5494 if ("function" == typeof p) { 5495 var i = this; 5496 return e[Symbol.replace].call(this, t, function () { 5497 var e = arguments; 5498 return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e); 5499 }); 5500 } 5501 return e[Symbol.replace].call(this, t, p); 5502 }, _wrapRegExp.apply(this, arguments); 5503 } 5504 function _AwaitValue(value) { 5505 this.wrapped = value; 5506 } 5507 function _wrapAsyncGenerator(fn) { 5508 return function () { 5509 return new _AsyncGenerator(fn.apply(this, arguments)); 5510 }; 5511 } 5512 function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { 5513 try { 5514 var info = gen[key](arg); 5515 var value = info.value; 5516 } catch (error) { 5517 reject(error); 5518 return; 5519 } 5520 if (info.done) { 5521 resolve(value); 5522 } else { 5523 Promise.resolve(value).then(_next, _throw); 5524 } 5525 } 5526 function _asyncToGenerator(fn) { 5527 return function () { 5528 var self = this, 5529 args = arguments; 5530 return new Promise(function (resolve, reject) { 5531 var gen = fn.apply(self, args); 5532 function _next(value) { 5533 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); 5534 } 5535 function _throw(err) { 5536 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); 5537 } 5538 _next(undefined); 5539 }); 5540 }; 5541 } 5542 function _classCallCheck(instance, Constructor) { 5543 if (!(instance instanceof Constructor)) { 5544 throw new TypeError("Cannot call a class as a function"); 5545 } 5546 } 5547 function _defineProperties(target, props) { 5548 for (var i = 0; i < props.length; i++) { 5549 var descriptor = props[i]; 5550 descriptor.enumerable = descriptor.enumerable || false; 5551 descriptor.configurable = true; 5552 if ("value" in descriptor) descriptor.writable = true; 5553 Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); 5554 } 5555 } 5556 function _createClass(Constructor, protoProps, staticProps) { 5557 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 5558 if (staticProps) _defineProperties(Constructor, staticProps); 5559 Object.defineProperty(Constructor, "prototype", { 5560 writable: false 5561 }); 5562 return Constructor; 5563 } 5564 function _defineEnumerableProperties(obj, descs) { 5565 for (var key in descs) { 5566 var desc = descs[key]; 5567 desc.configurable = desc.enumerable = true; 5568 if ("value" in desc) desc.writable = true; 5569 Object.defineProperty(obj, key, desc); 5570 } 5571 if (Object.getOwnPropertySymbols) { 5572 var objectSymbols = Object.getOwnPropertySymbols(descs); 5573 for (var i = 0; i < objectSymbols.length; i++) { 5574 var sym = objectSymbols[i]; 5575 var desc = descs[sym]; 5576 desc.configurable = desc.enumerable = true; 5577 if ("value" in desc) desc.writable = true; 5578 Object.defineProperty(obj, sym, desc); 5579 } 5580 } 5581 return obj; 5582 } 5583 function _defaults(obj, defaults) { 5584 var keys = Object.getOwnPropertyNames(defaults); 5585 for (var i = 0; i < keys.length; i++) { 5586 var key = keys[i]; 5587 var value = Object.getOwnPropertyDescriptor(defaults, key); 5588 if (value && value.configurable && obj[key] === undefined) { 5589 Object.defineProperty(obj, key, value); 5590 } 5591 } 5592 return obj; 5593 } 5594 function _defineProperty(obj, key, value) { 5595 key = _toPropertyKey(key); 5596 if (key in obj) { 5597 Object.defineProperty(obj, key, { 5598 value: value, 5599 enumerable: true, 5600 configurable: true, 5601 writable: true 5602 }); 5603 } else { 5604 obj[key] = value; 5605 } 5606 return obj; 5607 } 5608 function _extends() { 5609 _extends = Object.assign ? Object.assign.bind() : function (target) { 5610 for (var i = 1; i < arguments.length; i++) { 5611 var source = arguments[i]; 5612 for (var key in source) { 5613 if (Object.prototype.hasOwnProperty.call(source, key)) { 5614 target[key] = source[key]; 5615 } 5616 } 5617 } 5618 return target; 5619 }; 5620 return _extends.apply(this, arguments); 5621 } 5622 function _objectSpread(target) { 5623 for (var i = 1; i < arguments.length; i++) { 5624 var source = arguments[i] != null ? Object(arguments[i]) : {}; 5625 var ownKeys = Object.keys(source); 5626 if (typeof Object.getOwnPropertySymbols === 'function') { 5627 ownKeys.push.apply(ownKeys, Object.getOwnPropertySymbols(source).filter(function (sym) { 5628 return Object.getOwnPropertyDescriptor(source, sym).enumerable; 5629 })); 5630 } 5631 ownKeys.forEach(function (key) { 5632 _defineProperty(target, key, source[key]); 5633 }); 5634 } 5635 return target; 5636 } 5637 function _inherits(subClass, superClass) { 5638 if (typeof superClass !== "function" && superClass !== null) { 5639 throw new TypeError("Super expression must either be null or a function"); 5640 } 5641 subClass.prototype = Object.create(superClass && superClass.prototype, { 5642 constructor: { 5643 value: subClass, 5644 writable: true, 5645 configurable: true 5646 } 5647 }); 5648 Object.defineProperty(subClass, "prototype", { 5649 writable: false 5650 }); 5651 if (superClass) _setPrototypeOf(subClass, superClass); 5652 } 5653 function _inheritsLoose(subClass, superClass) { 5654 subClass.prototype = Object.create(superClass.prototype); 5655 subClass.prototype.constructor = subClass; 5656 _setPrototypeOf(subClass, superClass); 5657 } 5658 function _getPrototypeOf(o) { 5659 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { 5660 return o.__proto__ || Object.getPrototypeOf(o); 5661 }; 5662 return _getPrototypeOf(o); 5663 } 5664 function _setPrototypeOf(o, p) { 5665 _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { 5666 o.__proto__ = p; 5667 return o; 5668 }; 5669 return _setPrototypeOf(o, p); 5670 } 5671 function _isNativeFunction(fn) { 5672 try { 5673 return Function.toString.call(fn).indexOf("[native code]") !== -1; 5674 } catch (e) { 5675 return typeof fn === "function"; 5676 } 5677 } 5678 function _wrapNativeSuper(Class) { 5679 var _cache = typeof Map === "function" ? new Map() : undefined; 5680 _wrapNativeSuper = function _wrapNativeSuper(Class) { 5681 if (Class === null || !_isNativeFunction(Class)) return Class; 5682 if (typeof Class !== "function") { 5683 throw new TypeError("Super expression must either be null or a function"); 5684 } 5685 if (typeof _cache !== "undefined") { 5686 if (_cache.has(Class)) return _cache.get(Class); 5687 _cache.set(Class, Wrapper); 5688 } 5689 function Wrapper() { 5690 return _construct(Class, arguments, _getPrototypeOf(this).constructor); 5691 } 5692 Wrapper.prototype = Object.create(Class.prototype, { 5693 constructor: { 5694 value: Wrapper, 5695 enumerable: false, 5696 writable: true, 5697 configurable: true 5698 } 5699 }); 5700 return _setPrototypeOf(Wrapper, Class); 5701 }; 5702 return _wrapNativeSuper(Class); 5703 } 5704 function _instanceof(left, right) { 5705 if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { 5706 return !!right[Symbol.hasInstance](left); 5707 } else { 5708 return left instanceof right; 5709 } 5710 } 5711 function _interopRequireDefault(obj) { 5712 return obj && obj.__esModule ? obj : { 5713 default: obj 5714 }; 5715 } 5716 function _newArrowCheck(innerThis, boundThis) { 5717 if (innerThis !== boundThis) { 5718 throw new TypeError("Cannot instantiate an arrow function"); 5719 } 5720 } 5721 function _objectDestructuringEmpty(obj) { 5722 if (obj == null) throw new TypeError("Cannot destructure " + obj); 5723 } 5724 function _objectWithoutPropertiesLoose(source, excluded) { 5725 if (source == null) return {}; 5726 var target = {}; 5727 var sourceKeys = Object.keys(source); 5728 var key, i; 5729 for (i = 0; i < sourceKeys.length; i++) { 5730 key = sourceKeys[i]; 5731 if (excluded.indexOf(key) >= 0) continue; 5732 target[key] = source[key]; 5733 } 5734 return target; 5735 } 5736 function _objectWithoutProperties(source, excluded) { 5737 if (source == null) return {}; 5738 var target = _objectWithoutPropertiesLoose(source, excluded); 5739 var key, i; 5740 if (Object.getOwnPropertySymbols) { 5741 var sourceSymbolKeys = Object.getOwnPropertySymbols(source); 5742 for (i = 0; i < sourceSymbolKeys.length; i++) { 5743 key = sourceSymbolKeys[i]; 5744 if (excluded.indexOf(key) >= 0) continue; 5745 if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; 5746 target[key] = source[key]; 5747 } 5748 } 5749 return target; 5750 } 5751 function _assertThisInitialized(self) { 5752 if (self === void 0) { 5753 throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 5754 } 5755 return self; 5756 } 5757 function _possibleConstructorReturn(self, call) { 5758 if (call && (typeof call === "object" || typeof call === "function")) { 5759 return call; 5760 } else if (call !== void 0) { 5761 throw new TypeError("Derived constructors may only return object or undefined"); 5762 } 5763 return _assertThisInitialized(self); 5764 } 5765 function _createSuper(Derived) { 5766 var hasNativeReflectConstruct = _isNativeReflectConstruct(); 5767 return function _createSuperInternal() { 5768 var Super = _getPrototypeOf(Derived), 5769 result; 5770 if (hasNativeReflectConstruct) { 5771 var NewTarget = _getPrototypeOf(this).constructor; 5772 result = Reflect.construct(Super, arguments, NewTarget); 5773 } else { 5774 result = Super.apply(this, arguments); 5775 } 5776 return _possibleConstructorReturn(this, result); 5777 }; 5778 } 5779 function _superPropBase(object, property) { 5780 while (!Object.prototype.hasOwnProperty.call(object, property)) { 5781 object = _getPrototypeOf(object); 5782 if (object === null) break; 5783 } 5784 return object; 5785 } 5786 function _get() { 5787 if (typeof Reflect !== "undefined" && Reflect.get) { 5788 _get = Reflect.get.bind(); 5789 } else { 5790 _get = function _get(target, property, receiver) { 5791 var base = _superPropBase(target, property); 5792 if (!base) return; 5793 var desc = Object.getOwnPropertyDescriptor(base, property); 5794 if (desc.get) { 5795 return desc.get.call(arguments.length < 3 ? target : receiver); 5796 } 5797 return desc.value; 5798 }; 5799 } 5800 return _get.apply(this, arguments); 5801 } 5802 function set(target, property, value, receiver) { 5803 if (typeof Reflect !== "undefined" && Reflect.set) { 5804 set = Reflect.set; 5805 } else { 5806 set = function set(target, property, value, receiver) { 5807 var base = _superPropBase(target, property); 5808 var desc; 5809 if (base) { 5810 desc = Object.getOwnPropertyDescriptor(base, property); 5811 if (desc.set) { 5812 desc.set.call(receiver, value); 5813 return true; 5814 } else if (!desc.writable) { 5815 return false; 5816 } 5817 } 5818 desc = Object.getOwnPropertyDescriptor(receiver, property); 5819 if (desc) { 5820 if (!desc.writable) { 5821 return false; 5822 } 5823 desc.value = value; 5824 Object.defineProperty(receiver, property, desc); 5825 } else { 5826 _defineProperty(receiver, property, value); 5827 } 5828 return true; 5829 }; 5830 } 5831 return set(target, property, value, receiver); 5832 } 5833 function _set(target, property, value, receiver, isStrict) { 5834 var s = set(target, property, value, receiver || target); 5835 if (!s && isStrict) { 5836 throw new TypeError('failed to set property'); 5837 } 5838 return value; 5839 } 5840 function _taggedTemplateLiteral(strings, raw) { 5841 if (!raw) { 5842 raw = strings.slice(0); 5843 } 5844 return Object.freeze(Object.defineProperties(strings, { 5845 raw: { 5846 value: Object.freeze(raw) 5847 } 5848 })); 5849 } 5850 function _taggedTemplateLiteralLoose(strings, raw) { 5851 if (!raw) { 5852 raw = strings.slice(0); 5853 } 5854 strings.raw = raw; 5855 return strings; 5856 } 5857 function _readOnlyError(name) { 5858 throw new TypeError("\"" + name + "\" is read-only"); 5859 } 5860 function _writeOnlyError(name) { 5861 throw new TypeError("\"" + name + "\" is write-only"); 5862 } 5863 function _classNameTDZError(name) { 5864 throw new ReferenceError("Class \"" + name + "\" cannot be referenced in computed property keys."); 5865 } 5866 function _temporalUndefined() {} 5867 function _tdz(name) { 5868 throw new ReferenceError(name + " is not defined - temporal dead zone"); 5869 } 5870 function _temporalRef(val, name) { 5871 return val === _temporalUndefined ? _tdz(name) : val; 5872 } 5873 function _slicedToArray(arr, i) { 5874 return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); 5875 } 5876 function _slicedToArrayLoose(arr, i) { 5877 return _arrayWithHoles(arr) || _iterableToArrayLimitLoose(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); 5878 } 5879 function _toArray(arr) { 5880 return _arrayWithHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableRest(); 5881 } 5882 function _toConsumableArray(arr) { 5883 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); 5884 } 5885 function _arrayWithoutHoles(arr) { 5886 if (Array.isArray(arr)) return _arrayLikeToArray(arr); 5887 } 5888 function _arrayWithHoles(arr) { 5889 if (Array.isArray(arr)) return arr; 5890 } 5891 function _maybeArrayLike(next, arr, i) { 5892 if (arr && !Array.isArray(arr) && typeof arr.length === "number") { 5893 var len = arr.length; 5894 return _arrayLikeToArray(arr, i !== void 0 && i < len ? i : len); 5895 } 5896 return next(arr, i); 5897 } 5898 function _iterableToArray(iter) { 5899 if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); 5900 } 5901 function _unsupportedIterableToArray(o, minLen) { 5902 if (!o) return; 5903 if (typeof o === "string") return _arrayLikeToArray(o, minLen); 5904 var n = Object.prototype.toString.call(o).slice(8, -1); 5905 if (n === "Object" && o.constructor) n = o.constructor.name; 5906 if (n === "Map" || n === "Set") return Array.from(o); 5907 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); 5908 } 5909 function _arrayLikeToArray(arr, len) { 5910 if (len == null || len > arr.length) len = arr.length; 5911 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; 5912 return arr2; 5913 } 5914 function _nonIterableSpread() { 5915 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 5916 } 5917 function _nonIterableRest() { 5918 throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 5919 } 5920 function _createForOfIteratorHelper(o, allowArrayLike) { 5921 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; 5922 if (!it) { 5923 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { 5924 if (it) o = it; 5925 var i = 0; 5926 var F = function () {}; 5927 return { 5928 s: F, 5929 n: function () { 5930 if (i >= o.length) return { 5931 done: true 5932 }; 5933 return { 5934 done: false, 5935 value: o[i++] 5936 }; 5937 }, 5938 e: function (e) { 5939 throw e; 5940 }, 5941 f: F 5942 }; 5943 } 5944 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 5945 } 5946 var normalCompletion = true, 5947 didErr = false, 5948 err; 5949 return { 5950 s: function () { 5951 it = it.call(o); 5952 }, 5953 n: function () { 5954 var step = it.next(); 5955 normalCompletion = step.done; 5956 return step; 5957 }, 5958 e: function (e) { 5959 didErr = true; 5960 err = e; 5961 }, 5962 f: function () { 5963 try { 5964 if (!normalCompletion && it.return != null) it.return(); 5965 } finally { 5966 if (didErr) throw err; 5967 } 5968 } 5969 }; 5970 } 5971 function _createForOfIteratorHelperLoose(o, allowArrayLike) { 5972 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; 5973 if (it) return (it = it.call(o)).next.bind(it); 5974 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { 5975 if (it) o = it; 5976 var i = 0; 5977 return function () { 5978 if (i >= o.length) return { 5979 done: true 5980 }; 5981 return { 5982 done: false, 5983 value: o[i++] 5984 }; 5985 }; 5986 } 5987 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 5988 } 5989 function _skipFirstGeneratorNext(fn) { 5990 return function () { 5991 var it = fn.apply(this, arguments); 5992 it.next(); 5993 return it; 5994 }; 5995 } 5996 function _initializerWarningHelper(descriptor, context) { 5997 throw new Error('Decorating class property failed. Please ensure that ' + 'transform-class-properties is enabled and runs after the decorators transform.'); 5998 } 5999 function _initializerDefineProperty(target, property, descriptor, context) { 6000 if (!descriptor) return; 6001 Object.defineProperty(target, property, { 6002 enumerable: descriptor.enumerable, 6003 configurable: descriptor.configurable, 6004 writable: descriptor.writable, 6005 value: descriptor.initializer ? descriptor.initializer.call(context) : void 0 6006 }); 6007 } 6008 function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { 6009 var desc = {}; 6010 Object.keys(descriptor).forEach(function (key) { 6011 desc[key] = descriptor[key]; 6012 }); 6013 desc.enumerable = !!desc.enumerable; 6014 desc.configurable = !!desc.configurable; 6015 if ('value' in desc || desc.initializer) { 6016 desc.writable = true; 6017 } 6018 desc = decorators.slice().reverse().reduce(function (desc, decorator) { 6019 return decorator(target, property, desc) || desc; 6020 }, desc); 6021 if (context && desc.initializer !== void 0) { 6022 desc.value = desc.initializer ? desc.initializer.call(context) : void 0; 6023 desc.initializer = undefined; 6024 } 6025 if (desc.initializer === void 0) { 6026 Object.defineProperty(target, property, desc); 6027 desc = null; 6028 } 6029 return desc; 6030 } 6031 var id$1 = 0; 6032 function _classPrivateFieldLooseKey(name) { 6033 return "__private_" + id$1++ + "_" + name; 6034 } 6035 function _classPrivateFieldLooseBase(receiver, privateKey) { 6036 if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { 6037 throw new TypeError("attempted to use private field on non-instance"); 6038 } 6039 return receiver; 6040 } 6041 function _classPrivateFieldGet(receiver, privateMap) { 6042 var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); 6043 return _classApplyDescriptorGet(receiver, descriptor); 6044 } 6045 function _classPrivateFieldSet(receiver, privateMap, value) { 6046 var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); 6047 _classApplyDescriptorSet(receiver, descriptor, value); 6048 return value; 6049 } 6050 function _classPrivateFieldDestructureSet(receiver, privateMap) { 6051 var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); 6052 return _classApplyDescriptorDestructureSet(receiver, descriptor); 6053 } 6054 function _classExtractFieldDescriptor(receiver, privateMap, action) { 6055 if (!privateMap.has(receiver)) { 6056 throw new TypeError("attempted to " + action + " private field on non-instance"); 6057 } 6058 return privateMap.get(receiver); 6059 } 6060 function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) { 6061 _classCheckPrivateStaticAccess(receiver, classConstructor); 6062 _classCheckPrivateStaticFieldDescriptor(descriptor, "get"); 6063 return _classApplyDescriptorGet(receiver, descriptor); 6064 } 6065 function _classStaticPrivateFieldSpecSet(receiver, classConstructor, descriptor, value) { 6066 _classCheckPrivateStaticAccess(receiver, classConstructor); 6067 _classCheckPrivateStaticFieldDescriptor(descriptor, "set"); 6068 _classApplyDescriptorSet(receiver, descriptor, value); 6069 return value; 6070 } 6071 function _classStaticPrivateMethodGet(receiver, classConstructor, method) { 6072 _classCheckPrivateStaticAccess(receiver, classConstructor); 6073 return method; 6074 } 6075 function _classStaticPrivateMethodSet() { 6076 throw new TypeError("attempted to set read only static private field"); 6077 } 6078 function _classApplyDescriptorGet(receiver, descriptor) { 6079 if (descriptor.get) { 6080 return descriptor.get.call(receiver); 6081 } 6082 return descriptor.value; 6083 } 6084 function _classApplyDescriptorSet(receiver, descriptor, value) { 6085 if (descriptor.set) { 6086 descriptor.set.call(receiver, value); 6087 } else { 6088 if (!descriptor.writable) { 6089 throw new TypeError("attempted to set read only private field"); 6090 } 6091 descriptor.value = value; 6092 } 6093 } 6094 function _classApplyDescriptorDestructureSet(receiver, descriptor) { 6095 if (descriptor.set) { 6096 if (!("__destrObj" in descriptor)) { 6097 descriptor.__destrObj = { 6098 set value(v) { 6099 descriptor.set.call(receiver, v); 6100 } 6101 }; 6102 } 6103 return descriptor.__destrObj; 6104 } else { 6105 if (!descriptor.writable) { 6106 throw new TypeError("attempted to set read only private field"); 6107 } 6108 return descriptor; 6109 } 6110 } 6111 function _classStaticPrivateFieldDestructureSet(receiver, classConstructor, descriptor) { 6112 _classCheckPrivateStaticAccess(receiver, classConstructor); 6113 _classCheckPrivateStaticFieldDescriptor(descriptor, "set"); 6114 return _classApplyDescriptorDestructureSet(receiver, descriptor); 6115 } 6116 function _classCheckPrivateStaticAccess(receiver, classConstructor) { 6117 if (receiver !== classConstructor) { 6118 throw new TypeError("Private static access of wrong provenance"); 6119 } 6120 } 6121 function _classCheckPrivateStaticFieldDescriptor(descriptor, action) { 6122 if (descriptor === undefined) { 6123 throw new TypeError("attempted to " + action + " private static field before its declaration"); 6124 } 6125 } 6126 function _decorate(decorators, factory, superClass, mixins) { 6127 var api = _getDecoratorsApi(); 6128 if (mixins) { 6129 for (var i = 0; i < mixins.length; i++) { 6130 api = mixins[i](api); 6131 } 6132 } 6133 var r = factory(function initialize(O) { 6134 api.initializeInstanceElements(O, decorated.elements); 6135 }, superClass); 6136 var decorated = api.decorateClass(_coalesceClassElements(r.d.map(_createElementDescriptor)), decorators); 6137 api.initializeClassElements(r.F, decorated.elements); 6138 return api.runClassFinishers(r.F, decorated.finishers); 6139 } 6140 function _getDecoratorsApi() { 6141 _getDecoratorsApi = function () { 6142 return api; 6143 }; 6144 var api = { 6145 elementsDefinitionOrder: [["method"], ["field"]], 6146 initializeInstanceElements: function (O, elements) { 6147 ["method", "field"].forEach(function (kind) { 6148 elements.forEach(function (element) { 6149 if (element.kind === kind && element.placement === "own") { 6150 this.defineClassElement(O, element); 6151 } 6152 }, this); 6153 }, this); 6154 }, 6155 initializeClassElements: function (F, elements) { 6156 var proto = F.prototype; 6157 ["method", "field"].forEach(function (kind) { 6158 elements.forEach(function (element) { 6159 var placement = element.placement; 6160 if (element.kind === kind && (placement === "static" || placement === "prototype")) { 6161 var receiver = placement === "static" ? F : proto; 6162 this.defineClassElement(receiver, element); 6163 } 6164 }, this); 6165 }, this); 6166 }, 6167 defineClassElement: function (receiver, element) { 6168 var descriptor = element.descriptor; 6169 if (element.kind === "field") { 6170 var initializer = element.initializer; 6171 descriptor = { 6172 enumerable: descriptor.enumerable, 6173 writable: descriptor.writable, 6174 configurable: descriptor.configurable, 6175 value: initializer === void 0 ? void 0 : initializer.call(receiver) 6176 }; 6177 } 6178 Object.defineProperty(receiver, element.key, descriptor); 6179 }, 6180 decorateClass: function (elements, decorators) { 6181 var newElements = []; 6182 var finishers = []; 6183 var placements = { 6184 static: [], 6185 prototype: [], 6186 own: [] 6187 }; 6188 elements.forEach(function (element) { 6189 this.addElementPlacement(element, placements); 6190 }, this); 6191 elements.forEach(function (element) { 6192 if (!_hasDecorators(element)) return newElements.push(element); 6193 var elementFinishersExtras = this.decorateElement(element, placements); 6194 newElements.push(elementFinishersExtras.element); 6195 newElements.push.apply(newElements, elementFinishersExtras.extras); 6196 finishers.push.apply(finishers, elementFinishersExtras.finishers); 6197 }, this); 6198 if (!decorators) { 6199 return { 6200 elements: newElements, 6201 finishers: finishers 6202 }; 6203 } 6204 var result = this.decorateConstructor(newElements, decorators); 6205 finishers.push.apply(finishers, result.finishers); 6206 result.finishers = finishers; 6207 return result; 6208 }, 6209 addElementPlacement: function (element, placements, silent) { 6210 var keys = placements[element.placement]; 6211 if (!silent && keys.indexOf(element.key) !== -1) { 6212 throw new TypeError("Duplicated element (" + element.key + ")"); 6213 } 6214 keys.push(element.key); 6215 }, 6216 decorateElement: function (element, placements) { 6217 var extras = []; 6218 var finishers = []; 6219 for (var decorators = element.decorators, i = decorators.length - 1; i >= 0; i--) { 6220 var keys = placements[element.placement]; 6221 keys.splice(keys.indexOf(element.key), 1); 6222 var elementObject = this.fromElementDescriptor(element); 6223 var elementFinisherExtras = this.toElementFinisherExtras((0, decorators[i])(elementObject) || elementObject); 6224 element = elementFinisherExtras.element; 6225 this.addElementPlacement(element, placements); 6226 if (elementFinisherExtras.finisher) { 6227 finishers.push(elementFinisherExtras.finisher); 6228 } 6229 var newExtras = elementFinisherExtras.extras; 6230 if (newExtras) { 6231 for (var j = 0; j < newExtras.length; j++) { 6232 this.addElementPlacement(newExtras[j], placements); 6233 } 6234 extras.push.apply(extras, newExtras); 6235 } 6236 } 6237 return { 6238 element: element, 6239 finishers: finishers, 6240 extras: extras 6241 }; 6242 }, 6243 decorateConstructor: function (elements, decorators) { 6244 var finishers = []; 6245 for (var i = decorators.length - 1; i >= 0; i--) { 6246 var obj = this.fromClassDescriptor(elements); 6247 var elementsAndFinisher = this.toClassDescriptor((0, decorators[i])(obj) || obj); 6248 if (elementsAndFinisher.finisher !== undefined) { 6249 finishers.push(elementsAndFinisher.finisher); 6250 } 6251 if (elementsAndFinisher.elements !== undefined) { 6252 elements = elementsAndFinisher.elements; 6253 for (var j = 0; j < elements.length - 1; j++) { 6254 for (var k = j + 1; k < elements.length; k++) { 6255 if (elements[j].key === elements[k].key && elements[j].placement === elements[k].placement) { 6256 throw new TypeError("Duplicated element (" + elements[j].key + ")"); 6257 } 6258 } 6259 } 6260 } 6261 } 6262 return { 6263 elements: elements, 6264 finishers: finishers 6265 }; 6266 }, 6267 fromElementDescriptor: function (element) { 6268 var obj = { 6269 kind: element.kind, 6270 key: element.key, 6271 placement: element.placement, 6272 descriptor: element.descriptor 6273 }; 6274 var desc = { 6275 value: "Descriptor", 6276 configurable: true 6277 }; 6278 Object.defineProperty(obj, Symbol.toStringTag, desc); 6279 if (element.kind === "field") obj.initializer = element.initializer; 6280 return obj; 6281 }, 6282 toElementDescriptors: function (elementObjects) { 6283 if (elementObjects === undefined) return; 6284 return _toArray(elementObjects).map(function (elementObject) { 6285 var element = this.toElementDescriptor(elementObject); 6286 this.disallowProperty(elementObject, "finisher", "An element descriptor"); 6287 this.disallowProperty(elementObject, "extras", "An element descriptor"); 6288 return element; 6289 }, this); 6290 }, 6291 toElementDescriptor: function (elementObject) { 6292 var kind = String(elementObject.kind); 6293 if (kind !== "method" && kind !== "field") { 6294 throw new TypeError('An element descriptor\'s .kind property must be either "method" or' + ' "field", but a decorator created an element descriptor with' + ' .kind "' + kind + '"'); 6295 } 6296 var key = _toPropertyKey(elementObject.key); 6297 var placement = String(elementObject.placement); 6298 if (placement !== "static" && placement !== "prototype" && placement !== "own") { 6299 throw new TypeError('An element descriptor\'s .placement property must be one of "static",' + ' "prototype" or "own", but a decorator created an element descriptor' + ' with .placement "' + placement + '"'); 6300 } 6301 var descriptor = elementObject.descriptor; 6302 this.disallowProperty(elementObject, "elements", "An element descriptor"); 6303 var element = { 6304 kind: kind, 6305 key: key, 6306 placement: placement, 6307 descriptor: Object.assign({}, descriptor) 6308 }; 6309 if (kind !== "field") { 6310 this.disallowProperty(elementObject, "initializer", "A method descriptor"); 6311 } else { 6312 this.disallowProperty(descriptor, "get", "The property descriptor of a field descriptor"); 6313 this.disallowProperty(descriptor, "set", "The property descriptor of a field descriptor"); 6314 this.disallowProperty(descriptor, "value", "The property descriptor of a field descriptor"); 6315 element.initializer = elementObject.initializer; 6316 } 6317 return element; 6318 }, 6319 toElementFinisherExtras: function (elementObject) { 6320 var element = this.toElementDescriptor(elementObject); 6321 var finisher = _optionalCallableProperty(elementObject, "finisher"); 6322 var extras = this.toElementDescriptors(elementObject.extras); 6323 return { 6324 element: element, 6325 finisher: finisher, 6326 extras: extras 6327 }; 6328 }, 6329 fromClassDescriptor: function (elements) { 6330 var obj = { 6331 kind: "class", 6332 elements: elements.map(this.fromElementDescriptor, this) 6333 }; 6334 var desc = { 6335 value: "Descriptor", 6336 configurable: true 6337 }; 6338 Object.defineProperty(obj, Symbol.toStringTag, desc); 6339 return obj; 6340 }, 6341 toClassDescriptor: function (obj) { 6342 var kind = String(obj.kind); 6343 if (kind !== "class") { 6344 throw new TypeError('A class descriptor\'s .kind property must be "class", but a decorator' + ' created a class descriptor with .kind "' + kind + '"'); 6345 } 6346 this.disallowProperty(obj, "key", "A class descriptor"); 6347 this.disallowProperty(obj, "placement", "A class descriptor"); 6348 this.disallowProperty(obj, "descriptor", "A class descriptor"); 6349 this.disallowProperty(obj, "initializer", "A class descriptor"); 6350 this.disallowProperty(obj, "extras", "A class descriptor"); 6351 var finisher = _optionalCallableProperty(obj, "finisher"); 6352 var elements = this.toElementDescriptors(obj.elements); 6353 return { 6354 elements: elements, 6355 finisher: finisher 6356 }; 6357 }, 6358 runClassFinishers: function (constructor, finishers) { 6359 for (var i = 0; i < finishers.length; i++) { 6360 var newConstructor = (0, finishers[i])(constructor); 6361 if (newConstructor !== undefined) { 6362 if (typeof newConstructor !== "function") { 6363 throw new TypeError("Finishers must return a constructor."); 6364 } 6365 constructor = newConstructor; 6366 } 6367 } 6368 return constructor; 6369 }, 6370 disallowProperty: function (obj, name, objectType) { 6371 if (obj[name] !== undefined) { 6372 throw new TypeError(objectType + " can't have a ." + name + " property."); 6373 } 6374 } 6375 }; 6376 return api; 6377 } 6378 function _createElementDescriptor(def) { 6379 var key = _toPropertyKey(def.key); 6380 var descriptor; 6381 if (def.kind === "method") { 6382 descriptor = { 6383 value: def.value, 6384 writable: true, 6385 configurable: true, 6386 enumerable: false 6387 }; 6388 } else if (def.kind === "get") { 6389 descriptor = { 6390 get: def.value, 6391 configurable: true, 6392 enumerable: false 6393 }; 6394 } else if (def.kind === "set") { 6395 descriptor = { 6396 set: def.value, 6397 configurable: true, 6398 enumerable: false 6399 }; 6400 } else if (def.kind === "field") { 6401 descriptor = { 6402 configurable: true, 6403 writable: true, 6404 enumerable: true 6405 }; 6406 } 6407 var element = { 6408 kind: def.kind === "field" ? "field" : "method", 6409 key: key, 6410 placement: def.static ? "static" : def.kind === "field" ? "own" : "prototype", 6411 descriptor: descriptor 6412 }; 6413 if (def.decorators) element.decorators = def.decorators; 6414 if (def.kind === "field") element.initializer = def.value; 6415 return element; 6416 } 6417 function _coalesceGetterSetter(element, other) { 6418 if (element.descriptor.get !== undefined) { 6419 other.descriptor.get = element.descriptor.get; 6420 } else { 6421 other.descriptor.set = element.descriptor.set; 6422 } 6423 } 6424 function _coalesceClassElements(elements) { 6425 var newElements = []; 6426 var isSameElement = function (other) { 6427 return other.kind === "method" && other.key === element.key && other.placement === element.placement; 6428 }; 6429 for (var i = 0; i < elements.length; i++) { 6430 var element = elements[i]; 6431 var other; 6432 if (element.kind === "method" && (other = newElements.find(isSameElement))) { 6433 if (_isDataDescriptor(element.descriptor) || _isDataDescriptor(other.descriptor)) { 6434 if (_hasDecorators(element) || _hasDecorators(other)) { 6435 throw new ReferenceError("Duplicated methods (" + element.key + ") can't be decorated."); 6436 } 6437 other.descriptor = element.descriptor; 6438 } else { 6439 if (_hasDecorators(element)) { 6440 if (_hasDecorators(other)) { 6441 throw new ReferenceError("Decorators can't be placed on different accessors with for " + "the same property (" + element.key + ")."); 6442 } 6443 other.decorators = element.decorators; 6444 } 6445 _coalesceGetterSetter(element, other); 6446 } 6447 } else { 6448 newElements.push(element); 6449 } 6450 } 6451 return newElements; 6452 } 6453 function _hasDecorators(element) { 6454 return element.decorators && element.decorators.length; 6455 } 6456 function _isDataDescriptor(desc) { 6457 return desc !== undefined && !(desc.value === undefined && desc.writable === undefined); 6458 } 6459 function _optionalCallableProperty(obj, name) { 6460 var value = obj[name]; 6461 if (value !== undefined && typeof value !== "function") { 6462 throw new TypeError("Expected '" + name + "' to be a function"); 6463 } 6464 return value; 6465 } 6466 function _classPrivateMethodGet(receiver, privateSet, fn) { 6467 if (!privateSet.has(receiver)) { 6468 throw new TypeError("attempted to get private field on non-instance"); 6469 } 6470 return fn; 6471 } 6472 function _checkPrivateRedeclaration(obj, privateCollection) { 6473 if (privateCollection.has(obj)) { 6474 throw new TypeError("Cannot initialize the same private elements twice on an object"); 6475 } 6476 } 6477 function _classPrivateFieldInitSpec(obj, privateMap, value) { 6478 _checkPrivateRedeclaration(obj, privateMap); 6479 privateMap.set(obj, value); 6480 } 6481 function _classPrivateMethodInitSpec(obj, privateSet) { 6482 _checkPrivateRedeclaration(obj, privateSet); 6483 privateSet.add(obj); 6484 } 6485 function _classPrivateMethodSet() { 6486 throw new TypeError("attempted to reassign private method"); 6487 } 6488 function _identity(x) { 6489 return x; 6490 } 6491 function _nullishReceiverError(r) { 6492 throw new TypeError("Cannot set property of null or undefined."); 6493 } 6494 6495 class Piece extends TrixObject { 6496 static registerType(type, constructor) { 6497 constructor.type = type; 6498 this.types[type] = constructor; 6499 } 6500 static fromJSON(pieceJSON) { 6501 const constructor = this.types[pieceJSON.type]; 6502 if (constructor) { 6503 return constructor.fromJSON(pieceJSON); 6504 } 6505 } 6506 constructor(value) { 6507 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 6508 super(...arguments); 6509 this.attributes = Hash.box(attributes); 6510 } 6511 copyWithAttributes(attributes) { 6512 return new this.constructor(this.getValue(), attributes); 6513 } 6514 copyWithAdditionalAttributes(attributes) { 6515 return this.copyWithAttributes(this.attributes.merge(attributes)); 6516 } 6517 copyWithoutAttribute(attribute) { 6518 return this.copyWithAttributes(this.attributes.remove(attribute)); 6519 } 6520 copy() { 6521 return this.copyWithAttributes(this.attributes); 6522 } 6523 getAttribute(attribute) { 6524 return this.attributes.get(attribute); 6525 } 6526 getAttributesHash() { 6527 return this.attributes; 6528 } 6529 getAttributes() { 6530 return this.attributes.toObject(); 6531 } 6532 hasAttribute(attribute) { 6533 return this.attributes.has(attribute); 6534 } 6535 hasSameStringValueAsPiece(piece) { 6536 return piece && this.toString() === piece.toString(); 6537 } 6538 hasSameAttributesAsPiece(piece) { 6539 return piece && (this.attributes === piece.attributes || this.attributes.isEqualTo(piece.attributes)); 6540 } 6541 isBlockBreak() { 6542 return false; 6543 } 6544 isEqualTo(piece) { 6545 return super.isEqualTo(...arguments) || this.hasSameConstructorAs(piece) && this.hasSameStringValueAsPiece(piece) && this.hasSameAttributesAsPiece(piece); 6546 } 6547 isEmpty() { 6548 return this.length === 0; 6549 } 6550 isSerializable() { 6551 return true; 6552 } 6553 toJSON() { 6554 return { 6555 type: this.constructor.type, 6556 attributes: this.getAttributes() 6557 }; 6558 } 6559 contentsForInspection() { 6560 return { 6561 type: this.constructor.type, 6562 attributes: this.attributes.inspect() 6563 }; 6564 } 6565 6566 // Grouping 6567 6568 canBeGrouped() { 6569 return this.hasAttribute("href"); 6570 } 6571 canBeGroupedWith(piece) { 6572 return this.getAttribute("href") === piece.getAttribute("href"); 6573 } 6574 6575 // Splittable 6576 6577 getLength() { 6578 return this.length; 6579 } 6580 canBeConsolidatedWith(piece) { 6581 return false; 6582 } 6583 } 6584 _defineProperty(Piece, "types", {}); 6585 6586 class ImagePreloadOperation extends Operation { 6587 constructor(url) { 6588 super(...arguments); 6589 this.url = url; 6590 } 6591 perform(callback) { 6592 const image = new Image(); 6593 image.onload = () => { 6594 image.width = this.width = image.naturalWidth; 6595 image.height = this.height = image.naturalHeight; 6596 return callback(true, image); 6597 }; 6598 image.onerror = () => callback(false); 6599 image.src = this.url; 6600 } 6601 } 6602 6603 class Attachment extends TrixObject { 6604 static attachmentForFile(file) { 6605 const attributes = this.attributesForFile(file); 6606 const attachment = new this(attributes); 6607 attachment.setFile(file); 6608 return attachment; 6609 } 6610 static attributesForFile(file) { 6611 return new Hash({ 6612 filename: file.name, 6613 filesize: file.size, 6614 contentType: file.type 6615 }); 6616 } 6617 static fromJSON(attachmentJSON) { 6618 return new this(attachmentJSON); 6619 } 6620 constructor() { 6621 let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 6622 super(attributes); 6623 this.releaseFile = this.releaseFile.bind(this); 6624 this.attributes = Hash.box(attributes); 6625 this.didChangeAttributes(); 6626 } 6627 setAttribute(attribute, value) { 6628 this.setAttributes({ 6629 [attribute]: value 6630 }); 6631 } 6632 getAttribute(attribute) { 6633 return this.attributes.get(attribute); 6634 } 6635 hasAttribute(attribute) { 6636 return this.attributes.has(attribute); 6637 } 6638 getAttributes() { 6639 return this.attributes.toObject(); 6640 } 6641 setAttributes() { 6642 let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 6643 const newAttributes = this.attributes.merge(attributes); 6644 if (!this.attributes.isEqualTo(newAttributes)) { 6645 var _this$previewDelegate, _this$previewDelegate2, _this$delegate, _this$delegate$attach; 6646 this.attributes = newAttributes; 6647 this.didChangeAttributes(); 6648 (_this$previewDelegate = this.previewDelegate) === null || _this$previewDelegate === void 0 || (_this$previewDelegate2 = _this$previewDelegate.attachmentDidChangeAttributes) === null || _this$previewDelegate2 === void 0 || _this$previewDelegate2.call(_this$previewDelegate, this); 6649 return (_this$delegate = this.delegate) === null || _this$delegate === void 0 || (_this$delegate$attach = _this$delegate.attachmentDidChangeAttributes) === null || _this$delegate$attach === void 0 ? void 0 : _this$delegate$attach.call(_this$delegate, this); 6650 } 6651 } 6652 didChangeAttributes() { 6653 if (this.isPreviewable()) { 6654 return this.preloadURL(); 6655 } 6656 } 6657 isPending() { 6658 return this.file != null && !(this.getURL() || this.getHref()); 6659 } 6660 isPreviewable() { 6661 if (this.attributes.has("previewable")) { 6662 return this.attributes.get("previewable"); 6663 } else { 6664 return Attachment.previewablePattern.test(this.getContentType()); 6665 } 6666 } 6667 getType() { 6668 if (this.hasContent()) { 6669 return "content"; 6670 } else if (this.isPreviewable()) { 6671 return "preview"; 6672 } else { 6673 return "file"; 6674 } 6675 } 6676 getURL() { 6677 return this.attributes.get("url"); 6678 } 6679 getHref() { 6680 return this.attributes.get("href"); 6681 } 6682 getFilename() { 6683 return this.attributes.get("filename") || ""; 6684 } 6685 getFilesize() { 6686 return this.attributes.get("filesize"); 6687 } 6688 getFormattedFilesize() { 6689 const filesize = this.attributes.get("filesize"); 6690 if (typeof filesize === "number") { 6691 return file_size_formatting.formatter(filesize); 6692 } else { 6693 return ""; 6694 } 6695 } 6696 getExtension() { 6697 var _this$getFilename$mat; 6698 return (_this$getFilename$mat = this.getFilename().match(/\.(\w+)$/)) === null || _this$getFilename$mat === void 0 ? void 0 : _this$getFilename$mat[1].toLowerCase(); 6699 } 6700 getContentType() { 6701 return this.attributes.get("contentType"); 6702 } 6703 hasContent() { 6704 return this.attributes.has("content"); 6705 } 6706 getContent() { 6707 return this.attributes.get("content"); 6708 } 6709 getWidth() { 6710 return this.attributes.get("width"); 6711 } 6712 getHeight() { 6713 return this.attributes.get("height"); 6714 } 6715 getFile() { 6716 return this.file; 6717 } 6718 setFile(file) { 6719 this.file = file; 6720 if (this.isPreviewable()) { 6721 return this.preloadFile(); 6722 } 6723 } 6724 releaseFile() { 6725 this.releasePreloadedFile(); 6726 this.file = null; 6727 } 6728 getUploadProgress() { 6729 return this.uploadProgress != null ? this.uploadProgress : 0; 6730 } 6731 setUploadProgress(value) { 6732 if (this.uploadProgress !== value) { 6733 var _this$uploadProgressD, _this$uploadProgressD2; 6734 this.uploadProgress = value; 6735 return (_this$uploadProgressD = this.uploadProgressDelegate) === null || _this$uploadProgressD === void 0 || (_this$uploadProgressD2 = _this$uploadProgressD.attachmentDidChangeUploadProgress) === null || _this$uploadProgressD2 === void 0 ? void 0 : _this$uploadProgressD2.call(_this$uploadProgressD, this); 6736 } 6737 } 6738 toJSON() { 6739 return this.getAttributes(); 6740 } 6741 getCacheKey() { 6742 return [super.getCacheKey(...arguments), this.attributes.getCacheKey(), this.getPreviewURL()].join("/"); 6743 } 6744 6745 // Previewable 6746 6747 getPreviewURL() { 6748 return this.previewURL || this.preloadingURL; 6749 } 6750 setPreviewURL(url) { 6751 if (url !== this.getPreviewURL()) { 6752 var _this$previewDelegate3, _this$previewDelegate4, _this$delegate2, _this$delegate2$attac; 6753 this.previewURL = url; 6754 (_this$previewDelegate3 = this.previewDelegate) === null || _this$previewDelegate3 === void 0 || (_this$previewDelegate4 = _this$previewDelegate3.attachmentDidChangeAttributes) === null || _this$previewDelegate4 === void 0 || _this$previewDelegate4.call(_this$previewDelegate3, this); 6755 return (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || (_this$delegate2$attac = _this$delegate2.attachmentDidChangePreviewURL) === null || _this$delegate2$attac === void 0 ? void 0 : _this$delegate2$attac.call(_this$delegate2, this); 6756 } 6757 } 6758 preloadURL() { 6759 return this.preload(this.getURL(), this.releaseFile); 6760 } 6761 preloadFile() { 6762 if (this.file) { 6763 this.fileObjectURL = URL.createObjectURL(this.file); 6764 return this.preload(this.fileObjectURL); 6765 } 6766 } 6767 releasePreloadedFile() { 6768 if (this.fileObjectURL) { 6769 URL.revokeObjectURL(this.fileObjectURL); 6770 this.fileObjectURL = null; 6771 } 6772 } 6773 preload(url, callback) { 6774 if (url && url !== this.getPreviewURL()) { 6775 this.preloadingURL = url; 6776 const operation = new ImagePreloadOperation(url); 6777 return operation.then(_ref => { 6778 let { 6779 width, 6780 height 6781 } = _ref; 6782 if (!this.getWidth() || !this.getHeight()) { 6783 this.setAttributes({ 6784 width, 6785 height 6786 }); 6787 } 6788 this.preloadingURL = null; 6789 this.setPreviewURL(url); 6790 return callback === null || callback === void 0 ? void 0 : callback(); 6791 }).catch(() => { 6792 this.preloadingURL = null; 6793 return callback === null || callback === void 0 ? void 0 : callback(); 6794 }); 6795 } 6796 } 6797 } 6798 _defineProperty(Attachment, "previewablePattern", /^image(\/(gif|png|webp|jpe?g)|$)/); 6799 6800 class AttachmentPiece extends Piece { 6801 static fromJSON(pieceJSON) { 6802 return new this(Attachment.fromJSON(pieceJSON.attachment), pieceJSON.attributes); 6803 } 6804 constructor(attachment) { 6805 super(...arguments); 6806 this.attachment = attachment; 6807 this.length = 1; 6808 this.ensureAttachmentExclusivelyHasAttribute("href"); 6809 if (!this.attachment.hasContent()) { 6810 this.removeProhibitedAttributes(); 6811 } 6812 } 6813 ensureAttachmentExclusivelyHasAttribute(attribute) { 6814 if (this.hasAttribute(attribute)) { 6815 if (!this.attachment.hasAttribute(attribute)) { 6816 this.attachment.setAttributes(this.attributes.slice([attribute])); 6817 } 6818 this.attributes = this.attributes.remove(attribute); 6819 } 6820 } 6821 removeProhibitedAttributes() { 6822 const attributes = this.attributes.slice(AttachmentPiece.permittedAttributes); 6823 if (!attributes.isEqualTo(this.attributes)) { 6824 this.attributes = attributes; 6825 } 6826 } 6827 getValue() { 6828 return this.attachment; 6829 } 6830 isSerializable() { 6831 return !this.attachment.isPending(); 6832 } 6833 getCaption() { 6834 return this.attributes.get("caption") || ""; 6835 } 6836 isEqualTo(piece) { 6837 var _piece$attachment; 6838 return super.isEqualTo(piece) && this.attachment.id === (piece === null || piece === void 0 || (_piece$attachment = piece.attachment) === null || _piece$attachment === void 0 ? void 0 : _piece$attachment.id); 6839 } 6840 toString() { 6841 return OBJECT_REPLACEMENT_CHARACTER; 6842 } 6843 toJSON() { 6844 const json = super.toJSON(...arguments); 6845 json.attachment = this.attachment; 6846 return json; 6847 } 6848 getCacheKey() { 6849 return [super.getCacheKey(...arguments), this.attachment.getCacheKey()].join("/"); 6850 } 6851 toConsole() { 6852 return JSON.stringify(this.toString()); 6853 } 6854 } 6855 _defineProperty(AttachmentPiece, "permittedAttributes", ["caption", "presentation"]); 6856 Piece.registerType("attachment", AttachmentPiece); 6857 6858 class StringPiece extends Piece { 6859 static fromJSON(pieceJSON) { 6860
6860return new this(pieceJSON.string, pieceJSON.
vendor: 264,607 bytes, lines 6860-13866
6860attributes); 6861 } 6862 constructor(string) { 6863 super(...arguments); 6864 this.string = normalizeNewlines(string); 6865 this.length = this.string.length; 6866 } 6867 getValue() { 6868 return this.string; 6869 } 6870 toString() { 6871 return this.string.toString(); 6872 } 6873 isBlockBreak() { 6874 return this.toString() === "\n" && this.getAttribute("blockBreak") === true; 6875 } 6876 toJSON() { 6877 const result = super.toJSON(...arguments); 6878 result.string = this.string; 6879 return result; 6880 } 6881 6882 // Splittable 6883 6884 canBeConsolidatedWith(piece) { 6885 return piece && this.hasSameConstructorAs(piece) && this.hasSameAttributesAsPiece(piece); 6886 } 6887 consolidateWith(piece) { 6888 return new this.constructor(this.toString() + piece.toString(), this.attributes); 6889 } 6890 splitAtOffset(offset) { 6891 let left, right; 6892 if (offset === 0) { 6893 left = null; 6894 right = this; 6895 } else if (offset === this.length) { 6896 left = this; 6897 right = null; 6898 } else { 6899 left = new this.constructor(this.string.slice(0, offset), this.attributes); 6900 right = new this.constructor(this.string.slice(offset), this.attributes); 6901 } 6902 return [left, right]; 6903 } 6904 toConsole() { 6905 let { 6906 string 6907 } = this; 6908 if (string.length > 15) { 6909 string = string.slice(0, 14) + "â¦"; 6910 } 6911 return JSON.stringify(string.toString()); 6912 } 6913 } 6914 Piece.registerType("string", StringPiece); 6915 6916 /* eslint-disable 6917 prefer-const, 6918 */ 6919 class SplittableList extends TrixObject { 6920 static box(objects) { 6921 if (objects instanceof this) { 6922 return objects; 6923 } else { 6924 return new this(objects); 6925 } 6926 } 6927 constructor() { 6928 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 6929 super(...arguments); 6930 this.objects = objects.slice(0); 6931 this.length = this.objects.length; 6932 } 6933 indexOf(object) { 6934 return this.objects.indexOf(object); 6935 } 6936 splice() { 6937 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 6938 args[_key] = arguments[_key]; 6939 } 6940 return new this.constructor(spliceArray(this.objects, ...args)); 6941 } 6942 eachObject(callback) { 6943 return this.objects.map((object, index) => callback(object, index)); 6944 } 6945 insertObjectAtIndex(object, index) { 6946 return this.splice(index, 0, object); 6947 } 6948 insertSplittableListAtIndex(splittableList, index) { 6949 return this.splice(index, 0, ...splittableList.objects); 6950 } 6951 insertSplittableListAtPosition(splittableList, position) { 6952 const [objects, index] = this.splitObjectAtPosition(position); 6953 return new this.constructor(objects).insertSplittableListAtIndex(splittableList, index); 6954 } 6955 editObjectAtIndex(index, callback) { 6956 return this.replaceObjectAtIndex(callback(this.objects[index]), index); 6957 } 6958 replaceObjectAtIndex(object, index) { 6959 return this.splice(index, 1, object); 6960 } 6961 removeObjectAtIndex(index) { 6962 return this.splice(index, 1); 6963 } 6964 getObjectAtIndex(index) { 6965 return this.objects[index]; 6966 } 6967 getSplittableListInRange(range) { 6968 const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range); 6969 return new this.constructor(objects.slice(leftIndex, rightIndex + 1)); 6970 } 6971 selectSplittableList(test) { 6972 const objects = this.objects.filter(object => test(object)); 6973 return new this.constructor(objects); 6974 } 6975 removeObjectsInRange(range) { 6976 const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range); 6977 return new this.constructor(objects).splice(leftIndex, rightIndex - leftIndex + 1); 6978 } 6979 transformObjectsInRange(range, transform) { 6980 const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range); 6981 const transformedObjects = objects.map((object, index) => leftIndex <= index && index <= rightIndex ? transform(object) : object); 6982 return new this.constructor(transformedObjects); 6983 } 6984 splitObjectsAtRange(range) { 6985 let rightOuterIndex; 6986 let [objects, leftInnerIndex, offset] = this.splitObjectAtPosition(startOfRange(range)); 6987 [objects, rightOuterIndex] = new this.constructor(objects).splitObjectAtPosition(endOfRange(range) + offset); 6988 return [objects, leftInnerIndex, rightOuterIndex - 1]; 6989 } 6990 getObjectAtPosition(position) { 6991 const { 6992 index 6993 } = this.findIndexAndOffsetAtPosition(position); 6994 return this.objects[index]; 6995 } 6996 splitObjectAtPosition(position) { 6997 let splitIndex, splitOffset; 6998 const { 6999 index, 7000 offset 7001 } = this.findIndexAndOffsetAtPosition(position); 7002 const objects = this.objects.slice(0); 7003 if (index != null) { 7004 if (offset === 0) { 7005 splitIndex = index; 7006 splitOffset = 0; 7007 } else { 7008 const object = this.getObjectAtIndex(index); 7009 const [leftObject, rightObject] = object.splitAtOffset(offset); 7010 objects.splice(index, 1, leftObject, rightObject); 7011 splitIndex = index + 1; 7012 splitOffset = leftObject.getLength() - offset; 7013 } 7014 } else { 7015 splitIndex = objects.length; 7016 splitOffset = 0; 7017 } 7018 return [objects, splitIndex, splitOffset]; 7019 } 7020 consolidate() { 7021 const objects = []; 7022 let pendingObject = this.objects[0]; 7023 this.objects.slice(1).forEach(object => { 7024 var _pendingObject$canBeC, _pendingObject; 7025 if ((_pendingObject$canBeC = (_pendingObject = pendingObject).canBeConsolidatedWith) !== null && _pendingObject$canBeC !== void 0 && _pendingObject$canBeC.call(_pendingObject, object)) { 7026 pendingObject = pendingObject.consolidateWith(object); 7027 } else { 7028 objects.push(pendingObject); 7029 pendingObject = object; 7030 } 7031 }); 7032 if (pendingObject) { 7033 objects.push(pendingObject); 7034 } 7035 return new this.constructor(objects); 7036 } 7037 consolidateFromIndexToIndex(startIndex, endIndex) { 7038 const objects = this.objects.slice(0); 7039 const objectsInRange = objects.slice(startIndex, endIndex + 1); 7040 const consolidatedInRange = new this.constructor(objectsInRange).consolidate().toArray(); 7041 return this.splice(startIndex, objectsInRange.length, ...consolidatedInRange); 7042 } 7043 findIndexAndOffsetAtPosition(position) { 7044 let index; 7045 let currentPosition = 0; 7046 for (index = 0; index < this.objects.length; index++) { 7047 const object = this.objects[index]; 7048 const nextPosition = currentPosition + object.getLength(); 7049 if (currentPosition <= position && position < nextPosition) { 7050 return { 7051 index, 7052 offset: position - currentPosition 7053 }; 7054 } 7055 currentPosition = nextPosition; 7056 } 7057 return { 7058 index: null, 7059 offset: null 7060 }; 7061 } 7062 findPositionAtIndexAndOffset(index, offset) { 7063 let position = 0; 7064 for (let currentIndex = 0; currentIndex < this.objects.length; currentIndex++) { 7065 const object = this.objects[currentIndex]; 7066 if (currentIndex < index) { 7067 position += object.getLength(); 7068 } else if (currentIndex === index) { 7069 position += offset; 7070 break; 7071 } 7072 } 7073 return position; 7074 } 7075 getEndPosition() { 7076 if (this.endPosition == null) { 7077 this.endPosition = 0; 7078 this.objects.forEach(object => this.endPosition += object.getLength()); 7079 } 7080 return this.endPosition; 7081 } 7082 toString() { 7083 return this.objects.join(""); 7084 } 7085 toArray() { 7086 return this.objects.slice(0); 7087 } 7088 toJSON() { 7089 return this.toArray(); 7090 } 7091 isEqualTo(splittableList) { 7092 return super.isEqualTo(...arguments) || objectArraysAreEqual(this.objects, splittableList === null || splittableList === void 0 ? void 0 : splittableList.objects); 7093 } 7094 contentsForInspection() { 7095 return { 7096 objects: "[".concat(this.objects.map(object => object.inspect()).join(", "), "]") 7097 }; 7098 } 7099 } 7100 const objectArraysAreEqual = function (left) { 7101 let right = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 7102 if (left.length !== right.length) { 7103 return false; 7104 } 7105 let result = true; 7106 for (let index = 0; index < left.length; index++) { 7107 const object = left[index]; 7108 if (result && !object.isEqualTo(right[index])) { 7109 result = false; 7110 } 7111 } 7112 return result; 7113 }; 7114 const startOfRange = range => range[0]; 7115 const endOfRange = range => range[1]; 7116 7117 class Text extends TrixObject { 7118 static textForAttachmentWithAttributes(attachment, attributes) { 7119 const piece = new AttachmentPiece(attachment, attributes); 7120 return new this([piece]); 7121 } 7122 static textForStringWithAttributes(string, attributes) { 7123 const piece = new StringPiece(string, attributes); 7124 return new this([piece]); 7125 } 7126 static fromJSON(textJSON) { 7127 const pieces = Array.from(textJSON).map(pieceJSON => Piece.fromJSON(pieceJSON)); 7128 return new this(pieces); 7129 } 7130 constructor() { 7131 let pieces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 7132 super(...arguments); 7133 const notEmpty = pieces.filter(piece => !piece.isEmpty()); 7134 this.pieceList = new SplittableList(notEmpty); 7135 } 7136 copy() { 7137 return this.copyWithPieceList(this.pieceList); 7138 } 7139 copyWithPieceList(pieceList) { 7140 return new this.constructor(pieceList.consolidate().toArray()); 7141 } 7142 copyUsingObjectMap(objectMap) { 7143 const pieces = this.getPieces().map(piece => objectMap.find(piece) || piece); 7144 return new this.constructor(pieces); 7145 } 7146 appendText(text) { 7147 return this.insertTextAtPosition(text, this.getLength()); 7148 } 7149 insertTextAtPosition(text, position) { 7150 return this.copyWithPieceList(this.pieceList.insertSplittableListAtPosition(text.pieceList, position)); 7151 } 7152 removeTextAtRange(range) { 7153 return this.copyWithPieceList(this.pieceList.removeObjectsInRange(range)); 7154 } 7155 replaceTextAtRange(text, range) { 7156 return this.removeTextAtRange(range).insertTextAtPosition(text, range[0]); 7157 } 7158 moveTextFromRangeToPosition(range, position) { 7159 if (range[0] <= position && position <= range[1]) return; 7160 const text = this.getTextAtRange(range); 7161 const length = text.getLength(); 7162 if (range[0] < position) { 7163 position -= length; 7164 } 7165 return this.removeTextAtRange(range).insertTextAtPosition(text, position); 7166 } 7167 addAttributeAtRange(attribute, value, range) { 7168 const attributes = {}; 7169 attributes[attribute] = value; 7170 return this.addAttributesAtRange(attributes, range); 7171 } 7172 addAttributesAtRange(attributes, range) { 7173 return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithAdditionalAttributes(attributes))); 7174 } 7175 removeAttributeAtRange(attribute, range) { 7176 return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithoutAttribute(attribute))); 7177 } 7178 setAttributesAtRange(attributes, range) { 7179 return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithAttributes(attributes))); 7180 } 7181 getAttributesAtPosition(position) { 7182 var _this$pieceList$getOb; 7183 return ((_this$pieceList$getOb = this.pieceList.getObjectAtPosition(position)) === null || _this$pieceList$getOb === void 0 ? void 0 : _this$pieceList$getOb.getAttributes()) || {}; 7184 } 7185 getCommonAttributes() { 7186 const objects = Array.from(this.pieceList.toArray()).map(piece => piece.getAttributes()); 7187 return Hash.fromCommonAttributesOfObjects(objects).toObject(); 7188 } 7189 getCommonAttributesAtRange(range) { 7190 return this.getTextAtRange(range).getCommonAttributes() || {}; 7191 } 7192 getExpandedRangeForAttributeAtOffset(attributeName, offset) { 7193 let right; 7194 let left = right = offset; 7195 const length = this.getLength(); 7196 while (left > 0 && this.getCommonAttributesAtRange([left - 1, right])[attributeName]) { 7197 left--; 7198 } 7199 while (right < length && this.getCommonAttributesAtRange([offset, right + 1])[attributeName]) { 7200 right++; 7201 } 7202 return [left, right]; 7203 } 7204 getTextAtRange(range) { 7205 return this.copyWithPieceList(this.pieceList.getSplittableListInRange(range)); 7206 } 7207 getStringAtRange(range) { 7208 return this.pieceList.getSplittableListInRange(range).toString(); 7209 } 7210 getStringAtPosition(position) { 7211 return this.getStringAtRange([position, position + 1]); 7212 } 7213 startsWithString(string) { 7214 return this.getStringAtRange([0, string.length]) === string; 7215 } 7216 endsWithString(string) { 7217 const length = this.getLength(); 7218 return this.getStringAtRange([length - string.length, length]) === string; 7219 } 7220 getAttachmentPieces() { 7221 return this.pieceList.toArray().filter(piece => !!piece.attachment); 7222 } 7223 getAttachments() { 7224 return this.getAttachmentPieces().map(piece => piece.attachment); 7225 } 7226 getAttachmentAndPositionById(attachmentId) { 7227 let position = 0; 7228 for (const piece of this.pieceList.toArray()) { 7229 var _piece$attachment; 7230 if (((_piece$attachment = piece.attachment) === null || _piece$attachment === void 0 ? void 0 : _piece$attachment.id) === attachmentId) { 7231 return { 7232 attachment: piece.attachment, 7233 position 7234 }; 7235 } 7236 position += piece.length; 7237 } 7238 return { 7239 attachment: null, 7240 position: null 7241 }; 7242 } 7243 getAttachmentById(attachmentId) { 7244 const { 7245 attachment 7246 } = this.getAttachmentAndPositionById(attachmentId); 7247 return attachment; 7248 } 7249 getRangeOfAttachment(attachment) { 7250 const attachmentAndPosition = this.getAttachmentAndPositionById(attachment.id); 7251 const position = attachmentAndPosition.position; 7252 attachment = attachmentAndPosition.attachment; 7253 if (attachment) { 7254 return [position, position + 1]; 7255 } 7256 } 7257 updateAttributesForAttachment(attributes, attachment) { 7258 const range = this.getRangeOfAttachment(attachment); 7259 if (range) { 7260 return this.addAttributesAtRange(attributes, range); 7261 } else { 7262 return this; 7263 } 7264 } 7265 getLength() { 7266 return this.pieceList.getEndPosition(); 7267 } 7268 isEmpty() { 7269 return this.getLength() === 0; 7270 } 7271 isEqualTo(text) { 7272 var _text$pieceList; 7273 return super.isEqualTo(text) || (text === null || text === void 0 || (_text$pieceList = text.pieceList) === null || _text$pieceList === void 0 ? void 0 : _text$pieceList.isEqualTo(this.pieceList)); 7274 } 7275 isBlockBreak() { 7276 return this.getLength() === 1 && this.pieceList.getObjectAtIndex(0).isBlockBreak(); 7277 } 7278 eachPiece(callback) { 7279 return this.pieceList.eachObject(callback); 7280 } 7281 getPieces() { 7282 return this.pieceList.toArray(); 7283 } 7284 getPieceAtPosition(position) { 7285 return this.pieceList.getObjectAtPosition(position); 7286 } 7287 contentsForInspection() { 7288 return { 7289 pieceList: this.pieceList.inspect() 7290 }; 7291 } 7292 toSerializableText() { 7293 const pieceList = this.pieceList.selectSplittableList(piece => piece.isSerializable()); 7294 return this.copyWithPieceList(pieceList); 7295 } 7296 toString() { 7297 return this.pieceList.toString(); 7298 } 7299 toJSON() { 7300 return this.pieceList.toJSON(); 7301 } 7302 toConsole() { 7303 return JSON.stringify(this.pieceList.toArray().map(piece => JSON.parse(piece.toConsole()))); 7304 } 7305 7306 // BIDI 7307 7308 getDirection() { 7309 return getDirection(this.toString()); 7310 } 7311 isRTL() { 7312 return this.getDirection() === "rtl"; 7313 } 7314 } 7315 7316 class Block extends TrixObject { 7317 static fromJSON(blockJSON) { 7318 const text = Text.fromJSON(blockJSON.text); 7319 return new this(text, blockJSON.attributes, blockJSON.htmlAttributes); 7320 } 7321 constructor(text, attributes, htmlAttributes) { 7322 super(...arguments); 7323 this.text = applyBlockBreakToText(text || new Text()); 7324 this.attributes = attributes || []; 7325 this.htmlAttributes = htmlAttributes || {}; 7326 } 7327 isEmpty() { 7328 return this.text.isBlockBreak(); 7329 } 7330 isEqualTo(block) { 7331 if (super.isEqualTo(block)) return true; 7332 return this.text.isEqualTo(block === null || block === void 0 ? void 0 : block.text) && arraysAreEqual(this.attributes, block === null || block === void 0 ? void 0 : block.attributes) && objectsAreEqual(this.htmlAttributes, block === null || block === void 0 ? void 0 : block.htmlAttributes); 7333 } 7334 copyWithText(text) { 7335 return new Block(text, this.attributes, this.htmlAttributes); 7336 } 7337 copyWithoutText() { 7338 return this.copyWithText(null); 7339 } 7340 copyWithAttributes(attributes) { 7341 return new Block(this.text, attributes, this.htmlAttributes); 7342 } 7343 copyWithoutAttributes() { 7344 return this.copyWithAttributes(null); 7345 } 7346 copyUsingObjectMap(objectMap) { 7347 const mappedText = objectMap.find(this.text); 7348 if (mappedText) { 7349 return this.copyWithText(mappedText); 7350 } else { 7351 return this.copyWithText(this.text.copyUsingObjectMap(objectMap)); 7352 } 7353 } 7354 addAttribute(attribute) { 7355 const attributes = this.attributes.concat(expandAttribute(attribute)); 7356 return this.copyWithAttributes(attributes); 7357 } 7358 addHTMLAttribute(attribute, value) { 7359 const htmlAttributes = Object.assign({}, this.htmlAttributes, { 7360 [attribute]: value 7361 }); 7362 return new Block(this.text, this.attributes, htmlAttributes); 7363 } 7364 removeAttribute(attribute) { 7365 const { 7366 listAttribute 7367 } = getBlockConfig(attribute); 7368 const attributes = removeLastValue(removeLastValue(this.attributes, attribute), listAttribute); 7369 return this.copyWithAttributes(attributes); 7370 } 7371 removeLastAttribute() { 7372 return this.removeAttribute(this.getLastAttribute()); 7373 } 7374 getLastAttribute() { 7375 return getLastElement(this.attributes); 7376 } 7377 getAttributes() { 7378 return this.attributes.slice(0); 7379 } 7380 getAttributeLevel() { 7381 return this.attributes.length; 7382 } 7383 getAttributeAtLevel(level) { 7384 return this.attributes[level - 1]; 7385 } 7386 hasAttribute(attributeName) { 7387 return this.attributes.includes(attributeName); 7388 } 7389 hasAttributes() { 7390 return this.getAttributeLevel() > 0; 7391 } 7392 getLastNestableAttribute() { 7393 return getLastElement(this.getNestableAttributes()); 7394 } 7395 getNestableAttributes() { 7396 return this.attributes.filter(attribute => getBlockConfig(attribute).nestable); 7397 } 7398 getNestingLevel() { 7399 return this.getNestableAttributes().length; 7400 } 7401 decreaseNestingLevel() { 7402 const attribute = this.getLastNestableAttribute(); 7403 if (attribute) { 7404 return this.removeAttribute(attribute); 7405 } else { 7406 return this; 7407 } 7408 } 7409 increaseNestingLevel() { 7410 const attribute = this.getLastNestableAttribute(); 7411 if (attribute) { 7412 const index = this.attributes.lastIndexOf(attribute); 7413 const attributes = spliceArray(this.attributes, index + 1, 0, ...expandAttribute(attribute)); 7414 return this.copyWithAttributes(attributes); 7415 } else { 7416 return this; 7417 } 7418 } 7419 getListItemAttributes() { 7420 return this.attributes.filter(attribute => getBlockConfig(attribute).listAttribute); 7421 } 7422 isListItem() { 7423 var _getBlockConfig; 7424 return (_getBlockConfig = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.listAttribute; 7425 } 7426 isTerminalBlock() { 7427 var _getBlockConfig2; 7428 return (_getBlockConfig2 = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig2 === void 0 ? void 0 : _getBlockConfig2.terminal; 7429 } 7430 breaksOnReturn() { 7431 var _getBlockConfig3; 7432 return (_getBlockConfig3 = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig3 === void 0 ? void 0 : _getBlockConfig3.breakOnReturn; 7433 } 7434 findLineBreakInDirectionFromPosition(direction, position) { 7435 const string = this.toString(); 7436 let result; 7437 switch (direction) { 7438 case "forward": 7439 result = string.indexOf("\n", position); 7440 break; 7441 case "backward": 7442 result = string.slice(0, position).lastIndexOf("\n"); 7443 } 7444 if (result !== -1) { 7445 return result; 7446 } 7447 } 7448 contentsForInspection() { 7449 return { 7450 text: this.text.inspect(), 7451 attributes: this.attributes 7452 }; 7453 } 7454 toString() { 7455 return this.text.toString(); 7456 } 7457 toJSON() { 7458 return { 7459 text: this.text, 7460 attributes: this.attributes, 7461 htmlAttributes: this.htmlAttributes 7462 }; 7463 } 7464 7465 // BIDI 7466 7467 getDirection() { 7468 return this.text.getDirection(); 7469 } 7470 isRTL() { 7471 return this.text.isRTL(); 7472 } 7473 7474 // Splittable 7475 7476 getLength() { 7477 return this.text.getLength(); 7478 } 7479 canBeConsolidatedWith(block) { 7480 return !this.hasAttributes() && !block.hasAttributes() && this.getDirection() === block.getDirection(); 7481 } 7482 consolidateWith(block) { 7483 const newlineText = Text.textForStringWithAttributes("\n"); 7484 const text = this.getTextWithoutBlockBreak().appendText(newlineText); 7485 return this.copyWithText(text.appendText(block.text)); 7486 } 7487 splitAtOffset(offset) { 7488 let left, right; 7489 if (offset === 0) { 7490 left = null; 7491 right = this; 7492 } else if (offset === this.getLength()) { 7493 left = this; 7494 right = null; 7495 } else { 7496 left = this.copyWithText(this.text.getTextAtRange([0, offset])); 7497 right = this.copyWithText(this.text.getTextAtRange([offset, this.getLength()])); 7498 } 7499 return [left, right]; 7500 } 7501 getBlockBreakPosition() { 7502 return this.text.getLength() - 1; 7503 } 7504 getTextWithoutBlockBreak() { 7505 if (textEndsInBlockBreak(this.text)) { 7506 return this.text.getTextAtRange([0, this.getBlockBreakPosition()]); 7507 } else { 7508 return this.text.copy(); 7509 } 7510 } 7511 7512 // Grouping 7513 7514 canBeGrouped(depth) { 7515 return this.attributes[depth]; 7516 } 7517 canBeGroupedWith(otherBlock, depth) { 7518 const otherAttributes = otherBlock.getAttributes(); 7519 const otherAttribute = otherAttributes[depth]; 7520 const attribute = this.attributes[depth]; 7521 return attribute === otherAttribute && !(getBlockConfig(attribute).group === false && !getListAttributeNames().includes(otherAttributes[depth + 1])) && (this.getDirection() === otherBlock.getDirection() || otherBlock.isEmpty()); 7522 } 7523 } 7524 7525 // Block breaks 7526 7527 const applyBlockBreakToText = function (text) { 7528 text = unmarkExistingInnerBlockBreaksInText(text); 7529 text = addBlockBreakToText(text); 7530 return text; 7531 }; 7532 const unmarkExistingInnerBlockBreaksInText = function (text) { 7533 let modified = false; 7534 const pieces = text.getPieces(); 7535 let innerPieces = pieces.slice(0, pieces.length - 1); 7536 const lastPiece = pieces[pieces.length - 1]; 7537 if (!lastPiece) return text; 7538 innerPieces = innerPieces.map(piece => { 7539 if (piece.isBlockBreak()) { 7540 modified = true; 7541 return unmarkBlockBreakPiece(piece); 7542 } else { 7543 return piece; 7544 } 7545 }); 7546 if (modified) { 7547 return new Text([...innerPieces, lastPiece]); 7548 } else { 7549 return text; 7550 } 7551 }; 7552 const blockBreakText = Text.textForStringWithAttributes("\n", { 7553 blockBreak: true 7554 }); 7555 const addBlockBreakToText = function (text) { 7556 if (textEndsInBlockBreak(text)) { 7557 return text; 7558 } else { 7559 return text.appendText(blockBreakText); 7560 } 7561 }; 7562 const textEndsInBlockBreak = function (text) { 7563 const length = text.getLength(); 7564 if (length === 0) { 7565 return false; 7566 } 7567 const endText = text.getTextAtRange([length - 1, length]); 7568 return endText.isBlockBreak(); 7569 }; 7570 const unmarkBlockBreakPiece = piece => piece.copyWithoutAttribute("blockBreak"); 7571 7572 // Attributes 7573 7574 const expandAttribute = function (attribute) { 7575 const { 7576 listAttribute 7577 } = getBlockConfig(attribute); 7578 if (listAttribute) { 7579 return [listAttribute, attribute]; 7580 } else { 7581 return [attribute]; 7582 } 7583 }; 7584 7585 // Array helpers 7586 7587 const getLastElement = array => array.slice(-1)[0]; 7588 const removeLastValue = function (array, value) { 7589 const index = array.lastIndexOf(value); 7590 if (index === -1) { 7591 return array; 7592 } else { 7593 return spliceArray(array, index, 1); 7594 } 7595 }; 7596 7597 class Document extends TrixObject { 7598 static fromJSON(documentJSON) { 7599 const blocks = Array.from(documentJSON).map(blockJSON => Block.fromJSON(blockJSON)); 7600 return new this(blocks); 7601 } 7602 static fromString(string, textAttributes) { 7603 const text = Text.textForStringWithAttributes(string, textAttributes); 7604 return new this([new Block(text)]); 7605 } 7606 constructor() { 7607 let blocks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 7608 super(...arguments); 7609 if (blocks.length === 0) { 7610 blocks = [new Block()]; 7611 } 7612 this.blockList = SplittableList.box(blocks); 7613 } 7614 isEmpty() { 7615 const block = this.getBlockAtIndex(0); 7616 return this.blockList.length === 1 && block.isEmpty() && !block.hasAttributes(); 7617 } 7618 copy() { 7619 let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 7620 const blocks = options.consolidateBlocks ? this.blockList.consolidate().toArray() : this.blockList.toArray(); 7621 return new this.constructor(blocks); 7622 } 7623 copyUsingObjectsFromDocument(sourceDocument) { 7624 const objectMap = new ObjectMap(sourceDocument.getObjects()); 7625 return this.copyUsingObjectMap(objectMap); 7626 } 7627 copyUsingObjectMap(objectMap) { 7628 const blocks = this.getBlocks().map(block => { 7629 const mappedBlock = objectMap.find(block); 7630 return mappedBlock || block.copyUsingObjectMap(objectMap); 7631 }); 7632 return new this.constructor(blocks); 7633 } 7634 copyWithBaseBlockAttributes() { 7635 let blockAttributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 7636 const blocks = this.getBlocks().map(block => { 7637 const attributes = blockAttributes.concat(block.getAttributes()); 7638 return block.copyWithAttributes(attributes); 7639 }); 7640 return new this.constructor(blocks); 7641 } 7642 replaceBlock(oldBlock, newBlock) { 7643 const index = this.blockList.indexOf(oldBlock); 7644 if (index === -1) { 7645 return this; 7646 } 7647 return new this.constructor(this.blockList.replaceObjectAtIndex(newBlock, index)); 7648 } 7649 insertDocumentAtRange(document, range) { 7650 const { 7651 blockList 7652 } = document; 7653 range = normalizeRange(range); 7654 let [position] = range; 7655 const { 7656 index, 7657 offset 7658 } = this.locationFromPosition(position); 7659 let result = this; 7660 const block = this.getBlockAtPosition(position); 7661 if (rangeIsCollapsed(range) && block.isEmpty() && !block.hasAttributes()) { 7662 result = new this.constructor(result.blockList.removeObjectAtIndex(index)); 7663 } else if (block.getBlockBreakPosition() === offset) { 7664 position++; 7665 } 7666 result = result.removeTextAtRange(range); 7667 return new this.constructor(result.blockList.insertSplittableListAtPosition(blockList, position)); 7668 } 7669 mergeDocumentAtRange(document, range) { 7670 let formattedDocument, result; 7671 range = normalizeRange(range); 7672 const [startPosition] = range; 7673 const startLocation = this.locationFromPosition(startPosition); 7674 const blockAttributes = this.getBlockAtIndex(startLocation.index).getAttributes(); 7675 const baseBlockAttributes = document.getBaseBlockAttributes(); 7676 const trailingBlockAttributes = blockAttributes.slice(-baseBlockAttributes.length); 7677 if (arraysAreEqual(baseBlockAttributes, trailingBlockAttributes)) { 7678 const leadingBlockAttributes = blockAttributes.slice(0, -baseBlockAttributes.length); 7679 formattedDocument = document.copyWithBaseBlockAttributes(leadingBlockAttributes); 7680 } else { 7681 formattedDocument = document.copy({ 7682 consolidateBlocks: true 7683 }).copyWithBaseBlockAttributes(blockAttributes); 7684 } 7685 const blockCount = formattedDocument.getBlockCount(); 7686 const firstBlock = formattedDocument.getBlockAtIndex(0); 7687 if (arraysAreEqual(blockAttributes, firstBlock.getAttributes())) { 7688 const firstText = firstBlock.getTextWithoutBlockBreak(); 7689 result = this.insertTextAtRange(firstText, range); 7690 if (blockCount > 1) { 7691 formattedDocument = new this.constructor(formattedDocument.getBlocks().slice(1)); 7692 const position = startPosition + firstText.getLength(); 7693 result = result.insertDocumentAtRange(formattedDocument, position); 7694 } 7695 } else { 7696 result = this.insertDocumentAtRange(formattedDocument, range); 7697 } 7698 return result; 7699 } 7700 insertTextAtRange(text, range) { 7701 range = normalizeRange(range); 7702 const [startPosition] = range; 7703 const { 7704 index, 7705 offset 7706 } = this.locationFromPosition(startPosition); 7707 const document = this.removeTextAtRange(range); 7708 return new this.constructor(document.blockList.editObjectAtIndex(index, block => block.copyWithText(block.text.insertTextAtPosition(text, offset)))); 7709 } 7710 removeTextAtRange(range) { 7711 let blocks; 7712 range = normalizeRange(range); 7713 const [leftPosition, rightPosition] = range; 7714 if (rangeIsCollapsed(range)) { 7715 return this; 7716 } 7717 const [leftLocation, rightLocation] = Array.from(this.locationRangeFromRange(range)); 7718 const leftIndex = leftLocation.index; 7719 const leftOffset = leftLocation.offset; 7720 const leftBlock = this.getBlockAtIndex(leftIndex); 7721 const rightIndex = rightLocation.index; 7722 const rightOffset = rightLocation.offset; 7723 const rightBlock = this.getBlockAtIndex(rightIndex); 7724 const removeRightNewline = rightPosition - leftPosition === 1 && leftBlock.getBlockBreakPosition() === leftOffset && rightBlock.getBlockBreakPosition() !== rightOffset && rightBlock.text.getStringAtPosition(rightOffset) === "\n"; 7725 if (removeRightNewline) { 7726 blocks = this.blockList.editObjectAtIndex(rightIndex, block => block.copyWithText(block.text.removeTextAtRange([rightOffset, rightOffset + 1]))); 7727 } else { 7728 let block; 7729 const leftText = leftBlock.text.getTextAtRange([0, leftOffset]); 7730 const rightText = rightBlock.text.getTextAtRange([rightOffset, rightBlock.getLength()]); 7731 const text = leftText.appendText(rightText); 7732 const removingLeftBlock = leftIndex !== rightIndex && leftOffset === 0; 7733 const useRightBlock = removingLeftBlock && leftBlock.getAttributeLevel() >= rightBlock.getAttributeLevel(); 7734 if (useRightBlock) { 7735 block = rightBlock.copyWithText(text); 7736 } else { 7737 block = leftBlock.copyWithText(text); 7738 } 7739 const affectedBlockCount = rightIndex + 1 - leftIndex; 7740 blocks = this.blockList.splice(leftIndex, affectedBlockCount, block); 7741 } 7742 return new this.constructor(blocks); 7743 } 7744 moveTextFromRangeToPosition(range, position) { 7745 let text; 7746 range = normalizeRange(range); 7747 const [startPosition, endPosition] = range; 7748 if (startPosition <= position && position <= endPosition) { 7749 return this; 7750 } 7751 let document = this.getDocumentAtRange(range); 7752 let result = this.removeTextAtRange(range); 7753 const movingRightward = startPosition < position; 7754 if (movingRightward) { 7755 position -= document.getLength(); 7756 } 7757 const [firstBlock, ...blocks] = document.getBlocks(); 7758 if (blocks.length === 0) { 7759 text = firstBlock.getTextWithoutBlockBreak(); 7760 if (movingRightward) { 7761 position += 1; 7762 } 7763 } else { 7764 text = firstBlock.text; 7765 } 7766 result = result.insertTextAtRange(text, position); 7767 if (blocks.length === 0) { 7768 return result; 7769 } 7770 document = new this.constructor(blocks); 7771 position += text.getLength(); 7772 return result.insertDocumentAtRange(document, position); 7773 } 7774 addAttributeAtRange(attribute, value, range) { 7775 let { 7776 blockList 7777 } = this; 7778 this.eachBlockAtRange(range, (block, textRange, index) => blockList = blockList.editObjectAtIndex(index, function () { 7779 if (getBlockConfig(attribute)) { 7780 return block.addAttribute(attribute, value); 7781 } else { 7782 if (textRange[0] === textRange[1]) { 7783 return block; 7784 } else { 7785 return block.copyWithText(block.text.addAttributeAtRange(attribute, value, textRange)); 7786 } 7787 } 7788 })); 7789 return new this.constructor(blockList); 7790 } 7791 addAttribute(attribute, value) { 7792 let { 7793 blockList 7794 } = this; 7795 this.eachBlock((block, index) => blockList = blockList.editObjectAtIndex(index, () => block.addAttribute(attribute, value))); 7796 return new this.constructor(blockList); 7797 } 7798 removeAttributeAtRange(attribute, range) { 7799 let { 7800 blockList 7801 } = this; 7802 this.eachBlockAtRange(range, function (block, textRange, index) { 7803 if (getBlockConfig(attribute)) { 7804 blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(attribute)); 7805 } else if (textRange[0] !== textRange[1]) { 7806 blockList = blockList.editObjectAtIndex(index, () => block.copyWithText(block.text.removeAttributeAtRange(attribute, textRange))); 7807 } 7808 }); 7809 return new this.constructor(blockList); 7810 } 7811 updateAttributesForAttachment(attributes, attachment) { 7812 const range = this.getRangeOfAttachment(attachment); 7813 const [startPosition] = Array.from(range); 7814 const { 7815 index 7816 } = this.locationFromPosition(startPosition); 7817 const text = this.getTextAtIndex(index); 7818 return new this.constructor(this.blockList.editObjectAtIndex(index, block => block.copyWithText(text.updateAttributesForAttachment(attributes, attachment)))); 7819 } 7820 removeAttributeForAttachment(attribute, attachment) { 7821 const range = this.getRangeOfAttachment(attachment); 7822 return this.removeAttributeAtRange(attribute, range); 7823 } 7824 setHTMLAttributeAtPosition(position, name, value) { 7825 const block = this.getBlockAtPosition(position); 7826 const updatedBlock = block.addHTMLAttribute(name, value); 7827 return this.replaceBlock(block, updatedBlock); 7828 } 7829 insertBlockBreakAtRange(range) { 7830 let blocks; 7831 range = normalizeRange(range); 7832 const [startPosition] = range; 7833 const { 7834 offset 7835 } = this.locationFromPosition(startPosition); 7836 const document = this.removeTextAtRange(range); 7837 if (offset === 0) { 7838 blocks = [new Block()]; 7839 } 7840 return new this.constructor(document.blockList.insertSplittableListAtPosition(new SplittableList(blocks), startPosition)); 7841 } 7842 applyBlockAttributeAtRange(attributeName, value, range) { 7843 const expanded = this.expandRangeToLineBreaksAndSplitBlocks(range); 7844 let document = expanded.document; 7845 range = expanded.range; 7846 const blockConfig = getBlockConfig(attributeName); 7847 if (blockConfig.listAttribute) { 7848 document = document.removeLastListAttributeAtRange(range, { 7849 exceptAttributeName: attributeName 7850 }); 7851 const converted = document.convertLineBreaksToBlockBreaksInRange(range); 7852 document = converted.document; 7853 range = converted.range; 7854 } else if (blockConfig.exclusive) { 7855 document = document.removeBlockAttributesAtRange(range); 7856 } else if (blockConfig.terminal) { 7857 document = document.removeLastTerminalAttributeAtRange(range); 7858 } else { 7859 document = document.consolidateBlocksAtRange(range); 7860 } 7861 return document.addAttributeAtRange(attributeName, value, range); 7862 } 7863 removeLastListAttributeAtRange(range) { 7864 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 7865 let { 7866 blockList 7867 } = this; 7868 this.eachBlockAtRange(range, function (block, textRange, index) { 7869 const lastAttributeName = block.getLastAttribute(); 7870 if (!lastAttributeName) { 7871 return; 7872 } 7873 if (!getBlockConfig(lastAttributeName).listAttribute) { 7874 return; 7875 } 7876 if (lastAttributeName === options.exceptAttributeName) { 7877 return; 7878 } 7879 blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(lastAttributeName)); 7880 }); 7881 return new this.constructor(blockList); 7882 } 7883 removeLastTerminalAttributeAtRange(range) { 7884 let { 7885 blockList 7886 } = this; 7887 this.eachBlockAtRange(range, function (block, textRange, index) { 7888 const lastAttributeName = block.getLastAttribute(); 7889 if (!lastAttributeName) { 7890 return; 7891 } 7892 if (!getBlockConfig(lastAttributeName).terminal) { 7893 return; 7894 } 7895 blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(lastAttributeName)); 7896 }); 7897 return new this.constructor(blockList); 7898 } 7899 removeBlockAttributesAtRange(range) { 7900 let { 7901 blockList 7902 } = this; 7903 this.eachBlockAtRange(range, function (block, textRange, index) { 7904 if (block.hasAttributes()) { 7905 blockList = blockList.editObjectAtIndex(index, () => block.copyWithoutAttributes()); 7906 } 7907 }); 7908 return new this.constructor(blockList); 7909 } 7910 expandRangeToLineBreaksAndSplitBlocks(range) { 7911 let position; 7912 range = normalizeRange(range); 7913 let [startPosition, endPosition] = range; 7914 const startLocation = this.locationFromPosition(startPosition); 7915 const endLocation = this.locationFromPosition(endPosition); 7916 let document = this; 7917 const startBlock = document.getBlockAtIndex(startLocation.index); 7918 startLocation.offset = startBlock.findLineBreakInDirectionFromPosition("backward", startLocation.offset); 7919 if (startLocation.offset != null) { 7920 position = document.positionFromLocation(startLocation); 7921 document = document.insertBlockBreakAtRange([position, position + 1]); 7922 endLocation.index += 1; 7923 endLocation.offset -= document.getBlockAtIndex(startLocation.index).getLength(); 7924 startLocation.index += 1; 7925 } 7926 startLocation.offset = 0; 7927 if (endLocation.offset === 0 && endLocation.index > startLocation.index) { 7928 endLocation.index -= 1; 7929 endLocation.offset = document.getBlockAtIndex(endLocation.index).getBlockBreakPosition(); 7930 } else { 7931 const endBlock = document.getBlockAtIndex(endLocation.index); 7932 if (endBlock.text.getStringAtRange([endLocation.offset - 1, endLocation.offset]) === "\n") { 7933 endLocation.offset -= 1; 7934 } else { 7935 endLocation.offset = endBlock.findLineBreakInDirectionFromPosition("forward", endLocation.offset); 7936 } 7937 if (endLocation.offset !== endBlock.getBlockBreakPosition()) { 7938 position = document.positionFromLocation(endLocation); 7939 document = document.insertBlockBreakAtRange([position, position + 1]); 7940 } 7941 } 7942 startPosition = document.positionFromLocation(startLocation); 7943 endPosition = document.positionFromLocation(endLocation); 7944 range = normalizeRange([startPosition, endPosition]); 7945 return { 7946 document, 7947 range 7948 }; 7949 } 7950 convertLineBreaksToBlockBreaksInRange(range) { 7951 range = normalizeRange(range); 7952 let [position] = range; 7953 const string = this.getStringAtRange(range).slice(0, -1); 7954 let document = this; 7955 string.replace(/.*?\n/g, function (match) { 7956 position += match.length; 7957 document = document.insertBlockBreakAtRange([position - 1, position]); 7958 }); 7959 return { 7960 document, 7961 range 7962 }; 7963 } 7964 consolidateBlocksAtRange(range) { 7965 range = normalizeRange(range); 7966 const [startPosition, endPosition] = range; 7967 const startIndex = this.locationFromPosition(startPosition).index; 7968 const endIndex = this.locationFromPosition(endPosition).index; 7969 return new this.constructor(this.blockList.consolidateFromIndexToIndex(startIndex, endIndex)); 7970 } 7971 getDocumentAtRange(range) { 7972 range = normalizeRange(range); 7973 const blocks = this.blockList.getSplittableListInRange(range).toArray(); 7974 return new this.constructor(blocks); 7975 } 7976 getStringAtRange(range) { 7977 let endIndex; 7978 const array = range = normalizeRange(range), 7979 endPosition = array[array.length - 1]; 7980 if (endPosition !== this.getLength()) { 7981 endIndex = -1; 7982 } 7983 return this.getDocumentAtRange(range).toString().slice(0, endIndex); 7984 } 7985 getBlockAtIndex(index) { 7986 return this.blockList.getObjectAtIndex(index); 7987 } 7988 getBlockAtPosition(position) { 7989 const { 7990 index 7991 } = this.locationFromPosition(position); 7992 return this.getBlockAtIndex(index); 7993 } 7994 getTextAtIndex(index) { 7995 var _this$getBlockAtIndex; 7996 return (_this$getBlockAtIndex = this.getBlockAtIndex(index)) === null || _this$getBlockAtIndex === void 0 ? void 0 : _this$getBlockAtIndex.text; 7997 } 7998 getTextAtPosition(position) { 7999 const { 8000 index 8001 } = this.locationFromPosition(position); 8002 return this.getTextAtIndex(index); 8003 } 8004 getPieceAtPosition(position) { 8005 const { 8006 index, 8007 offset 8008 } = this.locationFromPosition(position); 8009 return this.getTextAtIndex(index).getPieceAtPosition(offset); 8010 } 8011 getCharacterAtPosition(position) { 8012 const { 8013 index, 8014 offset 8015 } = this.locationFromPosition(position); 8016 return this.getTextAtIndex(index).getStringAtRange([offset, offset + 1]); 8017 } 8018 getLength() { 8019 return this.blockList.getEndPosition(); 8020 } 8021 getBlocks() { 8022 return this.blockList.toArray(); 8023 } 8024 getBlockCount() { 8025 return this.blockList.length; 8026 } 8027 getEditCount() { 8028 return this.editCount; 8029 } 8030 eachBlock(callback) { 8031 return this.blockList.eachObject(callback); 8032 } 8033 eachBlockAtRange(range, callback) { 8034 let block, textRange; 8035 range = normalizeRange(range); 8036 const [startPosition, endPosition] = range; 8037 const startLocation = this.locationFromPosition(startPosition); 8038 const endLocation = this.locationFromPosition(endPosition); 8039 if (startLocation.index === endLocation.index) { 8040 block = this.getBlockAtIndex(startLocation.index); 8041 textRange = [startLocation.offset, endLocation.offset]; 8042 return callback(block, textRange, startLocation.index); 8043 } else { 8044 for (let index = startLocation.index; index <= endLocation.index; index++) { 8045 block = this.getBlockAtIndex(index); 8046 if (block) { 8047 switch (index) { 8048 case startLocation.index: 8049 textRange = [startLocation.offset, block.text.getLength()]; 8050 break; 8051 case endLocation.index: 8052 textRange = [0, endLocation.offset]; 8053 break; 8054 default: 8055 textRange = [0, block.text.getLength()]; 8056 } 8057 callback(block, textRange, index); 8058 } 8059 } 8060 } 8061 } 8062 getCommonAttributesAtRange(range) { 8063 range = normalizeRange(range); 8064 const [startPosition] = range; 8065 if (rangeIsCollapsed(range)) { 8066 return this.getCommonAttributesAtPosition(startPosition); 8067 } else { 8068 const textAttributes = []; 8069 const blockAttributes = []; 8070 this.eachBlockAtRange(range, function (block, textRange) { 8071 if (textRange[0] !== textRange[1]) { 8072 textAttributes.push(block.text.getCommonAttributesAtRange(textRange)); 8073 return blockAttributes.push(attributesForBlock(block)); 8074 } 8075 }); 8076 return Hash.fromCommonAttributesOfObjects(textAttributes).merge(Hash.fromCommonAttributesOfObjects(blockAttributes)).toObject(); 8077 } 8078 } 8079 getCommonAttributesAtPosition(position) { 8080 let key, value; 8081 const { 8082 index, 8083 offset 8084 } = this.locationFromPosition(position); 8085 const block = this.getBlockAtIndex(index); 8086 if (!block) { 8087 return {}; 8088 } 8089 const commonAttributes = attributesForBlock(block); 8090 const attributes = block.text.getAttributesAtPosition(offset); 8091 const attributesLeft = block.text.getAttributesAtPosition(offset - 1); 8092 const inheritableAttributes = Object.keys(text_attributes).filter(key => { 8093 return text_attributes[key].inheritable; 8094 }); 8095 for (key in attributesLeft) { 8096 value = attributesLeft[key]; 8097 if (value === attributes[key] || inheritableAttributes.includes(key)) { 8098 commonAttributes[key] = value; 8099 } 8100 } 8101 return commonAttributes; 8102 } 8103 getRangeOfCommonAttributeAtPosition(attributeName, position) { 8104 const { 8105 index, 8106 offset 8107 } = this.locationFromPosition(position); 8108 const text = this.getTextAtIndex(index); 8109 const [startOffset, endOffset] = Array.from(text.getExpandedRangeForAttributeAtOffset(attributeName, offset)); 8110 const start = this.positionFromLocation({ 8111 index, 8112 offset: startOffset 8113 }); 8114 const end = this.positionFromLocation({ 8115 index, 8116 offset: endOffset 8117 }); 8118 return normalizeRange([start, end]); 8119 } 8120 getBaseBlockAttributes() { 8121 let baseBlockAttributes = this.getBlockAtIndex(0).getAttributes(); 8122 for (let blockIndex = 1; blockIndex < this.getBlockCount(); blockIndex++) { 8123 const blockAttributes = this.getBlockAtIndex(blockIndex).getAttributes(); 8124 const lastAttributeIndex = Math.min(baseBlockAttributes.length, blockAttributes.length); 8125 baseBlockAttributes = (() => { 8126 const result = []; 8127 for (let index = 0; index < lastAttributeIndex; index++) { 8128 if (blockAttributes[index] !== baseBlockAttributes[index]) { 8129 break; 8130 } 8131 result.push(blockAttributes[index]); 8132 } 8133 return result; 8134 })(); 8135 } 8136 return baseBlockAttributes; 8137 } 8138 getAttachmentById(attachmentId) { 8139 for (const attachment of this.getAttachments()) { 8140 if (attachment.id === attachmentId) { 8141 return attachment; 8142 } 8143 } 8144 } 8145 getAttachmentPieces() { 8146 let attachmentPieces = []; 8147 this.blockList.eachObject(_ref => { 8148 let { 8149 text 8150 } = _ref; 8151 return attachmentPieces = attachmentPieces.concat(text.getAttachmentPieces()); 8152 }); 8153 return attachmentPieces; 8154 } 8155 getAttachments() { 8156 return this.getAttachmentPieces().map(piece => piece.attachment); 8157 } 8158 getRangeOfAttachment(attachment) { 8159 let position = 0; 8160 const iterable = this.blockList.toArray(); 8161 for (let index = 0; index < iterable.length; index++) { 8162 const { 8163 text 8164 } = iterable[index]; 8165 const textRange = text.getRangeOfAttachment(attachment); 8166 if (textRange) { 8167 return normalizeRange([position + textRange[0], position + textRange[1]]); 8168 } 8169 position += text.getLength(); 8170 } 8171 } 8172 getLocationRangeOfAttachment(attachment) { 8173 const range = this.getRangeOfAttachment(attachment); 8174 return this.locationRangeFromRange(range); 8175 } 8176 getAttachmentPieceForAttachment(attachment) { 8177 for (const piece of this.getAttachmentPieces()) { 8178 if (piece.attachment === attachment) { 8179 return piece; 8180 } 8181 } 8182 } 8183 findRangesForBlockAttribute(attributeName) { 8184 let position = 0; 8185 const ranges = []; 8186 this.getBlocks().forEach(block => { 8187 const length = block.getLength(); 8188 if (block.hasAttribute(attributeName)) { 8189 ranges.push([position, position + length]); 8190 } 8191 position += length; 8192 }); 8193 return ranges; 8194 } 8195 findRangesForTextAttribute(attributeName) { 8196 let { 8197 withValue 8198 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 8199 let position = 0; 8200 let range = []; 8201 const ranges = []; 8202 const match = function (piece) { 8203 if (withValue) { 8204 return piece.getAttribute(attributeName) === withValue; 8205 } else { 8206 return piece.hasAttribute(attributeName); 8207 } 8208 }; 8209 this.getPieces().forEach(piece => { 8210 const length = piece.getLength(); 8211 if (match(piece)) { 8212 if (range[1] === position) { 8213 range[1] = position + length; 8214 } else { 8215 ranges.push(range = [position, position + length]); 8216 } 8217 } 8218 position += length; 8219 }); 8220 return ranges; 8221 } 8222 locationFromPosition(position) { 8223 const location = this.blockList.findIndexAndOffsetAtPosition(Math.max(0, position)); 8224 if (location.index != null) { 8225 return location; 8226 } else { 8227 const blocks = this.getBlocks(); 8228 return { 8229 index: blocks.length - 1, 8230 offset: blocks[blocks.length - 1].getLength() 8231 }; 8232 } 8233 } 8234 positionFromLocation(location) { 8235 return this.blockList.findPositionAtIndexAndOffset(location.index, location.offset); 8236 } 8237 locationRangeFromPosition(position) { 8238 return normalizeRange(this.locationFromPosition(position)); 8239 } 8240 locationRangeFromRange(range) { 8241 range = normalizeRange(range); 8242 if (!range) return; 8243 const [startPosition, endPosition] = Array.from(range); 8244 const startLocation = this.locationFromPosition(startPosition); 8245 const endLocation = this.locationFromPosition(endPosition); 8246 return normalizeRange([startLocation, endLocation]); 8247 } 8248 rangeFromLocationRange(locationRange) { 8249 let rightPosition; 8250 locationRange = normalizeRange(locationRange); 8251 const leftPosition = this.positionFromLocation(locationRange[0]); 8252 if (!rangeIsCollapsed(locationRange)) { 8253 rightPosition = this.positionFromLocation(locationRange[1]); 8254 } 8255 return normalizeRange([leftPosition, rightPosition]); 8256 } 8257 isEqualTo(document) { 8258 return this.blockList.isEqualTo(document === null || document === void 0 ? void 0 : document.blockList); 8259 } 8260 getTexts() { 8261 return this.getBlocks().map(block => block.text); 8262 } 8263 getPieces() { 8264 const pieces = []; 8265 Array.from(this.getTexts()).forEach(text => { 8266 pieces.push(...Array.from(text.getPieces() || [])); 8267 }); 8268 return pieces; 8269 } 8270 getObjects() { 8271 return this.getBlocks().concat(this.getTexts()).concat(this.getPieces()); 8272 } 8273 toSerializableDocument() { 8274 const blocks = []; 8275 this.blockList.eachObject(block => blocks.push(block.copyWithText(block.text.toSerializableText()))); 8276 return new this.constructor(blocks); 8277 } 8278 toString() { 8279 return this.blockList.toString(); 8280 } 8281 toJSON() { 8282 return this.blockList.toJSON(); 8283 } 8284 toConsole() { 8285 return JSON.stringify(this.blockList.toArray().map(block => JSON.parse(block.text.toConsole()))); 8286 } 8287 } 8288 const attributesForBlock = function (block) { 8289 const attributes = {}; 8290 const attributeName = block.getLastAttribute(); 8291 if (attributeName) { 8292 attributes[attributeName] = true; 8293 } 8294 return attributes; 8295 }; 8296 8297 /* eslint-disable 8298 no-case-declarations, 8299 no-irregular-whitespace, 8300 */ 8301 const pieceForString = function (string) { 8302 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 8303 const type = "string"; 8304 string = normalizeSpaces(string); 8305 return { 8306 string, 8307 attributes, 8308 type 8309 }; 8310 }; 8311 const pieceForAttachment = function (attachment) { 8312 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 8313 const type = "attachment"; 8314 return { 8315 attachment, 8316 attributes, 8317 type 8318 }; 8319 }; 8320 const blockForAttributes = function () { 8321 let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 8322 let htmlAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 8323 const text = []; 8324 return { 8325 text, 8326 attributes, 8327 htmlAttributes 8328 }; 8329 }; 8330 const parseTrixDataAttribute = (element, name) => { 8331 try { 8332 return JSON.parse(element.getAttribute("data-trix-".concat(name))); 8333 } catch (error) { 8334 return {}; 8335 } 8336 }; 8337 const getImageDimensions = element => { 8338 const width = element.getAttribute("width"); 8339 const height = element.getAttribute("height"); 8340 const dimensions = {}; 8341 if (width) { 8342 dimensions.width = parseInt(width, 10); 8343 } 8344 if (height) { 8345 dimensions.height = parseInt(height, 10); 8346 } 8347 return dimensions; 8348 }; 8349 class HTMLParser extends BasicObject { 8350 static parse(html, options) { 8351 const parser = new this(html, options); 8352 parser.parse(); 8353 return parser; 8354 } 8355 constructor(html) { 8356 let { 8357 referenceElement, 8358 purifyOptions 8359 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 8360 super(...arguments); 8361 this.html = html; 8362 this.referenceElement = referenceElement; 8363 this.purifyOptions = purifyOptions; 8364 this.blocks = []; 8365 this.blockElements = []; 8366 this.processedElements = []; 8367 } 8368 getDocument() { 8369 return Document.fromJSON(this.blocks); 8370 } 8371 8372 // HTML parsing 8373 8374 parse() { 8375 try { 8376 this.createHiddenContainer(); 8377 HTMLSanitizer.setHTML(this.containerElement, this.html, { 8378 purifyOptions: this.purifyOptions 8379 }); 8380 const walker = walkTree(this.containerElement, { 8381 usingFilter: nodeFilter 8382 }); 8383 while (walker.nextNode()) { 8384 this.processNode(walker.currentNode); 8385 } 8386 return this.translateBlockElementMarginsToNewlines(); 8387 } finally { 8388 this.removeHiddenContainer(); 8389 } 8390 } 8391 createHiddenContainer() { 8392 if (this.referenceElement) { 8393 this.containerElement = this.referenceElement.cloneNode(false); 8394 this.containerElement.removeAttribute("id"); 8395 this.containerElement.setAttribute("data-trix-internal", ""); 8396 this.containerElement.style.display = "none"; 8397 return this.referenceElement.parentNode.insertBefore(this.containerElement, this.referenceElement.nextSibling); 8398 } else { 8399 this.containerElement = makeElement({ 8400 tagName: "div", 8401 style: { 8402 display: "none" 8403 } 8404 }); 8405 return document.body.appendChild(this.containerElement); 8406 } 8407 } 8408 removeHiddenContainer() { 8409 return removeNode(this.containerElement); 8410 } 8411 processNode(node) { 8412 switch (node.nodeType) { 8413 case Node.TEXT_NODE: 8414 if (!this.isInsignificantTextNode(node)) { 8415 this.appendBlockForTextNode(node); 8416 return this.processTextNode(node); 8417 } 8418 break; 8419 case Node.ELEMENT_NODE: 8420 this.appendBlockForElement(node); 8421 return this.processElement(node); 8422 } 8423 } 8424 appendBlockForTextNode(node) { 8425 const element = node.parentNode; 8426 if (element === this.currentBlockElement && this.isBlockElement(node.previousSibling)) { 8427 return this.appendStringWithAttributes("\n"); 8428 } else if (element === this.containerElement || this.isBlockElement(element)) { 8429 var _this$currentBlock; 8430 const attributes = this.getBlockAttributes(element); 8431 const htmlAttributes = this.getBlockHTMLAttributes(element); 8432 if (!arraysAreEqual(attributes, (_this$currentBlock = this.currentBlock) === null || _this$currentBlock === void 0 ? void 0 : _this$currentBlock.attributes)) { 8433 this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes); 8434 this.currentBlockElement = element; 8435 } 8436 } 8437 } 8438 appendBlockForElement(element) { 8439 const elementIsBlockElement = this.isBlockElement(element); 8440 const currentBlockContainsElement = elementContainsNode(this.currentBlockElement, element); 8441 if (elementIsBlockElement && !this.isBlockElement(element.firstChild)) { 8442 if (!this.isInsignificantTextNode(element.firstChild) || !this.isBlockElement(element.firstElementChild)) { 8443 const attributes = this.getBlockAttributes(element); 8444 const htmlAttributes = this.getBlockHTMLAttributes(element); 8445 if (element.firstChild) { 8446 if (!(currentBlockContainsElement && arraysAreEqual(attributes, this.currentBlock.attributes))) { 8447 this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes); 8448 this.currentBlockElement = element; 8449 } else { 8450 return this.appendStringWithAttributes("\n"); 8451 } 8452 } 8453 } 8454 } else if (this.currentBlockElement && !currentBlockContainsElement && !elementIsBlockElement) { 8455 const parentBlockElement = this.findParentBlockElement(element); 8456 if (parentBlockElement) { 8457 return this.appendBlockForElement(parentBlockElement); 8458 } else { 8459 this.currentBlock = this.appendEmptyBlock(); 8460 this.currentBlockElement = null; 8461 } 8462 } 8463 } 8464 findParentBlockElement(element) { 8465 let { 8466 parentElement 8467 } = element; 8468 while (parentElement && parentElement !== this.containerElement) { 8469 if (this.isBlockElement(parentElement) && this.blockElements.includes(parentElement)) { 8470 return parentElement; 8471 } else { 8472 parentElement = parentElement.parentElement; 8473 } 8474 } 8475 return null; 8476 } 8477 processTextNode(node) { 8478 let string = node.data; 8479 if (!elementCanDisplayPreformattedText(node.parentNode)) { 8480 var _node$previousSibling; 8481 string = squishBreakableWhitespace(string); 8482 if (stringEndsWithWhitespace((_node$previousSibling = node.previousSibling) === null || _node$previousSibling === void 0 ? void 0 : _node$previousSibling.textContent)) { 8483 string = leftTrimBreakableWhitespace(string); 8484 } 8485 } 8486 return this.appendStringWithAttributes(string, this.getTextAttributes(node.parentNode)); 8487 } 8488 processElement(element) { 8489 let attributes; 8490 if (nodeIsAttachmentElement(element)) { 8491 attributes = parseTrixDataAttribute(element, "attachment"); 8492 if (Object.keys(attributes).length) { 8493 const textAttributes = this.getTextAttributes(element); 8494 this.appendAttachmentWithAttributes(attributes, textAttributes); 8495 // We have everything we need so avoid processing inner nodes 8496 element.innerHTML = ""; 8497 } 8498 return this.processedElements.push(element); 8499 } else { 8500 switch (tagName(element)) { 8501 case "br": 8502 if (!this.isExtraBR(element) && !this.isBlockElement(element.nextSibling)) { 8503 this.appendStringWithAttributes("\n", this.getTextAttributes(element)); 8504 } 8505 return this.processedElements.push(element); 8506 case "img": 8507 attributes = { 8508 url: element.getAttribute("src"), 8509 contentType: "image" 8510 }; 8511 const object = getImageDimensions(element); 8512 for (const key in object) { 8513 const value = object[key]; 8514 attributes[key] = value; 8515 } 8516 this.appendAttachmentWithAttributes(attributes, this.getTextAttributes(element)); 8517 return this.processedElements.push(element); 8518 case "tr": 8519 if (this.needsTableSeparator(element)) { 8520 return this.appendStringWithAttributes(parser.tableRowSeparator); 8521 } 8522 break; 8523 case "td": 8524 if (this.needsTableSeparator(element)) { 8525 return this.appendStringWithAttributes(parser.tableCellSeparator); 8526 } 8527 break; 8528 } 8529 } 8530 } 8531 8532 // Document construction 8533 8534 appendBlockForAttributesWithElement(attributes, element) { 8535 let htmlAttributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 8536 this.blockElements.push(element); 8537 const block = blockForAttributes(attributes, htmlAttributes); 8538 this.blocks.push(block); 8539 return block; 8540 } 8541 appendEmptyBlock() { 8542 return this.appendBlockForAttributesWithElement([], null); 8543 } 8544 appendStringWithAttributes(string, attributes) { 8545 return this.appendPiece(pieceForString(string, attributes)); 8546 } 8547 appendAttachmentWithAttributes(attachment, attributes) { 8548 return this.appendPiece(pieceForAttachment(attachment, attributes)); 8549 } 8550 appendPiece(piece) { 8551 if (this.blocks.length === 0) { 8552 this.appendEmptyBlock(); 8553 } 8554 return this.blocks[this.blocks.length - 1].text.push(piece); 8555 } 8556 appendStringToTextAtIndex(string, index) { 8557 const { 8558 text 8559 } = this.blocks[index]; 8560 const piece = text[text.length - 1]; 8561 if ((piece === null || piece === void 0 ? void 0 : piece.type) === "string") { 8562 piece.string += string; 8563 } else { 8564 return text.push(pieceForString(string)); 8565 } 8566 } 8567 prependStringToTextAtIndex(string, index) { 8568 const { 8569 text 8570 } = this.blocks[index]; 8571 const piece = text[0]; 8572 if ((piece === null || piece === void 0 ? void 0 : piece.type) === "string") { 8573 piece.string = string + piece.string; 8574 } else { 8575 return text.unshift(pieceForString(string)); 8576 } 8577 } 8578 8579 // Attribute parsing 8580 8581 getTextAttributes(element) { 8582 let value; 8583 const attributes = {}; 8584 for (const attribute in text_attributes) { 8585 const configAttr = text_attributes[attribute]; 8586 if (configAttr.tagName && findClosestElementFromNode(element, { 8587 matchingSelector: configAttr.tagName, 8588 untilNode: this.containerElement 8589 })) { 8590 attributes[attribute] = true; 8591 } else if (configAttr.parser) { 8592 value = configAttr.parser(element); 8593 if (value) { 8594 let attributeInheritedFromBlock = false; 8595 for (const blockElement of this.findBlockElementAncestors(element)) { 8596 if (configAttr.parser(blockElement) === value) { 8597 attributeInheritedFromBlock = true; 8598 break; 8599 } 8600 } 8601 if (!attributeInheritedFromBlock) { 8602 attributes[attribute] = value; 8603 } 8604 } 8605 } else if (configAttr.styleProperty) { 8606 value = element.style[configAttr.styleProperty]; 8607 if (value) { 8608 attributes[attribute] = value; 8609 } 8610 } 8611 } 8612 if (nodeIsAttachmentElement(element)) { 8613 const object = parseTrixDataAttribute(element, "attributes"); 8614 for (const key in object) { 8615 value = object[key]; 8616 attributes[key] = value; 8617 } 8618 } 8619 return attributes; 8620 } 8621 getBlockAttributes(element) { 8622 const attributes$1 = []; 8623 while (element && element !== this.containerElement) { 8624 for (const attribute in attributes) { 8625 const attrConfig = attributes[attribute]; 8626 if (attrConfig.parse !== false) { 8627 if (tagName(element) === attrConfig.tagName) { 8628 var _attrConfig$test; 8629 if ((_attrConfig$test = attrConfig.test) !== null && _attrConfig$test !== void 0 && _attrConfig$test.call(attrConfig, element) || !attrConfig.test) { 8630 attributes$1.push(attribute); 8631 if (attrConfig.listAttribute) { 8632 attributes$1.push(attrConfig.listAttribute); 8633 } 8634 } 8635 } 8636 } 8637 } 8638 element = element.parentNode; 8639 } 8640 return attributes$1.reverse(); 8641 } 8642 getBlockHTMLAttributes(element) { 8643 const attributes$1 = {}; 8644 const blockConfig = Object.values(attributes).find(settings => settings.tagName === tagName(element)); 8645 const allowedAttributes = (blockConfig === null || blockConfig === void 0 ? void 0 : blockConfig.htmlAttributes) || []; 8646 allowedAttributes.forEach(attribute => { 8647 if (element.hasAttribute(attribute)) { 8648 attributes$1[attribute] = element.getAttribute(attribute); 8649 } 8650 }); 8651 return attributes$1; 8652 } 8653 findBlockElementAncestors(element) { 8654 const ancestors = []; 8655 while (element && element !== this.containerElement) { 8656 const tag = tagName(element); 8657 if (getBlockTagNames().includes(tag)) { 8658 ancestors.push(element); 8659 } 8660 element = element.parentNode; 8661 } 8662 return ancestors; 8663 } 8664 8665 // Element inspection 8666 8667 isBlockElement(element) { 8668 if ((element === null || element === void 0 ? void 0 : element.nodeType) !== Node.ELEMENT_NODE) return; 8669 if (nodeIsAttachmentElement(element)) return; 8670 if (findClosestElementFromNode(element, { 8671 matchingSelector: "td", 8672 untilNode: this.containerElement 8673 })) return; 8674 return getBlockTagNames().includes(tagName(element)) || window.getComputedStyle(element).display === "block"; 8675 } 8676 isInsignificantTextNode(node) { 8677 if ((node === null || node === void 0 ? void 0 : node.nodeType) !== Node.TEXT_NODE) return; 8678 if (!stringIsAllBreakableWhitespace(node.data)) return; 8679 const { 8680 parentNode, 8681 previousSibling, 8682 nextSibling 8683 } = node; 8684 if (nodeEndsWithNonWhitespace(parentNode.previousSibling) && !this.isBlockElement(parentNode.previousSibling)) return; 8685 if (elementCanDisplayPreformattedText(parentNode)) return; 8686 return !previousSibling || this.isBlockElement(previousSibling) || !nextSibling || this.isBlockElement(nextSibling); 8687 } 8688 isExtraBR(element) { 8689 return tagName(element) === "br" && this.isBlockElement(element.parentNode) && element.parentNode.lastChild === element; 8690 } 8691 needsTableSeparator(element) { 8692 if (parser.removeBlankTableCells) { 8693 var _element$previousSibl; 8694 const content = (_element$previousSibl = element.previousSibling) === null || _element$previousSibl === void 0 ? void 0 : _element$previousSibl.textContent; 8695 return content && /\S/.test(content); 8696 } else { 8697 return element.previousSibling; 8698 } 8699 } 8700 8701 // Margin translation 8702 8703 translateBlockElementMarginsToNewlines() { 8704 const defaultMargin = this.getMarginOfDefaultBlockElement(); 8705 for (let index = 0; index < this.blocks.length; index++) { 8706 const margin = this.getMarginOfBlockElementAtIndex(index); 8707 if (margin) { 8708 if (margin.top > defaultMargin.top * 2) { 8709 this.prependStringToTextAtIndex("\n", index); 8710 } 8711 if (margin.bottom > defaultMargin.bottom * 2) { 8712 this.appendStringToTextAtIndex("\n", index); 8713 } 8714 } 8715 } 8716 } 8717 getMarginOfBlockElementAtIndex(index) { 8718 const element = this.blockElements[index]; 8719 if (element) { 8720 if (element.textContent) { 8721 if (!getBlockTagNames().includes(tagName(element)) && !this.processedElements.includes(element)) { 8722 return getBlockElementMargin(element); 8723 } 8724 } 8725 } 8726 } 8727 getMarginOfDefaultBlockElement() { 8728 const element = makeElement(attributes.default.tagName); 8729 this.containerElement.appendChild(element); 8730 return getBlockElementMargin(element); 8731 } 8732 } 8733 8734 // Helpers 8735 8736 const elementCanDisplayPreformattedText = function (element) { 8737 const { 8738 whiteSpace 8739 } = window.getComputedStyle(element); 8740 return ["pre", "pre-wrap", "pre-line"].includes(whiteSpace); 8741 }; 8742 const nodeEndsWithNonWhitespace = node => node && !stringEndsWithWhitespace(node.textContent); 8743 const getBlockElementMargin = function (element) { 8744 const style = window.getComputedStyle(element); 8745 if (style.display === "block") { 8746 return { 8747 top: parseInt(style.marginTop), 8748 bottom: parseInt(style.marginBottom) 8749 }; 8750 } 8751 }; 8752 const nodeFilter = function (node) { 8753 if (tagName(node) === "style") { 8754 return NodeFilter.FILTER_REJECT; 8755 } else { 8756 return NodeFilter.FILTER_ACCEPT; 8757 } 8758 }; 8759 8760 // Whitespace 8761 8762 const leftTrimBreakableWhitespace = string => string.replace(new RegExp("^".concat(breakableWhitespacePattern.source, "+")), ""); 8763 const stringIsAllBreakableWhitespace = string => new RegExp("^".concat(breakableWhitespacePattern.source, "*$")).test(string); 8764 const stringEndsWithWhitespace = string => /\s$/.test(string); 8765 8766 /* eslint-disable 8767 no-empty, 8768 */ 8769 const unserializableElementSelector = "[data-trix-serialize=false]"; 8770 const unserializableAttributeNames = ["contenteditable", "data-trix-id", "data-trix-store-key", "data-trix-mutable", "data-trix-placeholder", "tabindex"]; 8771 const serializedAttributesAttribute = "data-trix-serialized-attributes"; 8772 const serializedAttributesSelector = "[".concat(serializedAttributesAttribute, "]"); 8773 const blockCommentPattern = new RegExp("<!--block-->", "g"); 8774 const serializers = { 8775 "application/json": function (serializable) { 8776 let document; 8777 if (serializable instanceof Document) { 8778 document = serializable; 8779 } else if (serializable instanceof HTMLElement) { 8780 document = HTMLParser.parse(serializable.innerHTML).getDocument(); 8781 } else { 8782 throw new Error("unserializable object"); 8783 } 8784 return document.toSerializableDocument().toJSONString(); 8785 }, 8786 "text/html": function (serializable) { 8787 let element; 8788 if (serializable instanceof Document) { 8789 element = DocumentView.render(serializable); 8790 } else if (serializable instanceof HTMLElement) { 8791 element = serializable.cloneNode(true); 8792 } else { 8793 throw new Error("unserializable object"); 8794 } 8795 8796 // Remove unserializable elements 8797 Array.from(element.querySelectorAll(unserializableElementSelector)).forEach(el => { 8798 removeNode(el); 8799 }); 8800 8801 // Remove unserializable attributes 8802 unserializableAttributeNames.forEach(attribute => { 8803 Array.from(element.querySelectorAll("[".concat(attribute, "]"))).forEach(el => { 8804 el.removeAttribute(attribute); 8805 }); 8806 }); 8807 8808 // Rewrite elements with serialized attribute overrides 8809 Array.from(element.querySelectorAll(serializedAttributesSelector)).forEach(el => { 8810 try { 8811 const attributes = JSON.parse(el.getAttribute(serializedAttributesAttribute)); 8812 el.removeAttribute(serializedAttributesAttribute); 8813 for (const name in attributes) { 8814 const value = attributes[name]; 8815 el.setAttribute(name, value); 8816 } 8817 } catch (error) {} 8818 }); 8819 return element.innerHTML.replace(blockCommentPattern, ""); 8820 } 8821 }; 8822 const deserializers = { 8823 "application/json": function (string) { 8824 return Document.fromJSONString(string); 8825 }, 8826 "text/html": function (string) { 8827 return HTMLParser.parse(string).getDocument(); 8828 } 8829 }; 8830 const serializeToContentType = function (serializable, contentType) { 8831 const serializer = serializers[contentType]; 8832 if (serializer) { 8833 return serializer(serializable); 8834 } else { 8835 throw new Error("unknown content type: ".concat(contentType)); 8836 } 8837 }; 8838 const deserializeFromContentType = function (string, contentType) { 8839 const deserializer = deserializers[contentType]; 8840 if (deserializer) { 8841 return deserializer(string); 8842 } else { 8843 throw new Error("unknown content type: ".concat(contentType)); 8844 } 8845 }; 8846 8847 var core = /*#__PURE__*/Object.freeze({ 8848 __proto__: null 8849 }); 8850 8851 class ManagedAttachment extends BasicObject { 8852 constructor(attachmentManager, attachment) { 8853 super(...arguments); 8854 this.attachmentManager = attachmentManager; 8855 this.attachment = attachment; 8856 this.id = this.attachment.id; 8857 this.file = this.attachment.file; 8858 } 8859 remove() { 8860 return this.attachmentManager.requestRemovalOfAttachment(this.attachment); 8861 } 8862 } 8863 ManagedAttachment.proxyMethod("attachment.getAttribute"); 8864 ManagedAttachment.proxyMethod("attachment.hasAttribute"); 8865 ManagedAttachment.proxyMethod("attachment.setAttribute"); 8866 ManagedAttachment.proxyMethod("attachment.getAttributes"); 8867 ManagedAttachment.proxyMethod("attachment.setAttributes"); 8868 ManagedAttachment.proxyMethod("attachment.isPending"); 8869 ManagedAttachment.proxyMethod("attachment.isPreviewable"); 8870 ManagedAttachment.proxyMethod("attachment.getURL"); 8871 ManagedAttachment.proxyMethod("attachment.getPreviewURL"); 8872 ManagedAttachment.proxyMethod("attachment.setPreviewURL"); 8873 ManagedAttachment.proxyMethod("attachment.getHref"); 8874 ManagedAttachment.proxyMethod("attachment.getFilename"); 8875 ManagedAttachment.proxyMethod("attachment.getFilesize"); 8876 ManagedAttachment.proxyMethod("attachment.getFormattedFilesize"); 8877 ManagedAttachment.proxyMethod("attachment.getExtension"); 8878 ManagedAttachment.proxyMethod("attachment.getContentType"); 8879 ManagedAttachment.proxyMethod("attachment.getFile"); 8880 ManagedAttachment.proxyMethod("attachment.setFile"); 8881 ManagedAttachment.proxyMethod("attachment.releaseFile"); 8882 ManagedAttachment.proxyMethod("attachment.getUploadProgress"); 8883 ManagedAttachment.proxyMethod("attachment.setUploadProgress"); 8884 8885 class AttachmentManager extends BasicObject { 8886 constructor() { 8887 let attachments = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 8888 super(...arguments); 8889 this.managedAttachments = {}; 8890 Array.from(attachments).forEach(attachment => { 8891 this.manageAttachment(attachment); 8892 }); 8893 } 8894 getAttachments() { 8895 const result = []; 8896 for (const id in this.managedAttachments) { 8897 const attachment = this.managedAttachments[id]; 8898 result.push(attachment); 8899 } 8900 return result; 8901 } 8902 manageAttachment(attachment) { 8903 if (!this.managedAttachments[attachment.id]) { 8904 this.managedAttachments[attachment.id] = new ManagedAttachment(this, attachment); 8905 } 8906 return this.managedAttachments[attachment.id]; 8907 } 8908 attachmentIsManaged(attachment) { 8909 return attachment.id in this.managedAttachments; 8910 } 8911 requestRemovalOfAttachment(attachment) { 8912 if (this.attachmentIsManaged(attachment)) { 8913 var _this$delegate, _this$delegate$attach; 8914 return (_this$delegate = this.delegate) === null || _this$delegate === void 0 || (_this$delegate$attach = _this$delegate.attachmentManagerDidRequestRemovalOfAttachment) === null || _this$delegate$attach === void 0 ? void 0 : _this$delegate$attach.call(_this$delegate, attachment); 8915 } 8916 } 8917 unmanageAttachment(attachment) { 8918 const managedAttachment = this.managedAttachments[attachment.id]; 8919 delete this.managedAttachments[attachment.id]; 8920 return managedAttachment; 8921 } 8922 } 8923 8924 class LineBreakInsertion { 8925 constructor(composition) { 8926 this.composition = composition; 8927 this.document = this.composition.document; 8928 const selectedRange = this.composition.getSelectedRange(); 8929 this.startPosition = selectedRange[0]; 8930 this.endPosition = selectedRange[1]; 8931 this.startLocation = this.document.locationFromPosition(this.startPosition); 8932 this.endLocation = this.document.locationFromPosition(this.endPosition); 8933 this.block = this.document.getBlockAtIndex(this.endLocation.index); 8934 this.breaksOnReturn = this.block.breaksOnReturn(); 8935 this.previousCharacter = this.block.text.getStringAtPosition(this.endLocation.offset - 1); 8936 this.nextCharacter = this.block.text.getStringAtPosition(this.endLocation.offset); 8937 } 8938 shouldInsertBlockBreak() { 8939 if (this.block.hasAttributes() && this.block.isListItem() && !this.block.isEmpty()) { 8940 return this.startLocation.offset !== 0; 8941 } else { 8942 return this.breaksOnReturn && this.nextCharacter !== "\n"; 8943 } 8944 } 8945 shouldBreakFormattedBlock() { 8946 return this.block.hasAttributes() && !this.block.isListItem() && (this.breaksOnReturn && this.nextCharacter === "\n" || this.previousCharacter === "\n"); 8947 } 8948 shouldDecreaseListLevel() { 8949 return this.block.hasAttributes() && this.block.isListItem() && this.block.isEmpty(); 8950 } 8951 shouldPrependListItem() { 8952 return this.block.isListItem() && this.startLocation.offset === 0 && !this.block.isEmpty(); 8953 } 8954 shouldRemoveLastBlockAttribute() { 8955 return this.block.hasAttributes() && !this.block.isListItem() && this.block.isEmpty(); 8956 } 8957 } 8958 8959 const PLACEHOLDER = " "; 8960 class Composition extends BasicObject { 8961 constructor() { 8962 super(...arguments); 8963 this.document = new Document(); 8964 this.attachments = []; 8965 this.currentAttributes = {}; 8966 this.revision = 0; 8967 } 8968 setDocument(document) { 8969 if (!document.isEqualTo(this.document)) { 8970 var _this$delegate, _this$delegate$compos; 8971 this.document = document; 8972 this.refreshAttachments(); 8973 this.revision++; 8974 return (_this$delegate = this.delegate) === null || _this$delegate === void 0 || (_this$delegate$compos = _this$delegate.compositionDidChangeDocument) === null || _this$delegate$compos === void 0 ? void 0 : _this$delegate$compos.call(_this$delegate, document); 8975 } 8976 } 8977 8978 // Snapshots 8979 8980 getSnapshot() { 8981 return { 8982 document: this.document, 8983 selectedRange: this.getSelectedRange() 8984 }; 8985 } 8986 loadSnapshot(_ref) { 8987 var _this$delegate2, _this$delegate2$compo, _this$delegate3, _this$delegate3$compo; 8988 let { 8989 document, 8990 selectedRange 8991 } = _ref; 8992 (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || (_this$delegate2$compo = _this$delegate2.compositionWillLoadSnapshot) === null || _this$delegate2$compo === void 0 || _this$delegate2$compo.call(_this$delegate2); 8993 this.setDocument(document != null ? document : new Document()); 8994 this.setSelection(selectedRange != null ? selectedRange : [0, 0]); 8995 return (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || (_this$delegate3$compo = _this$delegate3.compositionDidLoadSnapshot) === null || _this$delegate3$compo === void 0 ? void 0 : _this$delegate3$compo.call(_this$delegate3); 8996 } 8997 8998 // Responder protocol 8999 9000 insertText(text) { 9001 let { 9002 updatePosition 9003 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { 9004 updatePosition: true 9005 }; 9006 const selectedRange = this.getSelectedRange(); 9007 this.setDocument(this.document.insertTextAtRange(text, selectedRange)); 9008 const startPosition = selectedRange[0]; 9009 const endPosition = startPosition + text.getLength(); 9010 if (updatePosition) { 9011 this.setSelection(endPosition); 9012 } 9013 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]); 9014 } 9015 insertBlock() { 9016 let block = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Block(); 9017 const document = new Document([block]); 9018 return this.insertDocument(document); 9019 } 9020 insertDocument() { 9021 let document = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Document(); 9022 const selectedRange = this.getSelectedRange(); 9023 this.setDocument(this.document.insertDocumentAtRange(document, selectedRange)); 9024 const startPosition = selectedRange[0]; 9025 const endPosition = startPosition + document.getLength(); 9026 this.setSelection(endPosition); 9027 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]); 9028 } 9029 insertString(string, options) { 9030 const attributes = this.getCurrentTextAttributes(); 9031 const text = Text.textForStringWithAttributes(string, attributes); 9032 return this.insertText(text, options); 9033 } 9034 insertBlockBreak() { 9035 const selectedRange = this.getSelectedRange(); 9036 this.setDocument(this.document.insertBlockBreakAtRange(selectedRange)); 9037 const startPosition = selectedRange[0]; 9038 const endPosition = startPosition + 1; 9039 this.setSelection(endPosition); 9040 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]); 9041 } 9042 insertLineBreak() { 9043 const insertion = new LineBreakInsertion(this); 9044 if (insertion.shouldDecreaseListLevel()) { 9045 this.decreaseListLevel(); 9046 return this.setSelection(insertion.startPosition); 9047 } else if (insertion.shouldPrependListItem()) { 9048 const document = new Document([insertion.block.copyWithoutText()]); 9049 return this.insertDocument(document); 9050 } else if (insertion.shouldInsertBlockBreak()) { 9051 return this.insertBlockBreak(); 9052 } else if (insertion.shouldRemoveLastBlockAttribute()) { 9053 return this.removeLastBlockAttribute(); 9054 } else if (insertion.shouldBreakFormattedBlock()) { 9055 return this.breakFormattedBlock(insertion); 9056 } else { 9057 return this.insertString("\n"); 9058 } 9059 } 9060 insertHTML(html) { 9061 const document = HTMLParser.parse(html, { 9062 purifyOptions: { 9063 SAFE_FOR_XML: true 9064 } 9065 }).getDocument(); 9066 const selectedRange = this.getSelectedRange(); 9067 this.setDocument(this.document.mergeDocumentAtRange(document, selectedRange)); 9068 const startPosition = selectedRange[0]; 9069 const endPosition = startPosition + document.getLength() - 1; 9070 this.setSelection(endPosition); 9071 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]); 9072 } 9073 replaceHTML(html) { 9074 const document = HTMLParser.parse(html).getDocument().copyUsingObjectsFromDocument(this.document); 9075 const locationRange = this.getLocationRange({ 9076 strict: false 9077 }); 9078 const selectedRange = this.document.rangeFromLocationRange(locationRange); 9079 this.setDocument(document); 9080 return this.setSelection(selectedRange); 9081 } 9082 insertFile(file) { 9083 return this.insertFiles([file]); 9084 } 9085 insertFiles(files) { 9086 const attachments = []; 9087 Array.from(files).forEach(file => { 9088 var _this$delegate4; 9089 if ((_this$delegate4 = this.delegate) !== null && _this$delegate4 !== void 0 && _this$delegate4.compositionShouldAcceptFile(file)) { 9090 const attachment = Attachment.attachmentForFile(file); 9091 attachments.push(attachment); 9092 } 9093 }); 9094 return this.insertAttachments(attachments); 9095 } 9096 insertAttachment(attachment) { 9097 return this.insertAttachments([attachment]); 9098 } 9099 insertAttachments(attachments$1) { 9100 let text = new Text(); 9101 Array.from(attachments$1).forEach(attachment => { 9102 var _config$attachments$t; 9103 const type = attachment.getType(); 9104 const presentation = (_config$attachments$t = attachments[type]) === null || _config$attachments$t === void 0 ? void 0 : _config$attachments$t.presentation; 9105 const attributes = this.getCurrentTextAttributes(); 9106 if (presentation) { 9107 attributes.presentation = presentation; 9108 } 9109 const attachmentText = Text.textForAttachmentWithAttributes(attachment, attributes); 9110 text = text.appendText(attachmentText); 9111 }); 9112 return this.insertText(text); 9113 } 9114 shouldManageDeletingInDirection(direction) { 9115 const locationRange = this.getLocationRange(); 9116 if (rangeIsCollapsed(locationRange)) { 9117 if (direction === "backward" && locationRange[0].offset === 0) { 9118 return true; 9119 } 9120 if (this.shouldManageMovingCursorInDirection(direction)) { 9121 return true; 9122 } 9123 } else { 9124 if (locationRange[0].index !== locationRange[1].index) { 9125 return true; 9126 } 9127 } 9128 return false; 9129 } 9130 deleteInDirection(direction) { 9131 let { 9132 length 9133 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 9134 let attachment, deletingIntoPreviousBlock, selectionSpansBlocks; 9135 const locationRange = this.getLocationRange(); 9136 let range = this.getSelectedRange(); 9137 const selectionIsCollapsed = rangeIsCollapsed(range); 9138 if (selectionIsCollapsed) { 9139 deletingIntoPreviousBlock = direction === "backward" && locationRange[0].offset === 0; 9140 } else { 9141 selectionSpansBlocks = locationRange[0].index !== locationRange[1].index; 9142 } 9143 if (deletingIntoPreviousBlock) { 9144 if (this.canDecreaseBlockAttributeLevel()) { 9145 const block = this.getBlock(); 9146 if (block.isListItem()) { 9147 this.decreaseListLevel(); 9148 } else { 9149 this.decreaseBlockAttributeLevel(); 9150 } 9151 this.setSelection(range[0]); 9152 if (block.isEmpty()) { 9153 return false; 9154 } 9155 } 9156 } 9157 if (selectionIsCollapsed) { 9158 range = this.getExpandedRangeInDirection(direction, { 9159 length 9160 }); 9161 if (direction === "backward") { 9162 attachment = this.getAttachmentAtRange(range); 9163 } 9164 } 9165 if (attachment) { 9166 this.editAttachment(attachment); 9167 return false; 9168 } else { 9169 this.setDocument(this.document.removeTextAtRange(range)); 9170 this.setSelection(range[0]); 9171 if (deletingIntoPreviousBlock || selectionSpansBlocks) { 9172 return false; 9173 } 9174 } 9175 } 9176 moveTextFromRange(range) { 9177 const [position] = Array.from(this.getSelectedRange()); 9178 this.setDocument(this.document.moveTextFromRangeToPosition(range, position)); 9179 return this.setSelection(position); 9180 } 9181 removeAttachment(attachment) { 9182 const range = this.document.getRangeOfAttachment(attachment); 9183 if (range) { 9184 this.stopEditingAttachment(); 9185 this.setDocument(this.document.removeTextAtRange(range)); 9186 return this.setSelection(range[0]); 9187 } 9188 } 9189 removeLastBlockAttribute() { 9190 const [startPosition, endPosition] = Array.from(this.getSelectedRange()); 9191 const block = this.document.getBlockAtPosition(endPosition); 9192 this.removeCurrentAttribute(block.getLastAttribute()); 9193 return this.setSelection(startPosition); 9194 } 9195 insertPlaceholder() { 9196 this.placeholderPosition = this.getPosition(); 9197 return this.insertString(PLACEHOLDER); 9198 } 9199 selectPlaceholder() { 9200 if (this.placeholderPosition != null) { 9201 this.setSelectedRange([this.placeholderPosition, this.placeholderPosition + PLACEHOLDER.length]); 9202 return this.getSelectedRange(); 9203 } 9204 } 9205 forgetPlaceholder() { 9206 this.placeholderPosition = null; 9207 } 9208 9209 // Current attributes 9210 9211 hasCurrentAttribute(attributeName) { 9212 const value = this.currentAttributes[attributeName]; 9213 return value != null && value !== false; 9214 } 9215 toggleCurrentAttribute(attributeName) { 9216 const value = !this.currentAttributes[attributeName]; 9217 if (value) { 9218 return this.setCurrentAttribute(attributeName, value); 9219 } else { 9220 return this.removeCurrentAttribute(attributeName); 9221 } 9222 } 9223 canSetCurrentAttribute(attributeName) { 9224 if (getBlockConfig(attributeName)) { 9225 return this.canSetCurrentBlockAttribute(attributeName); 9226 } else { 9227 return this.canSetCurrentTextAttribute(attributeName); 9228 } 9229 } 9230 canSetCurrentTextAttribute(attributeName) { 9231 const document = this.getSelectedDocument(); 9232 if (!document) return; 9233 for (const attachment of Array.from(document.getAttachments())) { 9234 if (!attachment.hasContent()) { 9235 return false; 9236 } 9237 } 9238 return true; 9239 } 9240 canSetCurrentBlockAttribute(attributeName) { 9241 const block = this.getBlock(); 9242 if (!block) return; 9243 return !block.isTerminalBlock(); 9244 } 9245 setCurrentAttribute(attributeName, value) { 9246 if (getBlockConfig(attributeName)) { 9247 return this.setBlockAttribute(attributeName, value); 9248 } else { 9249 this.setTextAttribute(attributeName, value); 9250 this.currentAttributes[attributeName] = value; 9251 return this.notifyDelegateOfCurrentAttributesChange(); 9252 } 9253 } 9254 setHTMLAtributeAtPosition(position, attributeName, value) { 9255 var _getBlockConfig; 9256 const block = this.document.getBlockAtPosition(position); 9257 const allowedHTMLAttributes = (_getBlockConfig = getBlockConfig(block.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.htmlAttributes; 9258 if (block && allowedHTMLAttributes !== null && allowedHTMLAttributes !== void 0 && allowedHTMLAttributes.includes(attributeName)) { 9259 const newDocument = this.document.setHTMLAttributeAtPosition(position, attributeName, value); 9260 this.setDocument(newDocument); 9261 } 9262 } 9263 setTextAttribute(attributeName, value) { 9264 const selectedRange = this.getSelectedRange(); 9265 if (!selectedRange) return; 9266 const [startPosition, endPosition] = Array.from(selectedRange); 9267 if (startPosition === endPosition) { 9268 if (attributeName === "href") { 9269 const text = Text.textForStringWithAttributes(value, { 9270 href: value 9271 }); 9272 return this.insertText(text); 9273 } 9274 } else { 9275 return this.setDocument(this.document.addAttributeAtRange(attributeName, value, selectedRange)); 9276 } 9277 } 9278 setBlockAttribute(attributeName, value) { 9279 const selectedRange = this.getSelectedRange(); 9280 if (this.canSetCurrentAttribute(attributeName)) { 9281 this.setDocument(this.document.applyBlockAttributeAtRange(attributeName, value, selectedRange)); 9282 return this.setSelection(selectedRange); 9283 } 9284 } 9285 removeCurrentAttribute(attributeName) { 9286 if (getBlockConfig(attributeName)) { 9287 this.removeBlockAttribute(attributeName); 9288 return this.updateCurrentAttributes(); 9289 } else { 9290 this.removeTextAttribute(attributeName); 9291 delete this.currentAttributes[attributeName]; 9292 return this.notifyDelegateOfCurrentAttributesChange(); 9293 } 9294 } 9295 removeTextAttribute(attributeName) { 9296 const selectedRange = this.getSelectedRange(); 9297 if (!selectedRange) return; 9298 return this.setDocument(this.document.removeAttributeAtRange(attributeName, selectedRange)); 9299 } 9300 removeBlockAttribute(attributeName) { 9301 const selectedRange = this.getSelectedRange(); 9302 if (!selectedRange) return; 9303 return this.setDocument(this.document.removeAttributeAtRange(attributeName, selectedRange)); 9304 } 9305 canDecreaseNestingLevel() { 9306 var _this$getBlock; 9307 return ((_this$getBlock = this.getBlock()) === null || _this$getBlock === void 0 ? void 0 : _this$getBlock.getNestingLevel()) > 0; 9308 } 9309 canIncreaseNestingLevel() { 9310 var _getBlockConfig2; 9311 const block = this.getBlock(); 9312 if (!block) return; 9313 if ((_getBlockConfig2 = getBlockConfig(block.getLastNestableAttribute())) !== null && _getBlockConfig2 !== void 0 && _getBlockConfig2.listAttribute) { 9314 const previousBlock = this.getPreviousBlock(); 9315 if (previousBlock) { 9316 return arrayStartsWith(previousBlock.getListItemAttributes(), block.getListItemAttributes()); 9317 } 9318 } else { 9319 return block.getNestingLevel() > 0; 9320 } 9321 } 9322 decreaseNestingLevel() { 9323 const block = this.getBlock(); 9324 if (!block) return; 9325 return this.setDocument(this.document.replaceBlock(block, block.decreaseNestingLevel())); 9326 } 9327 increaseNestingLevel() { 9328 const block = this.getBlock(); 9329 if (!block) return; 9330 return this.setDocument(this.document.replaceBlock(block, block.increaseNestingLevel())); 9331 } 9332 canDecreaseBlockAttributeLevel() { 9333 var _this$getBlock2; 9334 return ((_this$getBlock2 = this.getBlock()) === null || _this$getBlock2 === void 0 ? void 0 : _this$getBlock2.getAttributeLevel()) > 0; 9335 } 9336 decreaseBlockAttributeLevel() { 9337 var _this$getBlock3; 9338 const attribute = (_this$getBlock3 = this.getBlock()) === null || _this$getBlock3 === void 0 ? void 0 : _this$getBlock3.getLastAttribute(); 9339 if (attribute) { 9340 return this.removeCurrentAttribute(attribute); 9341 } 9342 } 9343 decreaseListLevel() { 9344 let [startPosition] = Array.from(this.getSelectedRange()); 9345 const { 9346 index 9347 } = this.document.locationFromPosition(startPosition); 9348 let endIndex = index; 9349 const attributeLevel = this.getBlock().getAttributeLevel(); 9350 let block = this.document.getBlockAtIndex(endIndex + 1); 9351 while (block) { 9352 if (!block.isListItem() || block.getAttributeLevel() <= attributeLevel) { 9353 break; 9354 } 9355 endIndex++; 9356 block = this.document.getBlockAtIndex(endIndex + 1); 9357 } 9358 startPosition = this.document.positionFromLocation({ 9359 index, 9360 offset: 0 9361 }); 9362 const endPosition = this.document.positionFromLocation({ 9363 index: endIndex, 9364 offset: 0 9365 }); 9366 return this.setDocument(this.document.removeLastListAttributeAtRange([startPosition, endPosition])); 9367 } 9368 updateCurrentAttributes() { 9369 const selectedRange = this.getSelectedRange({ 9370 ignoreLock: true 9371 }); 9372 if (selectedRange) { 9373 const currentAttributes = this.document.getCommonAttributesAtRange(selectedRange); 9374 Array.from(getAllAttributeNames()).forEach(attributeName => { 9375 if (!currentAttributes[attributeName]) { 9376 if (!this.canSetCurrentAttribute(attributeName)) { 9377 currentAttributes[attributeName] = false; 9378 } 9379 } 9380 }); 9381 if (!objectsAreEqual(currentAttributes, this.currentAttributes)) { 9382 this.currentAttributes = currentAttributes; 9383 return this.notifyDelegateOfCurrentAttributesChange(); 9384 } 9385 } 9386 } 9387 getCurrentAttributes() { 9388 return extend.call({}, this.currentAttributes); 9389 } 9390 getCurrentTextAttributes() { 9391 const attributes = {}; 9392 for (const key in this.currentAttributes) { 9393 const value = this.currentAttributes[key]; 9394 if (value !== false) { 9395 if (getTextConfig(key)) { 9396 attributes[key] = value; 9397 } 9398 } 9399 } 9400 return attributes; 9401 } 9402 9403 // Selection freezing 9404 9405 freezeSelection() { 9406 return this.setCurrentAttribute("frozen", true); 9407 } 9408 thawSelection() { 9409 return this.removeCurrentAttribute("frozen"); 9410 } 9411 hasFrozenSelection() { 9412 return this.hasCurrentAttribute("frozen"); 9413 } 9414 setSelection(selectedRange) { 9415 var _this$delegate5; 9416 const locationRange = this.document.locationRangeFromRange(selectedRange); 9417 return (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 ? void 0 : _this$delegate5.compositionDidRequestChangingSelectionToLocationRange(locationRange); 9418 } 9419 getSelectedRange() { 9420 const locationRange = this.getLocationRange(); 9421 if (locationRange) { 9422 return this.document.rangeFromLocationRange(locationRange); 9423 } 9424 } 9425 setSelectedRange(selectedRange) { 9426 const locationRange = this.document.locationRangeFromRange(selectedRange); 9427 return this.getSelectionManager().setLocationRange(locationRange); 9428 } 9429 getPosition() { 9430 const locationRange = this.getLocationRange(); 9431 if (locationRange) { 9432 return this.document.positionFromLocation(locationRange[0]); 9433 } 9434 } 9435 getLocationRange(options) { 9436 if (this.targetLocationRange) { 9437 return this.targetLocationRange; 9438 } else { 9439 return this.getSelectionManager().getLocationRange(options) || normalizeRange({ 9440 index: 0, 9441 offset: 0 9442 }); 9443 } 9444 } 9445 withTargetLocationRange(locationRange, fn) { 9446 let result; 9447 this.targetLocationRange = locationRange; 9448 try { 9449 result = fn(); 9450 } finally { 9451 this.targetLocationRange = null; 9452 } 9453 return result; 9454 } 9455 withTargetRange(range, fn) { 9456 const locationRange = this.document.locationRangeFromRange(range); 9457 return this.withTargetLocationRange(locationRange, fn); 9458 } 9459 withTargetDOMRange(domRange, fn) { 9460 const locationRange = this.createLocationRangeFromDOMRange(domRange, { 9461 strict: false 9462 }); 9463 return this.withTargetLocationRange(locationRange, fn); 9464 } 9465 getExpandedRangeInDirection(direction) { 9466 let { 9467 length 9468 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 9469 let [startPosition, endPosition] = Array.from(this.getSelectedRange()); 9470 if (direction === "backward") { 9471 if (length) { 9472 startPosition -= length; 9473 } else { 9474 startPosition = this.translateUTF16PositionFromOffset(startPosition, -1); 9475 } 9476 } else { 9477 if (length) { 9478 endPosition += length; 9479 } else { 9480 endPosition = this.translateUTF16PositionFromOffset(endPosition, 1); 9481 } 9482 } 9483 return normalizeRange([startPosition, endPosition]); 9484 } 9485 shouldManageMovingCursorInDirection(direction) { 9486 if (this.editingAttachment) { 9487 return true; 9488 } 9489 const range = this.getExpandedRangeInDirection(direction); 9490 return this.getAttachmentAtRange(range) != null; 9491 } 9492 moveCursorInDirection(direction) { 9493 let canEditAttachment, range; 9494 if (this.editingAttachment) { 9495 range = this.document.getRangeOfAttachment(this.editingAttachment); 9496 } else { 9497 const selectedRange = this.getSelectedRange(); 9498 range = this.getExpandedRangeInDirection(direction); 9499 canEditAttachment = !rangesAreEqual(selectedRange, range); 9500 } 9501 if (direction === "backward") { 9502 this.setSelectedRange(range[0]); 9503 } else { 9504 this.setSelectedRange(range[1]); 9505 } 9506 if (canEditAttachment) { 9507 const attachment = this.getAttachmentAtRange(range); 9508 if (attachment) { 9509 return this.editAttachment(attachment); 9510 } 9511 } 9512 } 9513 expandSelectionInDirection(direction) { 9514 let { 9515 length 9516 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 9517 const range = this.getExpandedRangeInDirection(direction, { 9518 length 9519 }); 9520 return this.setSelectedRange(range); 9521 } 9522 expandSelectionForEditing() { 9523 if (this.hasCurrentAttribute("href")) { 9524 return this.expandSelectionAroundCommonAttribute("href"); 9525 } 9526 } 9527 expandSelectionAroundCommonAttribute(attributeName) { 9528 const position = this.getPosition(); 9529 const range = this.document.getRangeOfCommonAttributeAtPosition(attributeName, position); 9530 return this.setSelectedRange(range); 9531 } 9532 selectionContainsAttachments() { 9533 var _this$getSelectedAtta; 9534 return ((_this$getSelectedAtta = this.getSelectedAttachments()) === null || _this$getSelectedAtta === void 0 ? void 0 : _this$getSelectedAtta.length) > 0; 9535 } 9536 selectionIsInCursorTarget() { 9537 return this.editingAttachment || this.positionIsCursorTarget(this.getPosition()); 9538 } 9539 positionIsCursorTarget(position) { 9540 const location = this.document.locationFromPosition(position); 9541 if (location) { 9542 return this.locationIsCursorTarget(location); 9543 } 9544 } 9545 positionIsBlockBreak(position) { 9546 var _this$document$getPie; 9547 return (_this$document$getPie = this.document.getPieceAtPosition(position)) === null || _this$document$getPie === void 0 ? void 0 : _this$document$getPie.isBlockBreak(); 9548 } 9549 getSelectedDocument() { 9550 const selectedRange = this.getSelectedRange(); 9551 if (selectedRange) { 9552 return this.document.getDocumentAtRange(selectedRange); 9553 } 9554 } 9555 getSelectedAttachments() { 9556 var _this$getSelectedDocu; 9557 return (_this$getSelectedDocu = this.getSelectedDocument()) === null || _this$getSelectedDocu === void 0 ? void 0 : _this$getSelectedDocu.getAttachments(); 9558 } 9559 9560 // Attachments 9561 9562 getAttachments() { 9563 return this.attachments.slice(0); 9564 } 9565 refreshAttachments() { 9566 const attachments = this.document.getAttachments(); 9567 const { 9568 added, 9569 removed 9570 } = summarizeArrayChange(this.attachments, attachments); 9571 this.attachments = attachments; 9572 Array.from(removed).forEach(attachment => { 9573 var _this$delegate6, _this$delegate6$compo; 9574 attachment.delegate = null; 9575 (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 || (_this$delegate6$compo = _this$delegate6.compositionDidRemoveAttachment) === null || _this$delegate6$compo === void 0 || _this$delegate6$compo.call(_this$delegate6, attachment); 9576 }); 9577 return (() => { 9578 const result = []; 9579 Array.from(added).forEach(attachment => { 9580 var _this$delegate7, _this$delegate7$compo; 9581 attachment.delegate = this; 9582 result.push((_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || (_this$delegate7$compo = _this$delegate7.compositionDidAddAttachment) === null || _this$delegate7$compo === void 0 ? void 0 : _this$delegate7$compo.call(_this$delegate7, attachment)); 9583 }); 9584 return result; 9585 })(); 9586 } 9587 9588 // Attachment delegate 9589 9590 attachmentDidChangeAttributes(attachment) { 9591 var _this$delegate8, _this$delegate8$compo; 9592 this.revision++; 9593 return (_this$delegate8 = this.delegate) === null || _this$delegate8 === void 0 || (_this$delegate8$compo = _this$delegate8.compositionDidEditAttachment) === null || _this$delegate8$compo === void 0 ? void 0 : _this$delegate8$compo.call(_this$delegate8, attachment); 9594 } 9595 attachmentDidChangePreviewURL(attachment) { 9596 var _this$delegate9, _this$delegate9$compo; 9597 this.revision++; 9598 return (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 || (_this$delegate9$compo = _this$delegate9.compositionDidChangeAttachmentPreviewURL) === null || _this$delegate9$compo === void 0 ? void 0 : _this$delegate9$compo.call(_this$delegate9, attachment); 9599 } 9600 9601 // Attachment editing 9602 9603 editAttachment(attachment, options) { 9604 var _this$delegate10, _this$delegate10$comp; 9605 if (attachment === this.editingAttachment) return; 9606 this.stopEditingAttachment(); 9607 this.editingAttachment = attachment; 9608 return (_this$delegate10 = this.delegate) === null || _this$delegate10 === void 0 || (_this$delegate10$comp = _this$delegate10.compositionDidStartEditingAttachment) === null || _this$delegate10$comp === void 0 ? void 0 : _this$delegate10$comp.call(_this$delegate10, this.editingAttachment, options); 9609 } 9610 stopEditingAttachment() { 9611 var _this$delegate11, _this$delegate11$comp; 9612 if (!this.editingAttachment) return; 9613 (_this$delegate11 = this.delegate) === null || _this$delegate11 === void 0 || (_this$delegate11$comp = _this$delegate11.compositionDidStopEditingAttachment) === null || _this$delegate11$comp === void 0 || _this$delegate11$comp.call(_this$delegate11, this.editingAttachment); 9614 this.editingAttachment = null; 9615 } 9616 updateAttributesForAttachment(attributes, attachment) { 9617 return this.setDocument(this.document.updateAttributesForAttachment(attributes, attachment)); 9618 } 9619 removeAttributeForAttachment(attribute, attachment) { 9620 return this.setDocument(this.document.removeAttributeForAttachment(attribute, attachment)); 9621 } 9622 9623 // Private 9624 9625 breakFormattedBlock(insertion) { 9626 let { 9627 document 9628 } = insertion; 9629 const { 9630 block 9631 } = insertion; 9632 let position = insertion.startPosition; 9633 let range = [position - 1, position]; 9634 if (block.getBlockBreakPosition() === insertion.startLocation.offset) { 9635 if (block.breaksOnReturn() && insertion.nextCharacter === "\n") { 9636 position += 1; 9637 } else { 9638 document = document.removeTextAtRange(range); 9639 } 9640 range = [position, position]; 9641 } else if (insertion.nextCharacter === "\n") { 9642 if (insertion.previousCharacter === "\n") { 9643 range = [position - 1, position + 1]; 9644 } else { 9645 range = [position, position + 1]; 9646 position += 1; 9647 } 9648 } else if (insertion.startLocation.offset - 1 !== 0) { 9649 position += 1; 9650 } 9651 const newDocument = new Document([block.removeLastAttribute().copyWithoutText()]); 9652 this.setDocument(document.insertDocumentAtRange(newDocument, range)); 9653 return this.setSelection(position); 9654 } 9655 getPreviousBlock() { 9656 const locationRange = this.getLocationRange(); 9657 if (locationRange) { 9658 const { 9659 index 9660 } = locationRange[0]; 9661 if (index > 0) { 9662 return this.document.getBlockAtIndex(index - 1); 9663 } 9664 } 9665 } 9666 getBlock() { 9667 const locationRange = this.getLocationRange(); 9668 if (locationRange) { 9669 return this.document.getBlockAtIndex(locationRange[0].index); 9670 } 9671 } 9672 getAttachmentAtRange(range) { 9673 const document = this.document.getDocumentAtRange(range); 9674 if (document.toString() === "".concat(OBJECT_REPLACEMENT_CHARACTER, "\n")) { 9675 return document.getAttachments()[0]; 9676 } 9677 } 9678 notifyDelegateOfCurrentAttributesChange() { 9679 var _this$delegate12, _this$delegate12$comp; 9680 return (_this$delegate12 = this.delegate) === null || _this$delegate12 === void 0 || (_this$delegate12$comp = _this$delegate12.compositionDidChangeCurrentAttributes) === null || _this$delegate12$comp === void 0 ? void 0 : _this$delegate12$comp.call(_this$delegate12, this.currentAttributes); 9681 } 9682 notifyDelegateOfInsertionAtRange(range) { 9683 var _this$delegate13, _this$delegate13$comp; 9684 return (_this$delegate13 = this.delegate) === null || _this$delegate13 === void 0 || (_this$delegate13$comp = _this$delegate13.compositionDidPerformInsertionAtRange) === null || _this$delegate13$comp === void 0 ? void 0 : _this$delegate13$comp.call(_this$delegate13, range); 9685 } 9686 translateUTF16PositionFromOffset(position, offset) { 9687 const utf16string = this.document.toUTF16String(); 9688 const utf16position = utf16string.offsetFromUCS2Offset(position); 9689 return utf16string.offsetToUCS2Offset(utf16position + offset); 9690 } 9691 } 9692 Composition.proxyMethod("getSelectionManager().getPointRange"); 9693 Composition.proxyMethod("getSelectionManager().setLocationRangeFromPointRange"); 9694 Composition.proxyMethod("getSelectionManager().createLocationRangeFromDOMRange"); 9695 Composition.proxyMethod("getSelectionManager().locationIsCursorTarget"); 9696 Composition.proxyMethod("getSelectionManager().selectionIsExpanded"); 9697 Composition.proxyMethod("delegate?.getSelectionManager"); 9698 9699 class UndoManager extends BasicObject { 9700 constructor(composition) { 9701 super(...arguments); 9702 this.composition = composition; 9703 this.undoEntries = []; 9704 this.redoEntries = []; 9705 } 9706 recordUndoEntry(description) { 9707 let { 9708 context, 9709 consolidatable 9710 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 9711 const previousEntry = this.undoEntries.slice(-1)[0]; 9712 if (!consolidatable || !entryHasDescriptionAndContext(previousEntry, description, context)) { 9713 const undoEntry = this.createEntry({ 9714 description, 9715 context 9716 }); 9717 this.undoEntries.push(undoEntry); 9718 this.redoEntries = []; 9719 } 9720 } 9721 undo() { 9722 const undoEntry = this.undoEntries.pop(); 9723 if (undoEntry) { 9724 const redoEntry = this.createEntry(undoEntry); 9725 this.redoEntries.push(redoEntry); 9726 return this.composition.loadSnapshot(undoEntry.snapshot); 9727 } 9728 } 9729 redo() { 9730 const redoEntry = this.redoEntries.pop(); 9731 if (redoEntry) { 9732 const undoEntry = this.createEntry(redoEntry); 9733 this.undoEntries.push(undoEntry); 9734 return this.composition.loadSnapshot(redoEntry.snapshot); 9735 } 9736 } 9737 canUndo() { 9738 return this.undoEntries.length > 0; 9739 } 9740 canRedo() { 9741 return this.redoEntries.length > 0; 9742 } 9743 9744 // Private 9745 9746 createEntry() { 9747 let { 9748 description, 9749 context 9750 } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 9751 return { 9752 description: description === null || description === void 0 ? void 0 : description.toString(), 9753 context: JSON.stringify(context), 9754 snapshot: this.composition.getSnapshot() 9755 }; 9756 } 9757 } 9758 const entryHasDescriptionAndContext = (entry, description, context) => (entry === null || entry === void 0 ? void 0 : entry.description) === (description === null || description === void 0 ? void 0 : description.toString()) && (entry === null || entry === void 0 ? void 0 : entry.context) === JSON.stringify(context); 9759 9760 const BLOCK_ATTRIBUTE_NAME = "attachmentGallery"; 9761 const TEXT_ATTRIBUTE_NAME = "presentation"; 9762 const TEXT_ATTRIBUTE_VALUE = "gallery"; 9763 class Filter { 9764 constructor(snapshot) { 9765 this.document = snapshot.document; 9766 this.selectedRange = snapshot.selectedRange; 9767 } 9768 perform() { 9769 this.removeBlockAttribute(); 9770 return this.applyBlockAttribute(); 9771 } 9772 getSnapshot() { 9773 return { 9774 document: this.document, 9775 selectedRange: this.selectedRange 9776 }; 9777 } 9778 9779 // Private 9780 9781 removeBlockAttribute() { 9782 return this.findRangesOfBlocks().map(range => this.document = this.document.removeAttributeAtRange(BLOCK_ATTRIBUTE_NAME, range)); 9783 } 9784 applyBlockAttribute() { 9785 let offset = 0; 9786 this.findRangesOfPieces().forEach(range => { 9787 if (range[1] - range[0] > 1) { 9788 range[0] += offset; 9789 range[1] += offset; 9790 if (this.document.getCharacterAtPosition(range[1]) !== "\n") { 9791 this.document = this.document.insertBlockBreakAtRange(range[1]); 9792 if (range[1] < this.selectedRange[1]) { 9793 this.moveSelectedRangeForward(); 9794 } 9795 range[1]++; 9796 offset++; 9797 } 9798 if (range[0] !== 0) { 9799 if (this.document.getCharacterAtPosition(range[0] - 1) !== "\n") { 9800 this.document = this.document.insertBlockBreakAtRange(range[0]); 9801 if (range[0] < this.selectedRange[0]) { 9802 this.moveSelectedRangeForward(); 9803 } 9804 range[0]++; 9805 offset++; 9806 } 9807 } 9808 this.document = this.document.applyBlockAttributeAtRange(BLOCK_ATTRIBUTE_NAME, true, range); 9809 } 9810 }); 9811 } 9812 findRangesOfBlocks() { 9813 return this.document.findRangesForBlockAttribute(BLOCK_ATTRIBUTE_NAME); 9814 } 9815 findRangesOfPieces() { 9816 return this.document.findRangesForTextAttribute(TEXT_ATTRIBUTE_NAME, { 9817 withValue: TEXT_ATTRIBUTE_VALUE 9818 }); 9819 } 9820 moveSelectedRangeForward() { 9821 this.selectedRange[0] += 1; 9822 this.selectedRange[1] += 1; 9823 } 9824 } 9825 9826 const attachmentGalleryFilter = function (snapshot) { 9827 const filter = new Filter(snapshot); 9828 filter.perform(); 9829 return filter.getSnapshot(); 9830 }; 9831 9832 const DEFAULT_FILTERS = [attachmentGalleryFilter]; 9833 class Editor { 9834 constructor(composition, selectionManager, element) { 9835 this.insertFiles = this.insertFiles.bind(this); 9836 this.composition = composition; 9837 this.selectionManager = selectionManager; 9838 this.element = element; 9839 this.undoManager = new UndoManager(this.composition); 9840 this.filters = DEFAULT_FILTERS.slice(0); 9841 } 9842 loadDocument(document) { 9843 return this.loadSnapshot({ 9844 document, 9845 selectedRange: [0, 0] 9846 }); 9847 } 9848 loadHTML() { 9849 let html = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; 9850 const document = HTMLParser.parse(html, { 9851 referenceElement: this.element 9852 }).getDocument(); 9853 return this.loadDocument(document); 9854 } 9855 loadJSON(_ref) { 9856 let { 9857 document, 9858 selectedRange 9859 } = _ref; 9860 document = Document.fromJSON(document); 9861 return this.loadSnapshot({ 9862 document, 9863 selectedRange 9864 }); 9865 } 9866 loadSnapshot(snapshot) { 9867 this.undoManager = new UndoManager(this.composition); 9868 return this.composition.loadSnapshot(snapshot); 9869 } 9870 getDocument() { 9871 return this.composition.document; 9872 } 9873 getSelectedDocument() { 9874 return this.composition.getSelectedDocument(); 9875 } 9876 getSnapshot() { 9877 return this.composition.getSnapshot(); 9878 } 9879 toJSON() { 9880 return this.getSnapshot(); 9881 } 9882 9883 // Document manipulation 9884 9885 deleteInDirection(direction) { 9886 return this.composition.deleteInDirection(direction); 9887 } 9888 insertAttachment(attachment) { 9889 return this.composition.insertAttachment(attachment); 9890 } 9891 insertAttachments(attachments) { 9892 return this.composition.insertAttachments(attachments); 9893 } 9894 insertDocument(document) { 9895 return this.composition.insertDocument(document); 9896 } 9897 insertFile(file) { 9898 return this.composition.insertFile(file); 9899 } 9900 insertFiles(files) { 9901 return this.composition.insertFiles(files); 9902 } 9903 insertHTML(html) { 9904 return this.composition.insertHTML(html); 9905 } 9906 insertString(string) { 9907 return this.composition.insertString(string); 9908 } 9909 insertText(text) { 9910 return this.composition.insertText(text); 9911 } 9912 insertLineBreak() { 9913 return this.composition.insertLineBreak(); 9914 } 9915 9916 // Selection 9917 9918 getSelectedRange() { 9919 return this.composition.getSelectedRange(); 9920 } 9921 getPosition() { 9922 return this.composition.getPosition(); 9923 } 9924 getClientRectAtPosition(position) { 9925 const locationRange = this.getDocument().locationRangeFromRange([position, position + 1]); 9926 return this.selectionManager.getClientRectAtLocationRange(locationRange); 9927 } 9928 expandSelectionInDirection(direction) { 9929 return this.composition.expandSelectionInDirection(direction); 9930 } 9931 moveCursorInDirection(direction) { 9932 return this.composition.moveCursorInDirection(direction); 9933 } 9934 setSelectedRange(selectedRange) { 9935 return this.composition.setSelectedRange(selectedRange); 9936 } 9937 9938 // Attributes 9939 9940 activateAttribute(name) { 9941 let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 9942 return this.composition.setCurrentAttribute(name, value); 9943 } 9944 attributeIsActive(name) { 9945 return this.composition.hasCurrentAttribute(name); 9946 } 9947 canActivateAttribute(name) { 9948 return this.composition.canSetCurrentAttribute(name); 9949 } 9950 deactivateAttribute(name) { 9951 return this.composition.removeCurrentAttribute(name); 9952 } 9953 9954 // HTML attributes 9955 setHTMLAtributeAtPosition(position, name, value) { 9956 this.composition.setHTMLAtributeAtPosition(position, name, value); 9957 } 9958 9959 // Nesting level 9960 9961 canDecreaseNestingLevel() { 9962 return this.composition.canDecreaseNestingLevel(); 9963 } 9964 canIncreaseNestingLevel() { 9965 return this.composition.canIncreaseNestingLevel(); 9966 } 9967 decreaseNestingLevel() { 9968 if (this.canDecreaseNestingLevel()) { 9969 return this.composition.decreaseNestingLevel(); 9970 } 9971 } 9972 increaseNestingLevel() { 9973 if (this.canIncreaseNestingLevel()) { 9974 return this.composition.increaseNestingLevel(); 9975 } 9976 } 9977 9978 // Undo/redo 9979 9980 canRedo() { 9981 return this.undoManager.canRedo(); 9982 } 9983 canUndo() { 9984 return this.undoManager.canUndo(); 9985 } 9986 recordUndoEntry(description) { 9987 let { 9988 context, 9989 consolidatable 9990 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 9991 return this.undoManager.recordUndoEntry(description, { 9992 context, 9993 consolidatable 9994 }); 9995 } 9996 redo() { 9997 if (this.canRedo()) { 9998 return this.undoManager.redo(); 9999 } 10000 } 10001 undo() { 10002 if (this.canUndo()) { 10003 return this.undoManager.undo(); 10004 } 10005 } 10006 } 10007 10008 /* eslint-disable 10009 no-var, 10010 prefer-const, 10011 */ 10012 class LocationMapper { 10013 constructor(element) { 10014 this.element = element; 10015 } 10016 findLocationFromContainerAndOffset(container, offset) { 10017 let { 10018 strict 10019 } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { 10020 strict: true 10021 }; 10022 let childIndex = 0; 10023 let foundBlock = false; 10024 const location = { 10025 index: 0, 10026 offset: 0 10027 }; 10028 const attachmentElement = this.findAttachmentElementParentForNode(container); 10029 if (attachmentElement) { 10030 container = attachmentElement.parentNode; 10031 offset = findChildIndexOfNode(attachmentElement); 10032 } 10033 const walker = walkTree(this.element, { 10034 usingFilter: rejectAttachmentContents 10035 }); 10036 while (walker.nextNode()) { 10037 const node = walker.currentNode; 10038 if (node === container && nodeIsTextNode(container)) { 10039 if (!nodeIsCursorTarget(node)) { 10040 location.offset += offset; 10041 } 10042 break; 10043 } else { 10044 if (node.parentNode === container) { 10045 if (childIndex++ === offset) { 10046 break; 10047 } 10048 } else if (!elementContainsNode(container, node)) { 10049 if (childIndex > 0) { 10050 break; 10051 } 10052 } 10053 if (nodeIsBlockStart(node, { 10054 strict 10055 })) { 10056 if (foundBlock) { 10057 location.index++; 10058 } 10059 location.offset = 0; 10060 foundBlock = true; 10061 } else { 10062 location.offset += nodeLength(node); 10063 } 10064 } 10065 } 10066 return location; 10067 } 10068 findContainerAndOffsetFromLocation(location) { 10069 let container, offset; 10070 if (location.index === 0 && location.offset === 0) { 10071 container = this.element; 10072 offset = 0; 10073 while (container.firstChild) { 10074 container = container.firstChild; 10075 if (nodeIsBlockContainer(container)) { 10076 offset = 1; 10077 break; 10078 } 10079 } 10080 return [container, offset]; 10081 } 10082 let [node, nodeOffset] = this.findNodeAndOffsetFromLocation(location); 10083 if (!node) return; 10084 if (nodeIsTextNode(node)) { 10085 if (nodeLength(node) === 0) { 10086 container = node.parentNode.parentNode; 10087 offset = findChildIndexOfNode(node.parentNode); 10088 if (nodeIsCursorTarget(node, { 10089 name: "right" 10090 })) { 10091 offset++; 10092 } 10093 } else { 10094 container = node; 10095 offset = location.offset - nodeOffset; 10096 } 10097 } else { 10098 container = node.parentNode; 10099 if (!nodeIsBlockStart(node.previousSibling)) { 10100 if (!nodeIsBlockContainer(container)) { 10101 while (node === container.lastChild) { 10102 node = container; 10103 container = container.parentNode; 10104 if (nodeIsBlockContainer(container)) { 10105 break; 10106 } 10107 } 10108 } 10109 } 10110 offset = findChildIndexOfNode(node); 10111 if (location.offset !== 0) { 10112 offset++; 10113 } 10114 } 10115 return [container, offset]; 10116 } 10117 findNodeAndOffsetFromLocation(location) { 10118 let node, nodeOffset; 10119 let offset = 0; 10120 for (const currentNode of this.getSignificantNodesForIndex(location.index)) { 10121 const length = nodeLength(currentNode); 10122 if (location.offset <= offset + length) { 10123 if (nodeIsTextNode(currentNode)) { 10124 node = currentNode; 10125 nodeOffset = offset; 10126 if (location.offset === nodeOffset && nodeIsCursorTarget(node)) { 10127 break; 10128 } 10129 } else if (!node) { 10130 node = currentNode; 10131 nodeOffset = offset; 10132 } 10133 } 10134 offset += length; 10135 if (offset > location.offset) { 10136 break; 10137 } 10138 } 10139 return [node, nodeOffset]; 10140 } 10141 10142 // Private 10143 10144 findAttachmentElementParentForNode(node) { 10145 while (node && node !== this.element) { 10146 if (nodeIsAttachmentElement(node)) { 10147 return node; 10148 } 10149 node = node.parentNode; 10150 } 10151 } 10152 getSignificantNodesForIndex(index) { 10153 const nodes = []; 10154 const walker = walkTree(this.element, { 10155 usingFilter: acceptSignificantNodes 10156 }); 10157 let recordingNodes = false; 10158 while (walker.nextNode()) { 10159 const node = walker.currentNode; 10160 if (nodeIsBlockStartComment(node)) { 10161 var blockIndex; 10162 if (blockIndex != null) { 10163 blockIndex++; 10164 } else { 10165 blockIndex = 0; 10166 } 10167 if (blockIndex === index) { 10168 recordingNodes = true; 10169 } else if (recordingNodes) { 10170 break; 10171 } 10172 } else if (recordingNodes) { 10173 nodes.push(node); 10174 } 10175 } 10176 return nodes; 10177 } 10178 } 10179 const nodeLength = function (node) { 10180 if (node.nodeType === Node.TEXT_NODE) { 10181 if (nodeIsCursorTarget(node)) { 10182 return 0; 10183 } else { 10184 const string = node.textContent; 10185 return string.length; 10186 } 10187 } else if (tagName(node) === "br" || nodeIsAttachmentElement(node)) { 10188 return 1; 10189 } else { 10190 return 0; 10191 } 10192 }; 10193 const acceptSignificantNodes = function (node) { 10194 if (rejectEmptyTextNodes(node) === NodeFilter.FILTER_ACCEPT) { 10195 return rejectAttachmentContents(node); 10196 } else { 10197 return NodeFilter.FILTER_REJECT; 10198 } 10199 }; 10200 const rejectEmptyTextNodes = function (node) { 10201 if (nodeIsEmptyTextNode(node)) { 10202 return NodeFilter.FILTER_REJECT; 10203 } else { 10204 return NodeFilter.FILTER_ACCEPT; 10205 } 10206 }; 10207 const rejectAttachmentContents = function (node) { 10208 if (nodeIsAttachmentElement(node.parentNode)) { 10209 return NodeFilter.FILTER_REJECT; 10210 } else { 10211 return NodeFilter.FILTER_ACCEPT; 10212 } 10213 }; 10214 10215 /* eslint-disable 10216 id-length, 10217 no-empty, 10218 */ 10219 class PointMapper { 10220 createDOMRangeFromPoint(_ref) { 10221 let { 10222 x, 10223 y 10224 } = _ref; 10225 let domRange; 10226 if (document.caretPositionFromPoint) { 10227 const { 10228 offsetNode, 10229 offset 10230 } = document.caretPositionFromPoint(x, y); 10231 domRange = document.createRange(); 10232 domRange.setStart(offsetNode, offset); 10233 return domRange; 10234 } else if (document.caretRangeFromPoint) { 10235 return document.caretRangeFromPoint(x, y); 10236 } else if (document.body.createTextRange) { 10237 const originalDOMRange = getDOMRange(); 10238 try { 10239 // IE 11 throws "Unspecified error" when using moveToPoint 10240 // during a drag-and-drop operation. 10241 const textRange = document.body.createTextRange(); 10242 textRange.moveToPoint(x, y); 10243 textRange.select(); 10244 } catch (error) {} 10245 domRange = getDOMRange(); 10246 setDOMRange(originalDOMRange); 10247 return domRange; 10248 } 10249 } 10250 getClientRectsForDOMRange(domRange) { 10251 const array = Array.from(domRange.getClientRects()); 10252 const start = array[0]; 10253 const end = array[array.length - 1]; 10254 return [start, end]; 10255 } 10256 } 10257 10258 /* eslint-disable 10259 */ 10260 class SelectionManager extends BasicObject { 10261 constructor(element) { 10262 super(...arguments); 10263 this.didMouseDown = this.didMouseDown.bind(this); 10264 this.selectionDidChange = this.selectionDidChange.bind(this); 10265 this.element = element; 10266 this.locationMapper = new LocationMapper(this.element); 10267 this.pointMapper = new PointMapper(); 10268 this.lockCount = 0; 10269 handleEvent("mousedown", { 10270 onElement: this.element, 10271 withCallback: this.didMouseDown 10272 }); 10273 } 10274 getLocationRange() { 10275 let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 10276 if (options.strict === false) { 10277 return this.createLocationRangeFromDOMRange(getDOMRange()); 10278 } else if (options.ignoreLock) { 10279 return this.currentLocationRange; 10280 } else if (this.lockedLocationRange) { 10281 return this.lockedLocationRange; 10282 } else { 10283 return this.currentLocationRange; 10284 } 10285 } 10286 setLocationRange(locationRange) { 10287 if (this.lockedLocationRange) return; 10288 locationRange = normalizeRange(locationRange); 10289 const domRange = this.createDOMRangeFromLocationRange(locationRange); 10290 if (domRange) { 10291 setDOMRange(domRange); 10292 this.updateCurrentLocationRange(locationRange); 10293 } 10294 } 10295 setLocationRangeFromPointRange(pointRange) { 10296 pointRange = normalizeRange(pointRange); 10297 const startLocation = this.getLocationAtPoint(pointRange[0]); 10298 const endLocation = this.getLocationAtPoint(pointRange[1]); 10299 this.setLocationRange([startLocation, endLocation]); 10300 } 10301 getClientRectAtLocationRange(locationRange) { 10302 const domRange = this.createDOMRangeFromLocationRange(locationRange); 10303 if (domRange) { 10304 return this.getClientRectsForDOMRange(domRange)[1]; 10305 } 10306 } 10307 locationIsCursorTarget(location) { 10308 const node = Array.from(this.findNodeAndOffsetFromLocation(location))[0]; 10309 return nodeIsCursorTarget(node); 10310 } 10311 lock() { 10312 if (this.lockCount++ === 0) { 10313 this.updateCurrentLocationRange(); 10314 this.lockedLocationRange = this.getLocationRange(); 10315 } 10316 } 10317 unlock() { 10318 if (--this.lockCount === 0) { 10319 const { 10320 lockedLocationRange 10321 } = this; 10322 this.lockedLocationRange = null; 10323 if (lockedLocationRange != null) { 10324 return this.setLocationRange(lockedLocationRange); 10325 } 10326 } 10327 } 10328 clearSelection() { 10329 var _getDOMSelection; 10330 return (_getDOMSelection = getDOMSelection()) === null || _getDOMSelection === void 0 ? void 0 : _getDOMSelection.removeAllRanges(); 10331 } 10332 selectionIsCollapsed() { 10333 var _getDOMRange; 10334 return ((_getDOMRange = getDOMRange()) === null || _getDOMRange === void 0 ? void 0 : _getDOMRange.collapsed) === true; 10335 } 10336 selectionIsExpanded() { 10337 return !this.selectionIsCollapsed(); 10338 } 10339 createLocationRangeFromDOMRange(domRange, options) { 10340 if (domRange == null || !this.domRangeWithinElement(domRange)) return; 10341 const start = this.findLocationFromContainerAndOffset(domRange.startContainer, domRange.startOffset, options); 10342 if (!start) return; 10343 const end = domRange.collapsed ? undefined : this.findLocationFromContainerAndOffset(domRange.endContainer, domRange.endOffset, options); 10344 return normalizeRange([start, end]); 10345 } 10346 didMouseDown() { 10347 return this.pauseTemporarily(); 10348 } 10349 pauseTemporarily() { 10350 let resumeHandlers; 10351 this.paused = true; 10352 const resume = () => { 10353 this.paused = false; 10354 clearTimeout(resumeTimeout); 10355 Array.from(resumeHandlers).forEach(handler => { 10356 handler.destroy(); 10357 }); 10358 if (elementContainsNode(document, this.element)) { 10359 return this.selectionDidChange(); 10360 } 10361 }; 10362 const resumeTimeout = setTimeout(resume, 200); 10363 resumeHandlers = ["mousemove", "keydown"].map(eventName => handleEvent(eventName, { 10364 onElement: document, 10365 withCallback: resume 10366 })); 10367 } 10368 selectionDidChange() { 10369 if (!this.paused && !innerElementIsActive(this.element)) { 10370 return this.updateCurrentLocationRange(); 10371 } 10372 } 10373 updateCurrentLocationRange(locationRange) { 10374 if (locationRange != null ? locationRange : locationRange = this.createLocationRangeFromDOMRange(getDOMRange())) { 10375 if (!rangesAreEqual(locationRange, this.currentLocationRange)) { 10376 var _this$delegate, _this$delegate$locati; 10377 this.currentLocationRange = locationRange; 10378 return (_this$delegate = this.delegate) === null || _this$delegate === void 0 || (_this$delegate$locati = _this$delegate.locationRangeDidChange) === null || _this$delegate$locati === void 0 ? void 0 : _this$delegate$locati.call(_this$delegate, this.currentLocationRange.slice(0)); 10379 } 10380 } 10381 } 10382 createDOMRangeFromLocationRange(locationRange) { 10383 const rangeStart = this.findContainerAndOffsetFromLocation(locationRange[0]); 10384 const rangeEnd = rangeIsCollapsed(locationRange) ? rangeStart : this.findContainerAndOffsetFromLocation(locationRange[1]) || rangeStart; 10385 if (rangeStart != null && rangeEnd != null) { 10386 const domRange = document.createRange(); 10387 domRange.setStart(...Array.from(rangeStart || [])); 10388 domRange.setEnd(...Array.from(rangeEnd || [])); 10389 return domRange; 10390 } 10391 } 10392 getLocationAtPoint(point) { 10393 const domRange = this.createDOMRangeFromPoint(point); 10394 if (domRange) { 10395 var _this$createLocationR; 10396 return (_this$createLocationR = this.createLocationRangeFromDOMRange(domRange)) === null || _this$createLocationR === void 0 ? void 0 : _this$createLocationR[0]; 10397 } 10398 } 10399 domRangeWithinElement(domRange) { 10400 if (domRange.collapsed) { 10401 return elementContainsNode(this.element, domRange.startContainer); 10402 } else { 10403 return elementContainsNode(this.element, domRange.startContainer) && elementContainsNode(this.element, domRange.endContainer); 10404 } 10405 } 10406 } 10407 SelectionManager.proxyMethod("locationMapper.findLocationFromContainerAndOffset"); 10408 SelectionManager.proxyMethod("locationMapper.findContainerAndOffsetFromLocation"); 10409 SelectionManager.proxyMethod("locationMapper.findNodeAndOffsetFromLocation"); 10410 SelectionManager.proxyMethod("pointMapper.createDOMRangeFromPoint"); 10411 SelectionManager.proxyMethod("pointMapper.getClientRectsForDOMRange"); 10412 10413 var models = /*#__PURE__*/Object.freeze({ 10414 __proto__: null, 10415 Attachment: Attachment, 10416 AttachmentManager: AttachmentManager, 10417 AttachmentPiece: AttachmentPiece, 10418 Block: Block, 10419 Composition: Composition, 10420 Document: Document, 10421 Editor: Editor, 10422 HTMLParser: HTMLParser, 10423 HTMLSanitizer: HTMLSanitizer, 10424 LineBreakInsertion: LineBreakInsertion, 10425 LocationMapper: LocationMapper, 10426 ManagedAttachment: ManagedAttachment, 10427 Piece: Piece, 10428 PointMapper: PointMapper, 10429 SelectionManager: SelectionManager, 10430 SplittableList: SplittableList, 10431 StringPiece: StringPiece, 10432 Text: Text, 10433 UndoManager: UndoManager 10434 }); 10435 10436 var views = /*#__PURE__*/Object.freeze({ 10437 __proto__: null, 10438 ObjectView: ObjectView, 10439 AttachmentView: AttachmentView, 10440 BlockView: BlockView, 10441 DocumentView: DocumentView, 10442 PieceView: PieceView, 10443 PreviewableAttachmentView: PreviewableAttachmentView, 10444 TextView: TextView 10445 }); 10446 10447 const { 10448 lang, 10449 css, 10450 keyNames: keyNames$1 10451 } = config; 10452 const undoable = function (fn) { 10453 return function () { 10454 const commands = fn.apply(this, arguments); 10455 commands.do(); 10456 if (!this.undos) { 10457 this.undos = []; 10458 } 10459 this.undos.push(commands.undo); 10460 }; 10461 }; 10462 class AttachmentEditorController extends BasicObject { 10463 constructor(attachmentPiece, _element, container) { 10464 let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; 10465 super(...arguments); 10466 // Installing and uninstalling 10467 _defineProperty(this, "makeElementMutable", undoable(() => { 10468 return { 10469 do: () => { 10470 this.element.dataset.trixMutable = true; 10471 }, 10472 undo: () => delete this.element.dataset.trixMutable 10473 }; 10474 })); 10475 _defineProperty(this, "addToolbar", undoable(() => { 10476 // <div class="#{css.attachmentMetadataContainer}" data-trix-mutable="true"> 10477 // <div class="trix-button-row"> 10478 // <span class="trix-button-group trix-button-group--actions"> 10479 // <button type="button" class="trix-button trix-button--remove" title="#{lang.remove}" data-trix-action="remove">#{lang.remove}</button> 10480 // </span> 10481 // </div> 10482 // </div> 10483 const element = makeElement({ 10484 tagName: "div", 10485 className: css.attachmentToolbar, 10486 data: { 10487 trixMutable: true 10488 }, 10489 childNodes: makeElement({ 10490 tagName: "div", 10491 className: "trix-button-row", 10492 childNodes: makeElement({ 10493 tagName: "span", 10494 className: "trix-button-group trix-button-group--actions", 10495 childNodes: makeElement({ 10496 tagName: "button", 10497 className: "trix-button trix-button--remove", 10498 textContent: lang.remove, 10499 attributes: { 10500 title: lang.remove 10501 }, 10502 data: { 10503 trixAction: "remove" 10504 } 10505 }) 10506 }) 10507 }) 10508 }); 10509 if (this.attachment.isPreviewable()) { 10510 // <div class="#{css.attachmentMetadataContainer}"> 10511 // <span class="#{css.attachmentMetadata}"> 10512 // <span class="#{css.attachmentName}" title="#{name}">#{name}</span> 10513 // <span class="#{css.attachmentSize}">#{size}</span> 10514 // </span> 10515 // </div> 10516 element.appendChild(makeElement({ 10517 tagName: "div", 10518 className: css.attachmentMetadataContainer, 10519 childNodes: makeElement({ 10520 tagName: "span", 10521 className: css.attachmentMetadata, 10522 childNodes: [makeElement({ 10523 tagName: "span", 10524 className: css.attachmentName, 10525 textContent: this.attachment.getFilename(), 10526 attributes: { 10527 title: this.attachment.getFilename() 10528 } 10529 }), makeElement({ 10530 tagName: "span", 10531 className: css.attachmentSize, 10532 textContent: this.attachment.getFormattedFilesize() 10533 })] 10534 }) 10535 })); 10536 } 10537 handleEvent("click", { 10538 onElement: element, 10539 withCallback: this.didClickToolbar 10540 }); 10541 handleEvent("click", { 10542 onElement: element, 10543 matchingSelector: "[data-trix-action]", 10544 withCallback: this.didClickActionButton 10545 }); 10546 triggerEvent("trix-attachment-before-toolbar", { 10547 onElement: this.element, 10548 attributes: { 10549 toolbar: element, 10550 attachment: this.attachment 10551 } 10552 }); 10553 return { 10554 do: () => this.element.appendChild(element), 10555 undo: () => removeNode(element) 10556 }; 10557 })); 10558 _defineProperty(this, "installCaptionEditor", undoable(() => { 10559 const textarea = makeElement({ 10560 tagName: "textarea", 10561 className: css.attachmentCaptionEditor, 10562 attributes: { 10563 placeholder: lang.captionPlaceholder 10564 }, 10565 data: { 10566 trixMutable: true 10567 } 10568 }); 10569 textarea.value = this.attachmentPiece.getCaption(); 10570 const textareaClone = textarea.cloneNode(); 10571 textareaClone.classList.add("trix-autoresize-clone"); 10572 textareaClone.tabIndex = -1; 10573 const autoresize = function () { 10574 textareaClone.value = textarea.value; 10575 textarea.style.height = textareaClone.scrollHeight + "px"; 10576 }; 10577 handleEvent("input", { 10578 onElement: textarea, 10579 withCallback: autoresize 10580 }); 10581 handleEvent("input", { 10582 onElement: textarea, 10583 withCallback: this.didInputCaption 10584 }); 10585 handleEvent("keydown", { 10586 onElement: textarea, 10587 withCallback: this.didKeyDownCaption 10588 }); 10589 handleEvent("change", { 10590 onElement: textarea, 10591 withCallback: this.didChangeCaption 10592 }); 10593 handleEvent("blur", { 10594 onElement: textarea, 10595 withCallback: this.didBlurCaption 10596 }); 10597 const figcaption = this.element.querySelector("figcaption"); 10598 const editingFigcaption = figcaption.cloneNode(); 10599 return { 10600 do: () => { 10601 figcaption.style.display = "none"; 10602 editingFigcaption.appendChild(textarea); 10603 editingFigcaption.appendChild(textareaClone); 10604 editingFigcaption.classList.add("".concat(css.attachmentCaption, "--editing")); 10605 figcaption.parentElement.insertBefore(editingFigcaption, figcaption); 10606 autoresize(); 10607 if (this.options.editCaption) { 10608 return defer(() => textarea.focus()); 10609 } 10610 }, 10611 undo() { 10612 removeNode(editingFigcaption); 10613 figcaption.style.display = null; 10614 } 10615 }; 10616 })); 10617 this.didClickToolbar = this.didClickToolbar.bind(this); 10618 this.didClickActionButton = this.didClickActionButton.bind(this); 10619 this.didKeyDownCaption = this.didKeyDownCaption.bind(this); 10620 this.didInputCaption = this.didInputCaption.bind(this); 10621 this.didChangeCaption = this.didChangeCaption.bind(this); 10622 this.didBlurCaption = this.didBlurCaption.bind(this); 10623 this.attachmentPiece = attachmentPiece; 10624 this.element = _element; 10625 this.container = container; 10626 this.options = options; 10627 this.attachment = this.attachmentPiece.attachment; 10628 if (tagName(this.element) === "a") { 10629 this.element = this.element.firstChild; 10630 } 10631 this.install(); 10632 } 10633 install() { 10634 this.makeElementMutable(); 10635 this.addToolbar(); 10636 if (this.attachment.isPreviewable()) { 10637 this.installCaptionEditor(); 10638 } 10639 } 10640 uninstall() { 10641 var _this$delegate; 10642 let undo = this.undos.pop(); 10643 this.savePendingCaption(); 10644 while (undo) { 10645 undo(); 10646 undo = this.undos.pop(); 10647 } 10648 (_this$delegate = this.delegate) === null || _this$delegate === void 0 || _this$delegate.didUninstallAttachmentEditor(this); 10649 } 10650 10651 // Private 10652 10653 savePendingCaption() { 10654 if (this.pendingCaption != null) { 10655 const caption = this.pendingCaption; 10656 this.pendingCaption = null; 10657 if (caption) { 10658 var _this$delegate2, _this$delegate2$attac; 10659 (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || (_this$delegate2$attac = _this$delegate2.attachmentEditorDidRequestUpdatingAttributesForAttachment) === null || _this$delegate2$attac === void 0 || _this$delegate2$attac.call(_this$delegate2, { 10660 caption 10661 }, this.attachment); 10662 } else { 10663 var _this$delegate3, _this$delegate3$attac; 10664 (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || (_this$delegate3$attac = _this$delegate3.attachmentEditorDidRequestRemovingAttributeForAttachment) === null || _this$delegate3$attac === void 0 || _this$delegate3$attac.call(_this$delegate3, "caption", this.attachment); 10665 } 10666 } 10667 } 10668 // Event handlers 10669 10670 didClickToolbar(event) { 10671 event.preventDefault(); 10672 return event.stopPropagation(); 10673 } 10674 didClickActionButton(event) { 10675 var _this$delegate4; 10676 const action = event.target.getAttribute("data-trix-action"); 10677 switch (action) { 10678 case "remove": 10679 return (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 ? void 0 : _this$delegate4.attachmentEditorDidRequestRemovalOfAttachment(this.attachment); 10680 } 10681 } 10682 didKeyDownCaption(event) { 10683 if (keyNames$1[event.keyCode] === "return") { 10684 var _this$delegate5, _this$delegate5$attac; 10685 event.preventDefault(); 10686 this.savePendingCaption(); 10687 return (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || (_this$delegate5$attac = _this$delegate5.attachmentEditorDidRequestDeselectingAttachment) === null || _this$delegate5$attac === void 0 ? void 0 : _this$delegate5$attac.call(_this$delegate5, this.attachment); 10688 } 10689 } 10690 didInputCaption(event) { 10691 this.pendingCaption = event.target.value.replace(/\s/g, " ").trim(); 10692 } 10693 didChangeCaption(event) { 10694 return this.savePendingCaption(); 10695 } 10696 didBlurCaption(event) { 10697 return this.savePendingCaption(); 10698 } 10699 } 10700 10701 class CompositionController extends BasicObject { 10702 constructor(element, composition) { 10703 super(...arguments); 10704 this.didFocus = this.didFocus.bind(this); 10705 this.didBlur = this.didBlur.bind(this); 10706 this.didClickAttachment = this.didClickAttachment.bind(this); 10707 this.element = element; 10708 this.composition = composition; 10709 this.documentView = new DocumentView(this.composition.document, { 10710 element: this.element 10711 }); 10712 handleEvent("focus", { 10713 onElement: this.element, 10714 withCallback: this.didFocus 10715 }); 10716 handleEvent("blur", { 10717 onElement: this.element, 10718 withCallback: this.didBlur 10719 }); 10720 handleEvent("click", { 10721 onElement: this.element, 10722 matchingSelector: "a[contenteditable=false]", 10723 preventDefault: true 10724 }); 10725 handleEvent("mousedown", { 10726 onElement: this.element, 10727 matchingSelector: attachmentSelector, 10728 withCallback: this.didClickAttachment 10729 }); 10730 handleEvent("click", { 10731 onElement: this.element, 10732 matchingSelector: "a".concat(attachmentSelector), 10733 preventDefault: true 10734 }); 10735 } 10736 didFocus(event) { 10737 var _this$blurPromise; 10738 const perform = () => { 10739 if (!this.focused) { 10740 var _this$delegate, _this$delegate$compos; 10741 this.focused = true; 10742 return (_this$delegate = this.delegate) === null || _this$delegate === void 0 || (_this$delegate$compos = _this$delegate.compositionControllerDidFocus) === null || _this$delegate$compos === void 0 ? void 0 : _this$delegate$compos.call(_this$delegate); 10743 } 10744 }; 10745 return ((_this$blurPromise = this.blurPromise) === null || _this$blurPromise === void 0 ? void 0 : _this$blurPromise.then(perform)) || perform(); 10746 } 10747 didBlur(event) { 10748 this.blurPromise = new Promise(resolve => { 10749 return defer(() => { 10750 if (!innerElementIsActive(this.element)) { 10751 var _this$delegate2, _this$delegate2$compo; 10752 this.focused = null; 10753 (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || (_this$delegate2$compo = _this$delegate2.compositionControllerDidBlur) === null || _this$delegate2$compo === void 0 || _this$delegate2$compo.call(_this$delegate2); 10754 } 10755 this.blurPromise = null; 10756 return resolve(); 10757 }); 10758 }); 10759 } 10760 didClickAttachment(event, target) { 10761 var _this$delegate3, _this$delegate3$compo; 10762 const attachment = this.findAttachmentForElement(target); 10763 const editCaption = !!findClosestElementFromNode(event.target, { 10764 matchingSelector: "figcaption" 10765 }); 10766 return (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || (_this$delegate3$compo = _this$delegate3.compositionControllerDidSelectAttachment) === null || _this$delegate3$compo === void 0 ? void 0 : _this$delegate3$compo.call(_this$delegate3, attachment, { 10767 editCaption 10768 }); 10769 } 10770 getSerializableElement() { 10771 if (this.isEditingAttachment()) { 10772 return this.documentView.shadowElement; 10773 } else { 10774 return this.element; 10775 } 10776 } 10777 render() { 10778 var _this$delegate6, _this$delegate6$compo; 10779 if (this.revision !== this.composition.revision) { 10780 this.documentView.setDocument(this.composition.document); 10781 this.documentView.render(); 10782 this.revision = this.composition.revision; 10783 } 10784 if (this.canSyncDocumentView() && !this.documentView.isSynced()) { 10785 var _this$delegate4, _this$delegate4$compo, _this$delegate5, _this$delegate5$compo; 10786 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || (_this$delegate4$compo = _this$delegate4.compositionControllerWillSyncDocumentView) === null || _this$delegate4$compo === void 0 || _this$delegate4$compo.call(_this$delegate4); 10787 this.documentView.sync(); 10788 (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || (_this$delegate5$compo = _this$delegate5.compositionControllerDidSyncDocumentView) === null || _this$delegate5$compo === void 0 || _this$delegate5$compo.call(_this$delegate5); 10789 } 10790 return (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 || (_this$delegate6$compo = _this$delegate6.compositionControllerDidRender) === null || _this$delegate6$compo === void 0 ? void 0 : _this$delegate6$compo.call(_this$delegate6); 10791 } 10792 rerenderViewForObject(object) { 10793 this.invalidateViewForObject(object); 10794 return this.render(); 10795 } 10796 invalidateViewForObject(object) { 10797 return this.documentView.invalidateViewForObject(object); 10798 } 10799 isViewCachingEnabled() { 10800 return this.documentView.isViewCachingEnabled(); 10801 } 10802 enableViewCaching() { 10803 return this.documentView.enableViewCaching(); 10804 } 10805 disableViewCaching() { 10806 return this.documentView.disableViewCaching(); 10807 } 10808 refreshViewCache() { 10809 return this.documentView.garbageCollectCachedViews(); 10810 } 10811 10812 // Attachment editor management 10813 10814 isEditingAttachment() { 10815 return !!this.attachmentEditor; 10816 } 10817 installAttachmentEditorForAttachment(attachment, options) { 10818 var _this$attachmentEdito; 10819 if (((_this$attachmentEdito = this.attachmentEditor) === null || _this$attachmentEdito === void 0 ? void 0 : _this$attachmentEdito.attachment) === attachment) return; 10820 const element = this.documentView.findElementForObject(attachment); 10821 if (!element) return; 10822 this.uninstallAttachmentEditor(); 10823 const attachmentPiece = this.composition.document.getAttachmentPieceForAttachment(attachment); 10824 this.attachmentEditor = new AttachmentEditorController(attachmentPiece, element, this.element, options); 10825 this.attachmentEditor.delegate = this; 10826 } 10827 uninstallAttachmentEditor() { 10828 var _this$attachmentEdito2; 10829 return (_this$attachmentEdito2 = this.attachmentEditor) === null || _this$attachmentEdito2 === void 0 ? void 0 : _this$attachmentEdito2.uninstall(); 10830 } 10831 10832 // Attachment controller delegate 10833 10834 didUninstallAttachmentEditor() { 10835 this.attachmentEditor = null; 10836 return this.render(); 10837 } 10838 attachmentEditorDidRequestUpdatingAttributesForAttachment(attributes, attachment) { 10839 var _this$delegate7, _this$delegate7$compo; 10840 (_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || (_this$delegate7$compo = _this$delegate7.compositionControllerWillUpdateAttachment) === null || _this$delegate7$compo === void 0 || _this$delegate7$compo.call(_this$delegate7, attachment); 10841 return this.composition.updateAttributesForAttachment(attributes, attachment); 10842 } 10843 attachmentEditorDidRequestRemovingAttributeForAttachment(attribute, attachment) { 10844 var _this$delegate8, _this$delegate8$compo; 10845 (_this$delegate8 = this.delegate) === null || _this$delegate8 === void 0 || (_this$delegate8$compo = _this$delegate8.compositionControllerWillUpdateAttachment) === null || _this$delegate8$compo === void 0 || _this$delegate8$compo.call(_this$delegate8, attachment); 10846 return this.composition.removeAttributeForAttachment(attribute, attachment); 10847 } 10848 attachmentEditorDidRequestRemovalOfAttachment(attachment) { 10849 var _this$delegate9, _this$delegate9$compo; 10850 return (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 || (_this$delegate9$compo = _this$delegate9.compositionControllerDidRequestRemovalOfAttachment) === null || _this$delegate9$compo === void 0 ? void 0 : _this$delegate9$compo.call(_this$delegate9, attachment); 10851 } 10852 attachmentEditorDidRequestDeselectingAttachment(attachment) { 10853 var _this$delegate10, _this$delegate10$comp; 10854 return (_this$delegate10 = this.delegate) === null || _this$delegate10 === void 0 || (_this$delegate10$comp = _this$delegate10.compositionControllerDidRequestDeselectingAttachment) === null || _this$delegate10$comp === void 0 ? void 0 : _this$delegate10$comp.call(_this$delegate10, attachment); 10855 } 10856 10857 // Private 10858 10859 canSyncDocumentView() { 10860 return !this.isEditingAttachment(); 10861 } 10862 findAttachmentForElement(element) { 10863 return this.composition.document.getAttachmentById(parseInt(element.dataset.trixId, 10)); 10864 } 10865 } 10866 10867 class Controller extends BasicObject {} 10868 10869 const mutableAttributeName = "data-trix-mutable"; 10870 const mutableSelector = "[".concat(mutableAttributeName, "]"); 10871 const options = { 10872 attributes: true, 10873 childList: true, 10874 characterData: true, 10875 characterDataOldValue: true, 10876 subtree: true 10877 }; 10878 class MutationObserver extends BasicObject { 10879 constructor(element) { 10880 super(element); 10881 this.didMutate = this.didMutate.bind(this); 10882 this.element = element; 10883 this.observer = new window.MutationObserver(this.didMutate); 10884 this.start(); 10885 } 10886 start() { 10887 this.reset(); 10888 return this.observer.observe(this.element, options); 10889 } 10890 stop() { 10891 return this.observer.disconnect(); 10892 } 10893 didMutate(mutations) { 10894 this.mutations.push(...Array.from(this.findSignificantMutations(mutations) || [])); 10895 if (this.mutations.length) { 10896 var _this$delegate, _this$delegate$elemen; 10897 (_this$delegate = this.delegate) === null || _this$delegate === void 0 || (_this$delegate$elemen = _this$delegate.elementDidMutate) === null || _this$delegate$elemen === void 0 || _this$delegate$elemen.call(_this$delegate, this.getMutationSummary()); 10898 return this.reset(); 10899 } 10900 } 10901 10902 // Private 10903 10904 reset() { 10905 this.mutations = []; 10906 } 10907 findSignificantMutations(mutations) { 10908 return mutations.filter(mutation => { 10909 return this.mutationIsSignificant(mutation); 10910 }); 10911 } 10912 mutationIsSignificant(mutation) { 10913 if (this.nodeIsMutable(mutation.target)) { 10914 return false; 10915 } 10916 for (const node of Array.from(this.nodesModifiedByMutation(mutation))) { 10917 if (this.nodeIsSignificant(node)) return true; 10918 } 10919 return false; 10920 } 10921 nodeIsSignificant(node) { 10922 return node !== this.element && !this.nodeIsMutable(node) && !nodeIsEmptyTextNode(node); 10923 } 10924 nodeIsMutable(node) { 10925 return findClosestElementFromNode(node, { 10926 matchingSelector: mutableSelector 10927 }); 10928 } 10929 nodesModifiedByMutation(mutation) { 10930 const nodes = []; 10931 switch (mutation.type) { 10932 case "attributes": 10933 if (mutation.attributeName !== mutableAttributeName) { 10934 nodes.push(mutation.target); 10935 } 10936 break; 10937 case "characterData": 10938 // Changes to text nodes should consider the parent element 10939 nodes.push(mutation.target.parentNode); 10940 nodes.push(mutation.target); 10941 break; 10942 case "childList": 10943 // Consider each added or removed node 10944 nodes.push(...Array.from(mutation.addedNodes || [])); 10945 nodes.push(...Array.from(mutation.removedNodes || [])); 10946 break; 10947 } 10948 return nodes; 10949 } 10950 getMutationSummary() { 10951 return this.getTextMutationSummary(); 10952 } 10953 getTextMutationSummary() { 10954 const { 10955 additions, 10956 deletions 10957 } = this.getTextChangesFromCharacterData(); 10958 const textChanges = this.getTextChangesFromChildList(); 10959 Array.from(textChanges.additions).forEach(addition => { 10960 if (!Array.from(additions).includes(addition)) { 10961 additions.push(addition); 10962 } 10963 }); 10964 deletions.push(...Array.from(textChanges.deletions || [])); 10965 const summary = {}; 10966 const added = additions.join(""); 10967 if (added) { 10968 summary.textAdded = added; 10969 } 10970 const deleted = deletions.join(""); 10971 if (deleted) { 10972 summary.textDeleted = deleted; 10973 } 10974 return summary; 10975 } 10976 getMutationsByType(type) { 10977 return Array.from(this.mutations).filter(mutation => mutation.type === type); 10978 } 10979 getTextChangesFromChildList() { 10980 let textAdded, textRemoved; 10981 const addedNodes = []; 10982 const removedNodes = []; 10983 Array.from(this.getMutationsByType("childList")).forEach(mutation => { 10984 addedNodes.push(...Array.from(mutation.addedNodes || [])); 10985 removedNodes.push(...Array.from(mutation.removedNodes || [])); 10986 }); 10987 const singleBlockCommentRemoved = addedNodes.length === 0 && removedNodes.length === 1 && nodeIsBlockStartComment(removedNodes[0]); 10988 if (singleBlockCommentRemoved) { 10989 textAdded = []; 10990 textRemoved = ["\n"]; 10991 } else { 10992 textAdded = getTextForNodes(addedNodes); 10993 textRemoved = getTextForNodes(removedNodes); 10994 } 10995 const additions = textAdded.filter((text, index) => text !== textRemoved[index]).map(normalizeSpaces); 10996 const deletions = textRemoved.filter((text, index) => text !== textAdded[index]).map(normalizeSpaces); 10997 return { 10998 additions, 10999 deletions 11000 }; 11001 } 11002 getTextChangesFromCharacterData() { 11003 let added, removed; 11004 const characterMutations = this.getMutationsByType("characterData"); 11005 if (characterMutations.length) { 11006 const startMutation = characterMutations[0], 11007 endMutation = characterMutations[characterMutations.length - 1]; 11008 const oldString = normalizeSpaces(startMutation.oldValue); 11009 const newString = normalizeSpaces(endMutation.target.data); 11010 const summarized = summarizeStringChange(oldString, newString); 11011 added = summarized.added; 11012 removed = summarized.removed; 11013 } 11014 return { 11015 additions: added ? [added] : [], 11016 deletions: removed ? [removed] : [] 11017 }; 11018 } 11019 } 11020 const getTextForNodes = function () { 11021 let nodes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 11022 const text = []; 11023 for (const node of Array.from(nodes)) { 11024 switch (node.nodeType) { 11025 case Node.TEXT_NODE: 11026 text.push(node.data); 11027 break; 11028 case Node.ELEMENT_NODE: 11029 if (tagName(node) === "br") { 11030 text.push("\n"); 11031 } else { 11032 text.push(...Array.from(getTextForNodes(node.childNodes) || [])); 11033 } 11034 break; 11035 } 11036 } 11037 return text; 11038 }; 11039 11040 /* eslint-disable 11041 no-empty, 11042 */ 11043 class FileVerificationOperation extends Operation { 11044 constructor(file) { 11045 super(...arguments); 11046 this.file = file; 11047 } 11048 perform(callback) { 11049 const reader = new FileReader(); 11050 reader.onerror = () => callback(false); 11051 reader.onload = () => { 11052 reader.onerror = null; 11053 try { 11054 reader.abort(); 11055 } catch (error) {} 11056 return callback(true, this.file); 11057 }; 11058 return reader.readAsArrayBuffer(this.file); 11059 } 11060 } 11061 11062 // Each software keyboard on Android emits its own set of events and some of them can be buggy. 11063 // This class detects when some buggy events are being emitted and lets know the input controller 11064 // that they should be ignored. 11065 class FlakyAndroidKeyboardDetector { 11066 constructor(element) { 11067 this.element = element; 11068 } 11069 shouldIgnore(event) { 11070 if (!browser$1.samsungAndroid) return false; 11071 this.previousEvent = this.event; 11072 this.event = event; 11073 this.checkSamsungKeyboardBuggyModeStart(); 11074 this.checkSamsungKeyboardBuggyModeEnd(); 11075 return this.buggyMode; 11076 } 11077 11078 // private 11079 11080 // The Samsung keyboard on Android can enter a buggy state in which it emits a flurry of confused events that, 11081 // if processed, corrupts the editor. The buggy mode always starts with an insertText event, right after a 11082 // keydown event with for an "Unidentified" key, with the same text as the editor element, except for a few 11083 // extra whitespace, or exotic utf8, characters. 11084 checkSamsungKeyboardBuggyModeStart() { 11085 if (this.insertingLongTextAfterUnidentifiedChar() && differsInWhitespace(this.element.innerText, this.event.data)) { 11086 this.buggyMode = true; 11087 this.event.preventDefault(); 11088 } 11089 } 11090 11091 // The flurry of buggy events are always insertText. If we see any other type, it means it's over. 11092 checkSamsungKeyboardBuggyModeEnd() { 11093 if (this.buggyMode && this.event.inputType !== "insertText") { 11094 this.buggyMode = false; 11095 } 11096 } 11097 insertingLongTextAfterUnidentifiedChar() { 11098 var _this$event$data; 11099 return this.isBeforeInputInsertText() && this.previousEventWasUnidentifiedKeydown() && ((_this$event$data = this.event.data) === null || _this$event$data === void 0 ? void 0 : _this$event$data.length) > 50; 11100 } 11101 isBeforeInputInsertText() { 11102 return this.event.type === "beforeinput" && this.event.inputType === "insertText"; 11103 } 11104 previousEventWasUnidentifiedKeydown() { 11105 var _this$previousEvent, _this$previousEvent2; 11106 return ((_this$previousEvent = this.previousEvent) === null || _this$previousEvent === void 0 ? void 0 : _this$previousEvent.type) === "keydown" && ((_this$previousEvent2 = this.previousEvent) === null || _this$previousEvent2 === void 0 ? void 0 : _this$previousEvent2.key) === "Unidentified"; 11107 } 11108 } 11109 const differsInWhitespace = (text1, text2) => { 11110 return normalize(text1) === normalize(text2); 11111 }; 11112 const whiteSpaceNormalizerRegexp = new RegExp("(".concat(OBJECT_REPLACEMENT_CHARACTER, "|").concat(ZERO_WIDTH_SPACE, "|").concat(NON_BREAKING_SPACE, "|\\s)+"), "g"); 11113 const normalize = text => text.replace(whiteSpaceNormalizerRegexp, " ").trim(); 11114 11115 class InputController extends BasicObject { 11116 constructor(element) { 11117 super(...arguments); 11118 this.element = element; 11119 this.mutationObserver = new MutationObserver(this.element); 11120 this.mutationObserver.delegate = this; 11121 this.flakyKeyboardDetector = new FlakyAndroidKeyboardDetector(this.element); 11122 for (const eventName in this.constructor.events) { 11123 handleEvent(eventName, { 11124 onElement: this.element, 11125 withCallback: this.handlerFor(eventName) 11126 }); 11127 } 11128 } 11129 elementDidMutate(mutationSummary) {} 11130 editorWillSyncDocumentView() { 11131 return this.mutationObserver.stop(); 11132 } 11133 editorDidSyncDocumentView() { 11134 return this.mutationObserver.start(); 11135 } 11136 requestRender() { 11137 var _this$delegate, _this$delegate$inputC; 11138 return (_this$delegate = this.delegate) === null || _this$delegate === void 0 || (_this$delegate$inputC = _this$delegate.inputControllerDidRequestRender) === null || _this$delegate$inputC === void 0 ? void 0 : _this$delegate$inputC.call(_this$delegate); 11139 } 11140 requestReparse() { 11141 var _this$delegate2, _this$delegate2$input; 11142 (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || (_this$delegate2$input = _this$delegate2.inputControllerDidRequestReparse) === null || _this$delegate2$input === void 0 || _this$delegate2$input.call(_this$delegate2); 11143 return this.requestRender(); 11144 } 11145 attachFiles(files) { 11146 const operations = Array.from(files).map(file => new FileVerificationOperation(file)); 11147 return Promise.all(operations).then(files => { 11148 this.handleInput(function () { 11149 var _this$delegate3, _this$responder; 11150 (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || _this$delegate3.inputControllerWillAttachFiles(); 11151 (_this$responder = this.responder) === null || _this$responder === void 0 || _this$responder.insertFiles(files); 11152 return this.requestRender(); 11153 }); 11154 }); 11155 } 11156 11157 // Private 11158 11159 handlerFor(eventName) { 11160 return event => { 11161 if (!event.defaultPrevented) { 11162 this.handleInput(() => { 11163 if (!innerElementIsActive(this.element)) { 11164 if (this.flakyKeyboardDetector.shouldIgnore(event)) return; 11165 this.eventName = eventName; 11166 this.constructor.events[eventName].call(this, event); 11167 } 11168 }); 11169 } 11170 }; 11171 } 11172 handleInput(callback) { 11173 try { 11174 var _this$delegate4; 11175 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillHandleInput(); 11176 callback.call(this); 11177 } finally { 11178 var _this$delegate5; 11179 (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.inputControllerDidHandleInput(); 11180 } 11181 } 11182 createLinkHTML(href, text) { 11183 const link = document.createElement("a"); 11184 link.href = href; 11185 link.textContent = text ? text : href; 11186 return link.outerHTML; 11187 } 11188 } 11189 _defineProperty(InputController, "events", {}); 11190 11191 var _$codePointAt, _; 11192 const { 11193 browser, 11194 keyNames 11195 } = config; 11196 let pastedFileCount = 0; 11197 class Level0InputController extends InputController { 11198 constructor() { 11199 super(...arguments); 11200 this.resetInputSummary(); 11201 } 11202 setInputSummary() { 11203 let summary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 11204 this.inputSummary.eventName = this.eventName; 11205 for (const key in summary) { 11206 const value = summary[key]; 11207 this.inputSummary[key] = value; 11208 } 11209 return this.inputSummary; 11210 } 11211 resetInputSummary() { 11212 this.inputSummary = {}; 11213 } 11214 reset() { 11215 this.resetInputSummary(); 11216 return selectionChangeObserver.reset(); 11217 } 11218 11219 // Mutation observer delegate 11220 11221 elementDidMutate(mutationSummary) { 11222 if (this.isComposing()) { 11223 var _this$delegate, _this$delegate$inputC; 11224 return (_this$delegate = this.delegate) === null || _this$delegate === void 0 || (_this$delegate$inputC = _this$delegate.inputControllerDidAllowUnhandledInput) === null || _this$delegate$inputC === void 0 ? void 0 : _this$delegate$inputC.call(_this$delegate); 11225 } else { 11226 return this.handleInput(function () { 11227 if (this.mutationIsSignificant(mutationSummary)) { 11228 if (this.mutationIsExpected(mutationSummary)) { 11229 this.requestRender(); 11230 } else { 11231 this.requestReparse(); 11232 } 11233 } 11234 return this.reset(); 11235 }); 11236 } 11237 } 11238 mutationIsExpected(_ref) { 11239 let { 11240 textAdded, 11241 textDeleted 11242 } = _ref; 11243 if (this.inputSummary.preferDocument) { 11244 return true; 11245 } 11246 const mutationAdditionMatchesSummary = textAdded != null ? textAdded === this.inputSummary.textAdded : !this.inputSummary.textAdded; 11247 const mutationDeletionMatchesSummary = textDeleted != null ? this.inputSummary.didDelete : !this.inputSummary.didDelete; 11248 const unexpectedNewlineAddition = ["\n", " \n"].includes(textAdded) && !mutationAdditionMatchesSummary; 11249 const unexpectedNewlineDeletion = textDeleted === "\n" && !mutationDeletionMatchesSummary; 11250 const singleUnexpectedNewline = unexpectedNewlineAddition && !unexpectedNewlineDeletion || unexpectedNewlineDeletion && !unexpectedNewlineAddition; 11251 if (singleUnexpectedNewline) { 11252 const range = this.getSelectedRange(); 11253 if (range) { 11254 var _this$responder; 11255 const offset = unexpectedNewlineAddition ? textAdded.replace(/\n$/, "").length || -1 : (textAdded === null || textAdded === void 0 ? void 0 : textAdded.length) || 1; 11256 if ((_this$responder = this.responder) !== null && _this$responder !== void 0 && _this$responder.positionIsBlockBreak(range[1] + offset)) { 11257 return true; 11258 } 11259 } 11260 } 11261 return mutationAdditionMatchesSummary && mutationDeletionMatchesSummary; 11262 } 11263 mutationIsSignificant(mutationSummary) { 11264 var _this$compositionInpu; 11265 const textChanged = Object.keys(mutationSummary).length > 0; 11266 const composedEmptyString = ((_this$compositionInpu = this.compositionInput) === null || _this$compositionInpu === void 0 ? void 0 : _this$compositionInpu.getEndData()) === ""; 11267 return textChanged || !composedEmptyString; 11268 } 11269 11270 // Private 11271 11272 getCompositionInput() { 11273 if (this.isComposing()) { 11274 return this.compositionInput; 11275 } else { 11276 this.compositionInput = new CompositionInput(this); 11277 } 11278 } 11279 isComposing() { 11280 return this.compositionInput && !this.compositionInput.isEnded(); 11281 } 11282 deleteInDirection(direction, event) { 11283 var _this$responder2; 11284 if (((_this$responder2 = this.responder) === null || _this$responder2 === void 0 ? void 0 : _this$responder2.deleteInDirection(direction)) === false) { 11285 if (event) { 11286 event.preventDefault(); 11287 return this.requestRender(); 11288 } 11289 } else { 11290 return this.setInputSummary({ 11291 didDelete: true 11292 }); 11293 } 11294 } 11295 serializeSelectionToDataTransfer(dataTransfer) { 11296 var _this$responder3; 11297 if (!dataTransferIsWritable(dataTransfer)) return; 11298 const document = (_this$responder3 = this.responder) === null || _this$responder3 === void 0 ? void 0 : _this$responder3.getSelectedDocument().toSerializableDocument(); 11299 dataTransfer.setData("application/x-trix-document", JSON.stringify(document)); 11300 dataTransfer.setData("text/html", DocumentView.render(document).innerHTML); 11301 dataTransfer.setData("text/plain", document.toString().replace(/\n$/, "")); 11302 return true; 11303 } 11304 canAcceptDataTransfer(dataTransfer) { 11305 const types = {}; 11306 Array.from((dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.types) || []).forEach(type => { 11307 types[type] = true; 11308 }); 11309 return types.Files || types["application/x-trix-document"] || types["text/html"] || types["text/plain"]; 11310 } 11311 getPastedHTMLUsingHiddenElement(callback) { 11312 const selectedRange = this.getSelectedRange(); 11313 const style = { 11314 position: "absolute", 11315 left: "".concat(window.pageXOffset, "px"), 11316 top: "".concat(window.pageYOffset, "px"), 11317 opacity: 0 11318 }; 11319 const element = makeElement({ 11320 style, 11321 tagName: "div", 11322 editable: true 11323 }); 11324 document.body.appendChild(element); 11325 element.focus(); 11326 return requestAnimationFrame(() => { 11327 const html = element.innerHTML; 11328 removeNode(element); 11329 this.setSelectedRange(selectedRange); 11330 return callback(html); 11331 }); 11332 } 11333 } 11334 _defineProperty(Level0InputController, "events", { 11335 keydown(event) { 11336 if (!this.isComposing()) { 11337 this.resetInputSummary(); 11338 } 11339 this.inputSummary.didInput = true; 11340 const keyName = keyNames[event.keyCode]; 11341 if (keyName) { 11342 var _context2; 11343 let context = this.keys; 11344 ["ctrl", "alt", "shift", "meta"].forEach(modifier => { 11345 if (event["".concat(modifier, "Key")]) { 11346 var _context; 11347 if (modifier === "ctrl") { 11348 modifier = "control"; 11349 } 11350 context = (_context = context) === null || _context === void 0 ? void 0 : _context[modifier]; 11351 } 11352 }); 11353 if (((_context2 = context) === null || _context2 === void 0 ? void 0 : _context2[keyName]) != null) { 11354 this.setInputSummary({ 11355 keyName 11356 }); 11357 selectionChangeObserver.reset(); 11358 context[keyName].call(this, event); 11359 } 11360 } 11361 if (keyEventIsKeyboardCommand(event)) { 11362 const character = String.fromCharCode(event.keyCode).toLowerCase(); 11363 if (character) { 11364 var _this$delegate3; 11365 const keys = ["alt", "shift"].map(modifier => { 11366 if (event["".concat(modifier, "Key")]) { 11367 return modifier; 11368 } 11369 }).filter(key => key); 11370 keys.push(character); 11371 if ((_this$delegate3 = this.delegate) !== null && _this$delegate3 !== void 0 && _this$delegate3.inputControllerDidReceiveKeyboardCommand(keys)) { 11372 event.preventDefault(); 11373 } 11374 } 11375 } 11376 }, 11377 keypress(event) { 11378 if (this.inputSummary.eventName != null) return; 11379 if (event.metaKey) return; 11380 if (event.ctrlKey && !event.altKey) return; 11381 const string = stringFromKeyEvent(event); 11382 if (string) { 11383 var _this$delegate4, _this$responder9; 11384 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillPerformTyping(); 11385 (_this$responder9 = this.responder) === null || _this$responder9 === void 0 || _this$responder9.insertString(string); 11386 return this.setInputSummary({ 11387 textAdded: string, 11388 didDelete: this.selectionIsExpanded() 11389 }); 11390 } 11391 }, 11392 textInput(event) { 11393 // Handle autocapitalization 11394 const { 11395 data 11396 } = event; 11397 const { 11398 textAdded 11399 } = this.inputSummary; 11400 if (textAdded && textAdded !== data && textAdded.toUpperCase() === data) { 11401 var _this$responder10; 11402 const range = this.getSelectedRange(); 11403 this.setSelectedRange([range[0], range[1] + textAdded.length]); 11404 (_this$responder10 = this.responder) === null || _this$responder10 === void 0 || _this$responder10.insertString(data); 11405 this.setInputSummary({ 11406 textAdded: data 11407 }); 11408 return this.setSelectedRange(range); 11409 } 11410 }, 11411 dragenter(event) { 11412 event.preventDefault(); 11413 }, 11414 dragstart(event) { 11415 var _this$delegate5, _this$delegate5$input; 11416 this.serializeSelectionToDataTransfer(event.dataTransfer); 11417 this.draggedRange = this.getSelectedRange(); 11418 return (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || (_this$delegate5$input = _this$delegate5.inputControllerDidStartDrag) === null || _this$delegate5$input === void 0 ? void 0 : _this$delegate5$input.call(_this$delegate5); 11419 }, 11420 dragover(event) { 11421 if (this.draggedRange || this.canAcceptDataTransfer(event.dataTransfer)) { 11422 event.preventDefault(); 11423 const draggingPoint = { 11424 x: event.clientX, 11425 y: event.clientY 11426 }; 11427 if (!objectsAreEqual(draggingPoint, this.draggingPoint)) { 11428 var _this$delegate6, _this$delegate6$input; 11429 this.draggingPoint = draggingPoint; 11430 return (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 || (_this$delegate6$input = _this$delegate6.inputControllerDidReceiveDragOverPoint) === null || _this$delegate6$input === void 0 ? void 0 : _this$delegate6$input.call(_this$delegate6, this.draggingPoint); 11431 } 11432 } 11433 }, 11434 dragend(event) { 11435 var _this$delegate7, _this$delegate7$input; 11436 (_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || (_this$delegate7$input = _this$delegate7.inputControllerDidCancelDrag) === null || _this$delegate7$input === void 0 || _this$delegate7$input.call(_this$delegate7); 11437 this.draggedRange = null; 11438 this.draggingPoint = null; 11439 }, 11440 drop(event) { 11441 var _event$dataTransfer, _this$responder11; 11442 event.preventDefault(); 11443 const files = (_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.files; 11444 const documentJSON = event.dataTransfer.getData("application/x-trix-document"); 11445 const point = { 11446 x: event.clientX, 11447 y: event.clientY 11448 }; 11449 (_this$responder11 = this.responder) === null || _this$responder11 === void 0 || _this$responder11.setLocationRangeFromPointRange(point); 11450 if (files !== null && files !== void 0 && files.length) { 11451 this.attachFiles(files); 11452 } else if (this.draggedRange) { 11453 var _this$delegate8, _this$responder12; 11454 (_this$delegate8 = this.delegate) === null || _this$delegate8 === void 0 || _this$delegate8.inputControllerWillMoveText(); 11455 (_this$responder12 = this.responder) === null || _this$responder12 === void 0 || _this$responder12.moveTextFromRange(this.draggedRange); 11456 this.draggedRange = null; 11457 this.requestRender(); 11458 } else if (documentJSON) { 11459 var _this$responder13; 11460 const document = Document.fromJSONString(documentJSON); 11461 (_this$responder13 = this.responder) === null || _this$responder13 === void 0 || _this$responder13.insertDocument(document); 11462 this.requestRender(); 11463 } 11464 this.draggedRange = null; 11465 this.draggingPoint = null; 11466 }, 11467 cut(event) { 11468 var _this$responder14; 11469 if ((_this$responder14 = this.responder) !== null && _this$responder14 !== void 0 && _this$responder14.selectionIsExpanded()) { 11470 var _this$delegate9; 11471 if (this.serializeSelectionToDataTransfer(event.clipboardData)) { 11472 event.preventDefault(); 11473 } 11474 (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 || _this$delegate9.inputControllerWillCutText(); 11475 this.deleteInDirection("backward"); 11476 if (event.defaultPrevented) { 11477 return this.requestRender(); 11478 } 11479 } 11480 }, 11481 copy(event) { 11482 var _this$responder15; 11483 if ((_this$responder15 = this.responder) !== null && _this$responder15 !== void 0 && _this$responder15.selectionIsExpanded()) { 11484 if (this.serializeSelectionToDataTransfer(event.clipboardData)) { 11485 event.preventDefault(); 11486 } 11487 } 11488 }, 11489 paste(event) { 11490 const clipboard = event.clipboardData || event.testClipboardData; 11491 const paste = { 11492 clipboard 11493 }; 11494 if (!clipboard || pasteEventIsCrippledSafariHTMLPaste(event)) { 11495 this.getPastedHTMLUsingHiddenElement(html => { 11496 var _this$delegate10, _this$responder16, _this$delegate11; 11497 paste.type = "text/html"; 11498 paste.html = html; 11499 (_this$delegate10 = this.delegate) === null || _this$delegate10 === void 0 || _this$delegate10.inputControllerWillPaste(paste); 11500 (_this$responder16 = this.responder) === null || _this$responder16 === void 0 || _this$responder16.insertHTML(paste.html); 11501 this.requestRender(); 11502 return (_this$delegate11 = this.delegate) === null || _this$delegate11 === void 0 ? void 0 : _this$delegate11.inputControllerDidPaste(paste); 11503 }); 11504 return; 11505 } 11506 const href = clipboard.getData("URL"); 11507 const html = clipboard.getData("text/html"); 11508 const name = clipboard.getData("public.url-name"); 11509 if (href) { 11510 var _this$delegate12, _this$responder17, _this$delegate13; 11511 let string; 11512 paste.type = "text/html"; 11513 if (name) { 11514 string = squishBreakableWhitespace(name).trim(); 11515 } else { 11516 string = href; 11517 } 11518 paste.html = this.createLinkHTML(href, string); 11519 (_this$delegate12 = this.delegate) === null || _this$delegate12 === void 0 || _this$delegate12.inputControllerWillPaste(paste); 11520 this.setInputSummary({ 11521 textAdded: string, 11522 didDelete: this.selectionIsExpanded() 11523 }); 11524 (_this$responder17 = this.responder) === null || _this$responder17 === void 0 || _this$responder17.insertHTML(paste.html); 11525 this.requestRender(); 11526 (_this$delegate13 = this.delegate) === null || _this$delegate13 === void 0 || _this$delegate13.inputControllerDidPaste(paste); 11527 } else if (dataTransferIsPlainText(clipboard)) { 11528 var _this$delegate14, _this$responder18, _this$delegate15; 11529 paste.type = "text/plain"; 11530 paste.string = clipboard.getData("text/plain"); 11531 (_this$delegate14 = this.delegate) === null || _this$delegate14 === void 0 || _this$delegate14.inputControllerWillPaste(paste); 11532 this.setInputSummary({ 11533 textAdded: paste.string, 11534 didDelete: this.selectionIsExpanded() 11535 }); 11536 (_this$responder18 = this.responder) === null || _this$responder18 === void 0 || _this$responder18.insertString(paste.string); 11537 this.requestRender(); 11538 (_this$delegate15 = this.delegate) === null || _this$delegate15 === void 0 || _this$delegate15.inputControllerDidPaste(paste); 11539 } else if (html) { 11540 var _this$delegate16, _this$responder19, _this$delegate17; 11541 paste.type = "text/html"; 11542 paste.html = html; 11543 (_this$delegate16 = this.delegate) === null || _this$delegate16 === void 0 || _this$delegate16.inputControllerWillPaste(paste); 11544 (_this$responder19 = this.responder) === null || _this$responder19 === void 0 || _this$responder19.insertHTML(paste.html); 11545 this.requestRender(); 11546 (_this$delegate17 = this.delegate) === null || _this$delegate17 === void 0 || _this$delegate17.inputControllerDidPaste(paste); 11547 } else if (Array.from(clipboard.types).includes("Files")) { 11548 var _clipboard$items, _clipboard$items$getA; 11549 const file = (_clipboard$items = clipboard.items) === null || _clipboard$items === void 0 || (_clipboard$items = _clipboard$items[0]) === null || _clipboard$items === void 0 || (_clipboard$items$getA = _clipboard$items.getAsFile) === null || _clipboard$items$getA === void 0 ? void 0 : _clipboard$items$getA.call(_clipboard$items); 11550 if (file) { 11551 var _this$delegate18, _this$responder20, _this$delegate19; 11552 const extension = extensionForFile(file); 11553 if (!file.name && extension) { 11554 file.name = "pasted-file-".concat(++pastedFileCount, ".").concat(extension); 11555 } 11556 paste.type = "File"; 11557 paste.file = file; 11558 (_this$delegate18 = this.delegate) === null || _this$delegate18 === void 0 || _this$delegate18.inputControllerWillAttachFiles(); 11559 (_this$responder20 = this.responder) === null || _this$responder20 === void 0 || _this$responder20.insertFile(paste.file); 11560 this.requestRender(); 11561 (_this$delegate19 = this.delegate) === null || _this$delegate19 === void 0 || _this$delegate19.inputControllerDidPaste(paste); 11562 } 11563 } 11564 event.preventDefault(); 11565 }, 11566 compositionstart(event) { 11567 return this.getCompositionInput().start(event.data); 11568 }, 11569 compositionupdate(event) { 11570 return this.getCompositionInput().update(event.data); 11571 }, 11572 compositionend(event) { 11573 return this.getCompositionInput().end(event.data); 11574 }, 11575 beforeinput(event) { 11576 this.inputSummary.didInput = true; 11577 }, 11578 input(event) { 11579 this.inputSummary.didInput = true; 11580 return event.stopPropagation(); 11581 } 11582 }); 11583 _defineProperty(Level0InputController, "keys", { 11584 backspace(event) { 11585 var _this$delegate20; 11586 (_this$delegate20 = this.delegate) === null || _this$delegate20 === void 0 || _this$delegate20.inputControllerWillPerformTyping(); 11587 return this.deleteInDirection("backward", event); 11588 }, 11589 delete(event) { 11590 var _this$delegate21; 11591 (_this$delegate21 = this.delegate) === null || _this$delegate21 === void 0 || _this$delegate21.inputControllerWillPerformTyping(); 11592 return this.deleteInDirection("forward", event); 11593 }, 11594 return(event) { 11595 var _this$delegate22, _this$responder21; 11596 this.setInputSummary({ 11597 preferDocument: true 11598 }); 11599 (_this$delegate22 = this.delegate) === null || _this$delegate22 === void 0 || _this$delegate22.inputControllerWillPerformTyping(); 11600 return (_this$responder21 = this.responder) === null || _this$responder21 === void 0 ? void 0 : _this$responder21.insertLineBreak(); 11601 }, 11602 tab(event) { 11603 var _this$responder22; 11604 if ((_this$responder22 = this.responder) !== null && _this$responder22 !== void 0 && _this$responder22.canIncreaseNestingLevel()) { 11605 var _this$responder23; 11606 (_this$responder23 = this.responder) === null || _this$responder23 === void 0 || _this$responder23.increaseNestingLevel(); 11607 this.requestRender(); 11608 event.preventDefault(); 11609 } 11610 }, 11611 left(event) { 11612 if (this.selectionIsInCursorTarget()) { 11613 var _this$responder24; 11614 event.preventDefault(); 11615 return (_this$responder24 = this.responder) === null || _this$responder24 === void 0 ? void 0 : _this$responder24.moveCursorInDirection("backward"); 11616 } 11617 }, 11618 right(event) { 11619 if (this.selectionIsInCursorTarget()) { 11620 var _this$responder25; 11621 event.preventDefault(); 11622 return (_this$responder25 = this.responder) === null || _this$responder25 === void 0 ? void 0 : _this$responder25.moveCursorInDirection("forward"); 11623 } 11624 }, 11625 control: { 11626 d(event) { 11627 var _this$delegate23; 11628 (_this$delegate23 = this.delegate) === null || _this$delegate23 === void 0 || _this$delegate23.inputControllerWillPerformTyping(); 11629 return this.deleteInDirection("forward", event); 11630 }, 11631 h(event) { 11632 var _this$delegate24; 11633 (_this$delegate24 = this.delegate) === null || _this$delegate24 === void 0 || _this$delegate24.inputControllerWillPerformTyping(); 11634 return this.deleteInDirection("backward", event); 11635 }, 11636 o(event) { 11637 var _this$delegate25, _this$responder26; 11638 event.preventDefault(); 11639 (_this$delegate25 = this.delegate) === null || _this$delegate25 === void 0 || _this$delegate25.inputControllerWillPerformTyping(); 11640 (_this$responder26 = this.responder) === null || _this$responder26 === void 0 || _this$responder26.insertString("\n", { 11641 updatePosition: false 11642 }); 11643 return this.requestRender(); 11644 } 11645 }, 11646 shift: { 11647 return(event) { 11648 var _this$delegate26, _this$responder27; 11649 (_this$delegate26 = this.delegate) === null || _this$delegate26 === void 0 || _this$delegate26.inputControllerWillPerformTyping(); 11650 (_this$responder27 = this.responder) === null || _this$responder27 === void 0 || _this$responder27.insertString("\n"); 11651 this.requestRender(); 11652 event.preventDefault(); 11653 }, 11654 tab(event) { 11655 var _this$responder28; 11656 if ((_this$responder28 = this.responder) !== null && _this$responder28 !== void 0 && _this$responder28.canDecreaseNestingLevel()) { 11657 var _this$responder29; 11658 (_this$responder29 = this.responder) === null || _this$responder29 === void 0 || _this$responder29.decreaseNestingLevel(); 11659 this.requestRender(); 11660 event.preventDefault(); 11661 } 11662 }, 11663 left(event) { 11664 if (this.selectionIsInCursorTarget()) { 11665 event.preventDefault(); 11666 return this.expandSelectionInDirection("backward"); 11667 } 11668 }, 11669 right(event) { 11670 if (this.selectionIsInCursorTarget()) { 11671 event.preventDefault(); 11672 return this.expandSelectionInDirection("forward"); 11673 } 11674 } 11675 }, 11676 alt: { 11677 backspace(event) { 11678 var _this$delegate27; 11679 this.setInputSummary({ 11680 preferDocument: false 11681 }); 11682 return (_this$delegate27 = this.delegate) === null || _this$delegate27 === void 0 ? void 0 : _this$delegate27.inputControllerWillPerformTyping(); 11683 } 11684 }, 11685 meta: { 11686 backspace(event) { 11687 var _this$delegate28; 11688 this.setInputSummary({ 11689 preferDocument: false 11690 }); 11691 return (_this$delegate28 = this.delegate) === null || _this$delegate28 === void 0 ? void 0 : _this$delegate28.inputControllerWillPerformTyping(); 11692 } 11693 } 11694 }); 11695 Level0InputController.proxyMethod("responder?.getSelectedRange"); 11696 Level0InputController.proxyMethod("responder?.setSelectedRange"); 11697 Level0InputController.proxyMethod("responder?.expandSelectionInDirection"); 11698 Level0InputController.proxyMethod("responder?.selectionIsInCursorTarget"); 11699 Level0InputController.proxyMethod("responder?.selectionIsExpanded"); 11700 const extensionForFile = file => { 11701 var _file$type; 11702 return (_file$type = file.type) === null || _file$type === void 0 || (_file$type = _file$type.match(/\/(\w+)$/)) === null || _file$type === void 0 ? void 0 : _file$type[1]; 11703 }; 11704 const hasStringCodePointAt = !!((_$codePointAt = (_ = " ").codePointAt) !== null && _$codePointAt !== void 0 && _$codePointAt.call(_, 0)); 11705 const stringFromKeyEvent = function (event) { 11706 if (event.key && hasStringCodePointAt && event.key.codePointAt(0) === event.keyCode) { 11707 return event.key; 11708 } else { 11709 let code; 11710 if (event.which === null) { 11711 code = event.keyCode; 11712 } else if (event.which !== 0 && event.charCode !== 0) { 11713 code = event.charCode; 11714 } 11715 if (code != null && keyNames[code] !== "escape") { 11716 return UTF16String.fromCodepoints([code]).toString(); 11717 } 11718 } 11719 }; 11720 const pasteEventIsCrippledSafariHTMLPaste = function (event) { 11721 const paste = event.clipboardData; 11722 if (paste) { 11723 if (paste.types.includes("text/html")) { 11724 // Answer is yes if there's any possibility of Paste and Match Style in Safari, 11725 // which is nearly impossible to detect confidently: https://bugs.webkit.org/show_bug.cgi?id=174165 11726 for (const type of paste.types) { 11727 const hasPasteboardFlavor = /^CorePasteboardFlavorType/.test(type); 11728 const hasReadableDynamicData = /^dyn\./.test(type) && paste.getData(type); 11729 const mightBePasteAndMatchStyle = hasPasteboardFlavor || hasReadableDynamicData; 11730 if (mightBePasteAndMatchStyle) { 11731 return true; 11732 } 11733 } 11734 return false; 11735 } else { 11736 const isExternalHTMLPaste = paste.types.includes("com.apple.webarchive"); 11737 const isExternalRichTextPaste = paste.types.includes("com.apple.flat-rtfd"); 11738 return isExternalHTMLPaste || isExternalRichTextPaste; 11739 } 11740 } 11741 }; 11742 class CompositionInput extends BasicObject { 11743 constructor(inputController) { 11744 super(...arguments); 11745 this.inputController = inputController; 11746 this.responder = this.inputController.responder; 11747 this.delegate = this.inputController.delegate; 11748 this.inputSummary = this.inputController.inputSummary; 11749 this.data = {}; 11750 } 11751 start(data) { 11752 this.data.start = data; 11753 if (this.isSignificant()) { 11754 var _this$responder5; 11755 if (this.inputSummary.eventName === "keypress" && this.inputSummary.textAdded) { 11756 var _this$responder4; 11757 (_this$responder4 = this.responder) === null || _this$responder4 === void 0 || _this$responder4.deleteInDirection("left"); 11758 } 11759 if (!this.selectionIsExpanded()) { 11760 this.insertPlaceholder(); 11761 this.requestRender(); 11762 } 11763 this.range = (_this$responder5 = this.responder) === null || _this$responder5 === void 0 ? void 0 : _this$responder5.getSelectedRange(); 11764 } 11765 } 11766 update(data) { 11767 this.data.update = data; 11768 if (this.isSignificant()) { 11769 const range = this.selectPlaceholder(); 11770 if (range) { 11771 this.forgetPlaceholder(); 11772 this.range = range; 11773 } 11774 } 11775 } 11776 end(data) { 11777 this.data.end = data; 11778 if (this.isSignificant()) { 11779 this.forgetPlaceholder(); 11780 if (this.canApplyToDocument()) { 11781 var _this$delegate2, _this$responder6, _this$responder7, _this$responder8; 11782 this.setInputSummary({ 11783 preferDocument: true, 11784 didInput: false 11785 }); 11786 (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || _this$delegate2.inputControllerWillPerformTyping(); 11787 (_this$responder6 = this.responder) === null || _this$responder6 === void 0 || _this$responder6.setSelectedRange(this.range); 11788 (_this$responder7 = this.responder) === null || _this$responder7 === void 0 || _this$responder7.insertString(this.data.end); 11789 return (_this$responder8 = this.responder) === null || _this$responder8 === void 0 ? void 0 : _this$responder8.setSelectedRange(this.range[0] + this.data.end.length); 11790 } else if (this.data.start != null || this.data.update != null) { 11791 this.requestReparse(); 11792 return this.inputController.reset(); 11793 } 11794 } else { 11795 return this.inputController.reset(); 11796 } 11797 } 11798 getEndData() { 11799 return this.data.end; 11800 } 11801 isEnded() { 11802 return this.getEndData() != null; 11803 } 11804 isSignificant() { 11805 if (browser.composesExistingText) { 11806 return this.inputSummary.didInput; 11807 } else { 11808 return true; 11809 } 11810 } 11811 11812 // Private 11813 11814 canApplyToDocument() { 11815 var _this$data$start, _this$data$end; 11816 return ((_this$data$start = this.data.start) === null || _this$data$start === void 0 ? void 0 : _this$data$start.length) === 0 && ((_this$data$end = this.data.end) === null || _this$data$end === void 0 ? void 0 : _this$data$end.length) > 0 && this.range; 11817 } 11818 } 11819 CompositionInput.proxyMethod("inputController.setInputSummary"); 11820 CompositionInput.proxyMethod("inputController.requestRender"); 11821 CompositionInput.proxyMethod("inputController.requestReparse"); 11822 CompositionInput.proxyMethod("responder?.selectionIsExpanded"); 11823 CompositionInput.proxyMethod("responder?.insertPlaceholder"); 11824 CompositionInput.proxyMethod("responder?.selectPlaceholder"); 11825 CompositionInput.proxyMethod("responder?.forgetPlaceholder"); 11826 11827 class Level2InputController extends InputController { 11828 constructor() { 11829 super(...arguments); 11830 this.render = this.render.bind(this); 11831 } 11832 elementDidMutate() { 11833 if (this.scheduledRender) { 11834 if (this.composing) { 11835 var _this$delegate, _this$delegate$inputC; 11836 return (_this$delegate = this.delegate) === null || _this$delegate === void 0 || (_this$delegate$inputC = _this$delegate.inputControllerDidAllowUnhandledInput) === null || _this$delegate$inputC === void 0 ? void 0 : _this$delegate$inputC.call(_this$delegate); 11837 } 11838 } else { 11839 return this.reparse(); 11840 } 11841 } 11842 scheduleRender() { 11843 return this.scheduledRender ? this.scheduledRender : this.scheduledRender = requestAnimationFrame(this.render); 11844 } 11845 render() { 11846 var _this$afterRender; 11847 cancelAnimationFrame(this.scheduledRender); 11848 this.scheduledRender = null; 11849 if (!this.composing) { 11850 var _this$delegate2; 11851 (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || _this$delegate2.render(); 11852 } 11853 (_this$afterRender = this.afterRender) === null || _this$afterRender === void 0 || _this$afterRender.call(this); 11854 this.afterRender = null; 11855 } 11856 reparse() { 11857 var _this$delegate3; 11858 return (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 ? void 0 : _this$delegate3.reparse(); 11859 } 11860 11861 // Responder helpers 11862 11863 insertString() { 11864 var _this$delegate4; 11865 let string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; 11866 let options = arguments.length > 1 ? arguments[1] : undefined; 11867 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillPerformTyping(); 11868 return this.withTargetDOMRange(function () { 11869 var _this$responder; 11870 return (_this$responder = this.responder) === null || _this$responder === void 0 ? void 0 : _this$responder.insertString(string, options); 11871 }); 11872 } 11873 toggleAttributeIfSupported(attributeName) { 11874 if (getAllAttributeNames().includes(attributeName)) { 11875 var _this$delegate5; 11876 (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.inputControllerWillPerformFormatting(attributeName); 11877 return this.withTargetDOMRange(function () { 11878 var _this$responder2; 11879 return (_this$responder2 = this.responder) === null || _this$responder2 === void 0 ? void 0 : _this$responder2.toggleCurrentAttribute(attributeName); 11880 }); 11881 } 11882 } 11883 activateAttributeIfSupported(attributeName, value) { 11884 if (getAllAttributeNames().includes(attributeName)) { 11885 var _this$delegate6; 11886 (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 || _this$delegate6.inputControllerWillPerformFormatting(attributeName); 11887 return this.withTargetDOMRange(function () { 11888 var _this$responder3; 11889 return (_this$responder3 = this.responder) === null || _this$responder3 === void 0 ? void 0 : _this$responder3.setCurrentAttribute(attributeName, value); 11890 }); 11891 } 11892 } 11893 deleteInDirection(direction) { 11894 let { 11895 recordUndoEntry 11896 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { 11897 recordUndoEntry: true 11898 }; 11899 if (recordUndoEntry) { 11900 var _this$delegate7; 11901 (_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || _this$delegate7.inputControllerWillPerformTyping(); 11902 } 11903 const perform = () => { 11904 var _this$responder4; 11905 return (_this$responder4 = this.responder) === null || _this$responder4 === void 0 ? void 0 : _this$responder4.deleteInDirection(direction); 11906 }; 11907 const domRange = this.getTargetDOMRange({ 11908 minLength: this.composing ? 1 : 2 11909 }); 11910 if (domRange) { 11911 return this.withTargetDOMRange(domRange, perform); 11912 } else { 11913 return perform(); 11914 } 11915 } 11916 11917 // Selection helpers 11918 11919 withTargetDOMRange(domRange, fn) { 11920 if (typeof domRange === "function") { 11921 fn = domRange; 11922 domRange = this.getTargetDOMRange(); 11923 } 11924 if (domRange) { 11925 var _this$responder5; 11926 return (_this$responder5 = this.responder) === null || _this$responder5 === void 0 ? void 0 : _this$responder5.withTargetDOMRange(domRange, fn.bind(this)); 11927 } else { 11928 selectionChangeObserver.reset(); 11929 return fn.call(this); 11930 } 11931 } 11932 getTargetDOMRange() { 11933 var _this$event$getTarget, _this$event; 11934 let { 11935 minLength 11936 } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { 11937 minLength: 0 11938 }; 11939 const targetRanges = (_this$event$getTarget = (_this$event = this.event).getTargetRanges) === null || _this$event$getTarget === void 0 ? void 0 : _this$event$getTarget.call(_this$event); 11940 if (targetRanges) { 11941 if (targetRanges.length) { 11942 const domRange = staticRangeToRange(targetRanges[0]); 11943 if (minLength === 0 || domRange.toString().length >= minLength) { 11944 return domRange; 11945 } 11946 } 11947 } 11948 } 11949 withEvent(event, fn) { 11950 let result; 11951 this.event = event; 11952 try { 11953 result = fn.call(this); 11954 } finally { 11955 this.event = null; 11956 } 11957 return result; 11958 } 11959 } 11960 _defineProperty(Level2InputController, "events", { 11961 keydown(event) { 11962 if (keyEventIsKeyboardCommand(event)) { 11963 var _this$delegate8; 11964 const command = keyboardCommandFromKeyEvent(event); 11965 if ((_this$delegate8 = this.delegate) !== null && _this$delegate8 !== void 0 && _this$delegate8.inputControllerDidReceiveKeyboardCommand(command)) { 11966 event.preventDefault(); 11967 } 11968 } else { 11969 let name = event.key; 11970 if (event.altKey) { 11971 name += "+Alt"; 11972 } 11973 if (event.shiftKey) { 11974 name += "+Shift"; 11975 } 11976 const handler = this.constructor.keys[name]; 11977 if (handler) { 11978 return this.withEvent(event, handler); 11979 } 11980 } 11981 }, 11982 // Handle paste event to work around beforeinput.insertFromPaste browser bugs. 11983 // Safe to remove each condition once fixed upstream. 11984 paste(event) { 11985 var _event$clipboardData; 11986 // https://bugs.webkit.org/show_bug.cgi?id=194921 11987 let paste; 11988 const href = (_event$clipboardData = event.clipboardData) === null || _event$clipboardData === void 0 ? void 0 : _event$clipboardData.getData("URL"); 11989 if (pasteEventHasFilesOnly(event)) { 11990 event.preventDefault(); 11991 return this.attachFiles(event.clipboardData.files); 11992 11993 // https://bugs.chromium.org/p/chromium/issues/detail?id=934448 11994 } else if (pasteEventHasPlainTextOnly(event)) { 11995 var _this$delegate9, _this$responder6, _this$delegate10; 11996 event.preventDefault(); 11997 paste = { 11998 type: "text/plain", 11999 string: event.clipboardData.getData("text/plain") 12000 }; 12001 (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 || _this$delegate9.inputControllerWillPaste(paste); 12002 (_this$responder6 = this.responder) === null || _this$responder6 === void 0 || _this$responder6.insertString(paste.string); 12003 this.render(); 12004 return (_this$delegate10 = this.delegate) === null || _this$delegate10 === void 0 ? void 0 : _this$delegate10.inputControllerDidPaste(paste); 12005 12006 // https://bugs.webkit.org/show_bug.cgi?id=196702 12007 } else if (href) { 12008 var _this$delegate11, _this$responder7, _this$delegate12; 12009 event.preventDefault(); 12010 paste = { 12011 type: "text/html", 12012 html: this.createLinkHTML(href) 12013 }; 12014 (_this$delegate11 = this.delegate) === null || _this$delegate11 === void 0 || _this$delegate11.inputControllerWillPaste(paste); 12015 (_this$responder7 = this.responder) === null || _this$responder7 === void 0 || _this$responder7.insertHTML(paste.html); 12016 this.render(); 12017 return (_this$delegate12 = this.delegate) === null || _this$delegate12 === void 0 ? void 0 : _this$delegate12.inputControllerDidPaste(paste); 12018 } 12019 }, 12020 beforeinput(event) { 12021 const handler = this.constructor.inputTypes[event.inputType]; 12022 const immmediateRender = shouldRenderInmmediatelyToDealWithIOSDictation(event); 12023 if (handler) { 12024 this.withEvent(event, handler); 12025 if (!immmediateRender) { 12026 this.scheduleRender(); 12027 } 12028 } 12029 if (immmediateRender) { 12030 this.render(); 12031 } 12032 }, 12033 input(event) { 12034 selectionChangeObserver.reset(); 12035 }, 12036 dragstart(event) { 12037 var _this$responder8; 12038 if ((_this$responder8 = this.responder) !== null && _this$responder8 !== void 0 && _this$responder8.selectionContainsAttachments()) { 12039 var _this$responder9; 12040 event.dataTransfer.setData("application/x-trix-dragging", true); 12041 this.dragging = { 12042 range: (_this$responder9 = this.responder) === null || _this$responder9 === void 0 ? void 0 : _this$responder9.getSelectedRange(), 12043 point: pointFromEvent(event) 12044 }; 12045 } 12046 }, 12047 dragenter(event) { 12048 if (dragEventHasFiles(event)) { 12049 event.preventDefault(); 12050 } 12051 }, 12052 dragover(event) { 12053 if (this.dragging) { 12054 event.preventDefault(); 12055 const point = pointFromEvent(event); 12056 if (!objectsAreEqual(point, this.dragging.point)) { 12057 var _this$responder10; 12058 this.dragging.point = point; 12059 return (_this$responder10 = this.responder) === null || _this$responder10 === void 0 ? void 0 : _this$responder10.setLocationRangeFromPointRange(point); 12060 } 12061 } else if (dragEventHasFiles(event)) { 12062 event.preventDefault(); 12063 } 12064 }, 12065 drop(event) { 12066 if (this.dragging) { 12067 var _this$delegate13, _this$responder11; 12068 event.preventDefault(); 12069 (_this$delegate13 = this.delegate) === null || _this$delegate13 === void 0 || _this$delegate13.inputControllerWillMoveText(); 12070 (_this$responder11 = this.responder) === null || _this$responder11 === void 0 || _this$responder11.moveTextFromRange(this.dragging.range); 12071 this.dragging = null; 12072 return this.scheduleRender(); 12073 } else if (dragEventHasFiles(event)) { 12074 var _this$responder12; 12075 event.preventDefault(); 12076 const point = pointFromEvent(event); 12077 (_this$responder12 = this.responder) === null || _this$responder12 === void 0 || _this$responder12.setLocationRangeFromPointRange(point); 12078 return this.attachFiles(event.dataTransfer.files); 12079 } 12080 }, 12081 dragend() { 12082 if (this.dragging) { 12083 var _this$responder13; 12084 (_this$responder13 = this.responder) === null || _this$responder13 === void 0 || _this$responder13.setSelectedRange(this.dragging.range); 12085 this.dragging = null; 12086 } 12087 }, 12088 compositionend(event) { 12089 if (this.composing) { 12090 this.composing = false; 12091 if (!browser$1.recentAndroid) this.scheduleRender(); 12092 } 12093 } 12094 }); 12095 _defineProperty(Level2InputController, "keys", { 12096 ArrowLeft() { 12097 var _this$responder14; 12098 if ((_this$responder14 = this.responder) !== null && _this$responder14 !== void 0 && _this$responder14.shouldManageMovingCursorInDirection("backward")) { 12099 var _this$responder15; 12100 this.event.preventDefault(); 12101 return (_this$responder15 = this.responder) === null || _this$responder15 === void 0 ? void 0 : _this$responder15.moveCursorInDirection("backward"); 12102 } 12103 }, 12104 ArrowRight() { 12105 var _this$responder16; 12106 if ((_this$responder16 = this.responder) !== null && _this$responder16 !== void 0 && _this$responder16.shouldManageMovingCursorInDirection("forward")) { 12107 var _this$responder17; 12108 this.event.preventDefault(); 12109 return (_this$responder17 = this.responder) === null || _this$responder17 === void 0 ? void 0 : _this$responder17.moveCursorInDirection("forward"); 12110 } 12111 }, 12112 Backspace() { 12113 var _this$responder18; 12114 if ((_this$responder18 = this.responder) !== null && _this$responder18 !== void 0 && _this$responder18.shouldManageDeletingInDirection("backward")) { 12115 var _this$delegate14, _this$responder19; 12116 this.event.preventDefault(); 12117 (_this$delegate14 = this.delegate) === null || _this$delegate14 === void 0 || _this$delegate14.inputControllerWillPerformTyping(); 12118 (_this$responder19 = this.responder) === null || _this$responder19 === void 0 || _this$responder19.deleteInDirection("backward"); 12119 return this.render(); 12120 } 12121 }, 12122 Tab() { 12123 var _this$responder20; 12124 if ((_this$responder20 = this.responder) !== null && _this$responder20 !== void 0 && _this$responder20.canIncreaseNestingLevel()) { 12125 var _this$responder21; 12126 this.event.preventDefault(); 12127 (_this$responder21 = this.responder) === null || _this$responder21 === void 0 || _this$responder21.increaseNestingLevel(); 12128 return this.render(); 12129 } 12130 }, 12131 "Tab+Shift"() { 12132 var _this$responder22; 12133 if ((_this$responder22 = this.responder) !== null && _this$responder22 !== void 0 && _this$responder22.canDecreaseNestingLevel()) { 12134 var _this$responder23; 12135 this.event.preventDefault(); 12136 (_this$responder23 = this.responder) === null || _this$responder23 === void 0 || _this$responder23.decreaseNestingLevel(); 12137 return this.render(); 12138 } 12139 } 12140 }); 12141 _defineProperty(Level2InputController, "inputTypes", { 12142 deleteByComposition() { 12143 return this.deleteInDirection("backward", { 12144 recordUndoEntry: false 12145 }); 12146 }, 12147 deleteByCut() { 12148 return this.deleteInDirection("backward"); 12149 }, 12150 deleteByDrag() { 12151 this.event.preventDefault(); 12152 return this.withTargetDOMRange(function () { 12153 var _this$responder24; 12154 this.deleteByDragRange = (_this$responder24 = this.responder) === null || _this$responder24 === void 0 ? void 0 : _this$responder24.getSelectedRange(); 12155 }); 12156 }, 12157 deleteCompositionText() { 12158 return this.deleteInDirection("backward", { 12159 recordUndoEntry: false 12160 }); 12161 }, 12162 deleteContent() { 12163 return this.deleteInDirection("backward"); 12164 }, 12165 deleteContentBackward() { 12166 return this.deleteInDirection("backward"); 12167 }, 12168 deleteContentForward() { 12169 return this.deleteInDirection("forward"); 12170 }, 12171 deleteEntireSoftLine() { 12172 return this.deleteInDirection("forward"); 12173 }, 12174 deleteHardLineBackward() { 12175 return this.deleteInDirection("backward"); 12176 }, 12177 deleteHardLineForward() { 12178 return this.deleteInDirection("forward"); 12179 }, 12180 deleteSoftLineBackward() { 12181 return this.deleteInDirection("backward"); 12182 }, 12183 deleteSoftLineForward() { 12184 return this.deleteInDirection("forward"); 12185 }, 12186 deleteWordBackward() { 12187 return this.deleteInDirection("backward"); 12188 }, 12189 deleteWordForward() { 12190 return this.deleteInDirection("forward"); 12191 }, 12192 formatBackColor() { 12193 return this.activateAttributeIfSupported("backgroundColor", this.event.data); 12194 }, 12195 formatBold() { 12196 return this.toggleAttributeIfSupported("bold"); 12197 }, 12198 formatFontColor() { 12199 return this.activateAttributeIfSupported("color", this.event.data); 12200 }, 12201 formatFontName() { 12202 return this.activateAttributeIfSupported("font", this.event.data); 12203 }, 12204 formatIndent() { 12205 var _this$responder25; 12206 if ((_this$responder25 = this.responder) !== null && _this$responder25 !== void 0 && _this$responder25.canIncreaseNestingLevel()) { 12207 return this.withTargetDOMRange(function () { 12208 var _this$responder26; 12209 return (_this$responder26 = this.responder) === null || _this$responder26 === void 0 ? void 0 : _this$responder26.increaseNestingLevel(); 12210 }); 12211 } 12212 }, 12213 formatItalic() { 12214 return this.toggleAttributeIfSupported("italic"); 12215 }, 12216 formatJustifyCenter() { 12217 return this.toggleAttributeIfSupported("justifyCenter"); 12218 }, 12219 formatJustifyFull() { 12220 return this.toggleAttributeIfSupported("justifyFull"); 12221 }, 12222 formatJustifyLeft() { 12223 return this.toggleAttributeIfSupported("justifyLeft"); 12224 }, 12225 formatJustifyRight() { 12226 return this.toggleAttributeIfSupported("justifyRight"); 12227 }, 12228 formatOutdent() { 12229 var _this$responder27; 12230 if ((_this$responder27 = this.responder) !== null && _this$responder27 !== void 0 && _this$responder27.canDecreaseNestingLevel()) { 12231 return this.withTargetDOMRange(function () { 12232 var _this$responder28; 12233 return (_this$responder28 = this.responder) === null || _this$responder28 === void 0 ? void 0 : _this$responder28.decreaseNestingLevel(); 12234 }); 12235 } 12236 }, 12237 formatRemove() { 12238 this.withTargetDOMRange(function () { 12239 for (const attributeName in (_this$responder29 = this.responder) === null || _this$responder29 === void 0 ? void 0 : _this$responder29.getCurrentAttributes()) { 12240 var _this$responder29, _this$responder30; 12241 (_this$responder30 = this.responder) === null || _this$responder30 === void 0 || _this$responder30.removeCurrentAttribute(attributeName); 12242 } 12243 }); 12244 }, 12245 formatSetBlockTextDirection() { 12246 return this.activateAttributeIfSupported("blockDir", this.event.data); 12247 }, 12248 formatSetInlineTextDirection() { 12249 return this.activateAttributeIfSupported("textDir", this.event.data); 12250 }, 12251 formatStrikeThrough() { 12252 return this.toggleAttributeIfSupported("strike"); 12253 }, 12254 formatSubscript() { 12255 return this.toggleAttributeIfSupported("sub"); 12256 }, 12257 formatSuperscript() { 12258 return this.toggleAttributeIfSupported("sup"); 12259 }, 12260 formatUnderline() { 12261 return this.toggleAttributeIfSupported("underline"); 12262 }, 12263 historyRedo() { 12264 var _this$delegate15; 12265 return (_this$delegate15 = this.delegate) === null || _this$delegate15 === void 0 ? void 0 : _this$delegate15.inputControllerWillPerformRedo(); 12266 }, 12267 historyUndo() { 12268 var _this$delegate16; 12269 return (_this$delegate16 = this.delegate) === null || _this$delegate16 === void 0 ? void 0 : _this$delegate16.inputControllerWillPerformUndo(); 12270 }, 12271 insertCompositionText() { 12272 this.composing = true; 12273 return this.insertString(this.event.data); 12274 }, 12275 insertFromComposition() { 12276 this.composing = false; 12277 return this.insertString(this.event.data); 12278 }, 12279 insertFromDrop() { 12280 const range = this.deleteByDragRange; 12281 if (range) { 12282 var _this$delegate17; 12283 this.deleteByDragRange = null; 12284 (_this$delegate17 = this.delegate) === null || _this$delegate17 === void 0 || _this$delegate17.inputControllerWillMoveText(); 12285 return this.withTargetDOMRange(function () { 12286 var _this$responder31; 12287 return (_this$responder31 = this.responder) === null || _this$responder31 === void 0 ? void 0 : _this$responder31.moveTextFromRange(range); 12288 }); 12289 } 12290 }, 12291 insertFromPaste() { 12292 const { 12293 dataTransfer 12294 } = this.event; 12295 const paste = { 12296 dataTransfer 12297 }; 12298 const href = dataTransfer.getData("URL"); 12299 const html = dataTransfer.getData("text/html"); 12300 if (href) { 12301 var _this$delegate18; 12302 let string; 12303 this.event.preventDefault(); 12304 paste.type = "text/html"; 12305 const name = dataTransfer.getData("public.url-name"); 12306 if (name) { 12307 string = squishBreakableWhitespace(name).trim(); 12308 } else { 12309 string = href; 12310 } 12311 paste.html = this.createLinkHTML(href, string); 12312 (_this$delegate18 = this.delegate) === null || _this$delegate18 === void 0 || _this$delegate18.inputControllerWillPaste(paste); 12313 this.withTargetDOMRange(function () { 12314 var _this$responder32; 12315 return (_this$responder32 = this.responder) === null || _this$responder32 === void 0 ? void 0 : _this$responder32.insertHTML(paste.html); 12316 }); 12317 this.afterRender = () => { 12318 var _this$delegate19; 12319 return (_this$delegate19 = this.delegate) === null || _this$delegate19 === void 0 ? void 0 : _this$delegate19.inputControllerDidPaste(paste); 12320 }; 12321 } else if (dataTransferIsPlainText(dataTransfer)) { 12322 var _this$delegate20; 12323 paste.type = "text/plain"; 12324 paste.string = dataTransfer.getData("text/plain"); 12325 (_this$delegate20 = this.delegate) === null || _this$delegate20 === void 0 || _this$delegate20.inputControllerWillPaste(paste); 12326 this.withTargetDOMRange(function () { 12327 var _this$responder33; 12328 return (_this$responder33 = this.responder) === null || _this$responder33 === void 0 ? void 0 : _this$responder33.insertString(paste.string); 12329 }); 12330 this.afterRender = () => { 12331 var _this$delegate21; 12332 return (_this$delegate21 = this.delegate) === null || _this$delegate21 === void 0 ? void 0 : _this$delegate21.inputControllerDidPaste(paste); 12333 }; 12334 } else if (processableFilePaste(this.event)) { 12335 var _this$delegate22; 12336 paste.type = "File"; 12337 paste.file = dataTransfer.files[0]; 12338 (_this$delegate22 = this.delegate) === null || _this$delegate22 === void 0 || _this$delegate22.inputControllerWillPaste(paste); 12339 this.withTargetDOMRange(function () { 12340 var _this$responder34; 12341 return (_this$responder34 = this.responder) === null || _this$responder34 === void 0 ? void 0 : _this$responder34.insertFile(paste.file); 12342 }); 12343 this.afterRender = () => { 12344 var _this$delegate23; 12345 return (_this$delegate23 = this.delegate) === null || _this$delegate23 === void 0 ? void 0 : _this$delegate23.inputControllerDidPaste(paste); 12346 }; 12347 } else if (html) { 12348 var _this$delegate24; 12349 this.event.preventDefault(); 12350 paste.type = "text/html"; 12351 paste.html = html; 12352 (_this$delegate24 = this.delegate) === null || _this$delegate24 === void 0 || _this$delegate24.inputControllerWillPaste(paste); 12353 this.withTargetDOMRange(function () { 12354 var _this$responder35; 12355 return (_this$responder35 = this.responder) === null || _this$responder35 === void 0 ? void 0 : _this$responder35.insertHTML(paste.html); 12356 }); 12357 this.afterRender = () => { 12358 var _this$delegate25; 12359 return (_this$delegate25 = this.delegate) === null || _this$delegate25 === void 0 ? void 0 : _this$delegate25.inputControllerDidPaste(paste); 12360 }; 12361 } 12362 }, 12363 insertFromYank() { 12364 return this.insertString(this.event.data); 12365 }, 12366 insertLineBreak() { 12367 return this.insertString("\n"); 12368 }, 12369 insertLink() { 12370 return this.activateAttributeIfSupported("href", this.event.data); 12371 }, 12372 insertOrderedList() { 12373 return this.toggleAttributeIfSupported("number"); 12374 }, 12375 insertParagraph() { 12376 var _this$delegate26; 12377 (_this$delegate26 = this.delegate) === null || _this$delegate26 === void 0 || _this$delegate26.inputControllerWillPerformTyping(); 12378 return this.withTargetDOMRange(function () { 12379 var _this$responder36; 12380 return (_this$responder36 = this.responder) === null || _this$responder36 === void 0 ? void 0 : _this$responder36.insertLineBreak(); 12381 }); 12382 }, 12383 insertReplacementText() { 12384 const replacement = this.event.dataTransfer.getData("text/plain"); 12385 const domRange = this.event.getTargetRanges()[0]; 12386 this.withTargetDOMRange(domRange, () => { 12387 this.insertString(replacement, { 12388 updatePosition: false 12389 }); 12390 }); 12391 }, 12392 insertText() { 12393 var _this$event$dataTrans; 12394 return this.insertString(this.event.data || ((_this$event$dataTrans = this.event.dataTransfer) === null || _this$event$dataTrans === void 0 ? void 0 : _this$event$dataTrans.getData("text/plain"))); 12395 }, 12396 insertTranspose() { 12397 return this.insertString(this.event.data); 12398 }, 12399 insertUnorderedList() { 12400 return this.toggleAttributeIfSupported("bullet"); 12401 } 12402 }); 12403 const staticRangeToRange = function (staticRange) { 12404 const range = document.createRange(); 12405 range.setStart(staticRange.startContainer, staticRange.startOffset); 12406 range.setEnd(staticRange.endContainer, staticRange.endOffset); 12407 return range; 12408 }; 12409 12410 // Event helpers 12411 12412 const dragEventHasFiles = event => { 12413 var _event$dataTransfer; 12414 return Array.from(((_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.types) || []).includes("Files"); 12415 }; 12416 const processableFilePaste = event => { 12417 var _event$dataTransfer$f; 12418 // Paste events that only have files are handled by the paste event handler, 12419 // to work around Safari not supporting beforeinput.insertFromPaste for files. 12420 12421 // MS Office text pastes include a file with a screenshot of the text, but we should 12422 // handle them as text pastes. 12423 return ((_event$dataTransfer$f = event.dataTransfer.files) === null || _event$dataTransfer$f === void 0 ? void 0 : _event$dataTransfer$f[0]) && !pasteEventHasFilesOnly(event) && !dataTransferIsMsOfficePaste(event); 12424 }; 12425 const pasteEventHasFilesOnly = function (event) { 12426 const clipboard = event.clipboardData; 12427 if (clipboard) { 12428 const fileTypes = Array.from(clipboard.types).filter(type => type.match(/file/i)); // "Files", "application/x-moz-file" 12429 return fileTypes.length === clipboard.types.length && clipboard.files.length >= 1; 12430 } 12431 }; 12432 const pasteEventHasPlainTextOnly = function (event) { 12433 const clipboard = event.clipboardData; 12434 if (clipboard) { 12435 return clipboard.types.includes("text/plain") && clipboard.types.length === 1; 12436 } 12437 }; 12438 const keyboardCommandFromKeyEvent = function (event) { 12439 const command = []; 12440 if (event.altKey) { 12441 command.push("alt"); 12442 } 12443 if (event.shiftKey) { 12444 command.push("shift"); 12445 } 12446 command.push(event.key); 12447 return command; 12448 }; 12449 const pointFromEvent = event => ({ 12450 x: event.clientX, 12451 y: event.clientY 12452 }); 12453 12454 const attributeButtonSelector = "[data-trix-attribute]"; 12455 const actionButtonSelector = "[data-trix-action]"; 12456 const toolbarButtonSelector = "".concat(attributeButtonSelector, ", ").concat(actionButtonSelector); 12457 const dialogSelector = "[data-trix-dialog]"; 12458 const activeDialogSelector = "".concat(dialogSelector, "[data-trix-active]"); 12459 const dialogButtonSelector = "".concat(dialogSelector, " [data-trix-method]"); 12460 const dialogInputSelector = "".concat(dialogSelector, " [data-trix-input]"); 12461 const getInputForDialog = (element, attributeName) => { 12462 if (!attributeName) { 12463 attributeName = getAttributeName(element); 12464 } 12465 return element.querySelector("[data-trix-input][name='".concat(attributeName, "']")); 12466 }; 12467 const getActionName = element => element.getAttribute("data-trix-action"); 12468 const getAttributeName = element => { 12469 return element.getAttribute("data-trix-attribute") || element.getAttribute("data-trix-dialog-attribute"); 12470 }; 12471 const getDialogName = element => element.getAttribute("data-trix-dialog"); 12472 class ToolbarController extends BasicObject { 12473 constructor(element) { 12474 super(element); 12475 this.didClickActionButton = this.didClickActionButton.bind(this); 12476 this.didClickAttributeButton = this.didClickAttributeButton.bind(this); 12477 this.didClickDialogButton = this.didClickDialogButton.bind(this); 12478 this.didKeyDownDialogInput = this.didKeyDownDialogInput.bind(this); 12479 this.element = element; 12480 this.attributes = {}; 12481 this.actions = {}; 12482 this.resetDialogInputs(); 12483 handleEvent("mousedown", { 12484 onElement: this.element, 12485 matchingSelector: actionButtonSelector, 12486 withCallback: this.didClickActionButton 12487 }); 12488 handleEvent("mousedown", { 12489 onElement: this.element, 12490 matchingSelector: attributeButtonSelector, 12491 withCallback: this.didClickAttributeButton 12492 }); 12493 handleEvent("click", { 12494 onElement: this.element, 12495 matchingSelector: toolbarButtonSelector, 12496 preventDefault: true 12497 }); 12498 handleEvent("click", { 12499 onElement: this.element, 12500 matchingSelector: dialogButtonSelector, 12501 withCallback: this.didClickDialogButton 12502 }); 12503 handleEvent("keydown", { 12504 onElement: this.element, 12505 matchingSelector: dialogInputSelector, 12506 withCallback: this.didKeyDownDialogInput 12507 }); 12508 } 12509 12510 // Event handlers 12511 12512 didClickActionButton(event, element) { 12513 var _this$delegate; 12514 (_this$delegate = this.delegate) === null || _this$delegate === void 0 || _this$delegate.toolbarDidClickButton(); 12515 event.preventDefault(); 12516 const actionName = getActionName(element); 12517 if (this.getDialog(actionName)) { 12518 return this.toggleDialog(actionName); 12519 } else { 12520 var _this$delegate2; 12521 return (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 ? void 0 : _this$delegate2.toolbarDidInvokeAction(actionName, element); 12522 } 12523 } 12524 didClickAttributeButton(event, element) { 12525 var _this$delegate3; 12526 (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || _this$delegate3.toolbarDidClickButton(); 12527 event.preventDefault(); 12528 const attributeName = getAttributeName(element); 12529 if (this.getDialog(attributeName)) { 12530 this.toggleDialog(attributeName); 12531 } else { 12532 var _this$delegate4; 12533 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.toolbarDidToggleAttribute(attributeName); 12534 } 12535 return this.refreshAttributeButtons(); 12536 } 12537 didClickDialogButton(event, element) { 12538 const dialogElement = findClosestElementFromNode(element, { 12539 matchingSelector: dialogSelector 12540 }); 12541 const method = element.getAttribute("data-trix-method"); 12542 return this[method].call(this, dialogElement); 12543 } 12544 didKeyDownDialogInput(event, element) { 12545 if (event.keyCode === 13) { 12546 // Enter key 12547 event.preventDefault(); 12548 const attribute = element.getAttribute("name"); 12549 const dialog = this.getDialog(attribute); 12550 this.setAttribute(dialog); 12551 } 12552 if (event.keyCode === 27) { 12553 // Escape key 12554 event.preventDefault(); 12555 return this.hideDialog(); 12556 } 12557 } 12558 12559 // Action buttons 12560 12561 updateActions(actions) { 12562 this.actions = actions; 12563 return this.refreshActionButtons(); 12564 } 12565 refreshActionButtons() { 12566 return this.eachActionButton((element, actionName) => { 12567 element.disabled = this.actions[actionName] === false; 12568 }); 12569 } 12570 eachActionButton(callback) { 12571 return Array.from(this.element.querySelectorAll(actionButtonSelector)).map(element => callback(element, getActionName(element))); 12572 } 12573 12574 // Attribute buttons 12575 12576 updateAttributes(attributes) { 12577 this.attributes = attributes; 12578 return this.refreshAttributeButtons(); 12579 } 12580 refreshAttributeButtons() { 12581 return this.eachAttributeButton((element, attributeName) => { 12582 element.disabled = this.attributes[attributeName] === false; 12583 if (this.attributes[attributeName] || this.dialogIsVisible(attributeName)) { 12584 element.setAttribute("data-trix-active", ""); 12585 return element.classList.add("trix-active"); 12586 } else { 12587 element.removeAttribute("data-trix-active"); 12588 return element.classList.remove("trix-active"); 12589 } 12590 }); 12591 } 12592 eachAttributeButton(callback) { 12593 return Array.from(this.element.querySelectorAll(attributeButtonSelector)).map(element => callback(element, getAttributeName(element))); 12594 } 12595 applyKeyboardCommand(keys) { 12596 const keyString = JSON.stringify(keys.sort()); 12597 for (const button of Array.from(this.element.querySelectorAll("[data-trix-key]"))) { 12598 const buttonKeys = button.getAttribute("data-trix-key").split("+"); 12599 const buttonKeyString = JSON.stringify(buttonKeys.sort()); 12600 if (buttonKeyString === keyString) { 12601 triggerEvent("mousedown", { 12602 onElement: button 12603 }); 12604 return true; 12605 } 12606 } 12607 return false; 12608 } 12609 12610 // Dialogs 12611 12612 dialogIsVisible(dialogName) { 12613 const element = this.getDialog(dialogName); 12614 if (element) { 12615 return element.hasAttribute("data-trix-active"); 12616 } 12617 } 12618 toggleDialog(dialogName) { 12619 if (this.dialogIsVisible(dialogName)) { 12620 return this.hideDialog(); 12621 } else { 12622 return this.showDialog(dialogName); 12623 } 12624 } 12625 showDialog(dialogName) { 12626 var _this$delegate5, _this$delegate6; 12627 this.hideDialog(); 12628 (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.toolbarWillShowDialog(); 12629 const element = this.getDialog(dialogName); 12630 element.setAttribute("data-trix-active", ""); 12631 element.classList.add("trix-active"); 12632 Array.from(element.querySelectorAll("input[disabled]")).forEach(disabledInput => { 12633 disabledInput.removeAttribute("disabled"); 12634 }); 12635 const attributeName = getAttributeName(element); 12636 if (attributeName) { 12637 const input = getInputForDialog(element, dialogName); 12638 if (input) { 12639 input.value = this.attributes[attributeName] || ""; 12640 input.select(); 12641 } 12642 } 12643 return (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 ? void 0 : _this$delegate6.toolbarDidShowDialog(dialogName); 12644 } 12645 setAttribute(dialogElement) { 12646 var _this$delegate7; 12647 const attributeName = getAttributeName(dialogElement); 12648 const input = getInputForDialog(dialogElement, attributeName); 12649 if (input.willValidate) { 12650 input.setCustomValidity(""); 12651 if (!input.checkValidity() || !this.isSafeAttribute(input)) { 12652 input.setCustomValidity("Invalid value"); 12653 input.setAttribute("data-trix-validate", ""); 12654 input.classList.add("trix-validate"); 12655 return input.focus(); 12656 } 12657 } 12658 (_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || _this$delegate7.toolbarDidUpdateAttribute(attributeName, input.value); 12659 return this.hideDialog(); 12660 } 12661 isSafeAttribute(input) { 12662 if (input.hasAttribute("data-trix-validate-href")) { 12663 return purify.isValidAttribute("a", "href", input.value); 12664 } else { 12665 return true; 12666 } 12667 } 12668 removeAttribute(dialogElement) { 12669 var _this$delegate8; 12670 const attributeName = getAttributeName(dialogElement); 12671 (_this$delegate8 = this.delegate) === null || _this$delegate8 === void 0 || _this$delegate8.toolbarDidRemoveAttribute(attributeName); 12672 return this.hideDialog(); 12673 } 12674 hideDialog() { 12675 const element = this.element.querySelector(activeDialogSelector); 12676 if (element) { 12677 var _this$delegate9; 12678 element.removeAttribute("data-trix-active"); 12679 element.classList.remove("trix-active"); 12680 this.resetDialogInputs(); 12681 return (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 ? void 0 : _this$delegate9.toolbarDidHideDialog(getDialogName(element)); 12682 } 12683 } 12684 resetDialogInputs() { 12685 Array.from(this.element.querySelectorAll(dialogInputSelector)).forEach(input => { 12686 input.setAttribute("disabled", "disabled"); 12687 input.removeAttribute("data-trix-validate"); 12688 input.classList.remove("trix-validate"); 12689 }); 12690 } 12691 getDialog(dialogName) { 12692 return this.element.querySelector("[data-trix-dialog=".concat(dialogName, "]")); 12693 } 12694 } 12695 12696 const snapshotsAreEqual = (a, b) => rangesAreEqual(a.selectedRange, b.selectedRange) && a.document.isEqualTo(b.document); 12697 class EditorController extends Controller { 12698 constructor(_ref) { 12699 let { 12700 editorElement, 12701 document, 12702 html 12703 } = _ref; 12704 super(...arguments); 12705 this.editorElement = editorElement; 12706 this.selectionManager = new SelectionManager(this.editorElement); 12707 this.selectionManager.delegate = this; 12708 this.composition = new Composition(); 12709 this.composition.delegate = this; 12710 this.attachmentManager = new AttachmentManager(this.composition.getAttachments()); 12711 this.attachmentManager.delegate = this; 12712 this.inputController = input.getLevel() === 2 ? new Level2InputController(this.editorElement) : new Level0InputController(this.editorElement); 12713 this.inputController.delegate = this; 12714 this.inputController.responder = this.composition; 12715 this.compositionController = new CompositionController(this.editorElement, this.composition); 12716 this.compositionController.delegate = this; 12717 this.toolbarController = new ToolbarController(this.editorElement.toolbarElement); 12718 this.toolbarController.delegate = this; 12719 this.editor = new Editor(this.composition, this.selectionManager, this.editorElement); 12720 if (document) { 12721 this.editor.loadDocument(document); 12722 } else { 12723 this.editor.loadHTML(html); 12724 } 12725 } 12726 registerSelectionManager() { 12727 return selectionChangeObserver.registerSelectionManager(this.selectionManager); 12728 } 12729 unregisterSelectionManager() { 12730 return selectionChangeObserver.unregisterSelectionManager(this.selectionManager); 12731 } 12732 render() { 12733 return this.compositionController.render(); 12734 } 12735 reparse() { 12736 return this.composition.replaceHTML(this.editorElement.innerHTML); 12737 } 12738 12739 // Composition delegate 12740 12741 compositionDidChangeDocument(document) { 12742 this.notifyEditorElement("document-change"); 12743 if (!this.handlingInput) { 12744 return this.render(); 12745 } 12746 } 12747 compositionDidChangeCurrentAttributes(currentAttributes) { 12748 this.currentAttributes = currentAttributes; 12749 this.toolbarController.updateAttributes(this.currentAttributes); 12750 this.updateCurrentActions(); 12751 return this.notifyEditorElement("attributes-change", { 12752 attributes: this.currentAttributes 12753 }); 12754 } 12755 compositionDidPerformInsertionAtRange(range) { 12756 if (this.pasting) { 12757 this.pastedRange = range; 12758 } 12759 } 12760 compositionShouldAcceptFile(file) { 12761 return this.notifyEditorElement("file-accept", { 12762 file 12763 }); 12764 } 12765 compositionDidAddAttachment(attachment) { 12766 const managedAttachment = this.attachmentManager.manageAttachment(attachment); 12767 return this.notifyEditorElement("attachment-add", { 12768 attachment: managedAttachment 12769 }); 12770 } 12771 compositionDidEditAttachment(attachment) { 12772 this.compositionController.rerenderViewForObject(attachment); 12773 const managedAttachment = this.attachmentManager.manageAttachment(attachment); 12774 this.notifyEditorElement("attachment-edit", { 12775 attachment: managedAttachment 12776 }); 12777 return this.notifyEditorElement("change"); 12778 } 12779 compositionDidChangeAttachmentPreviewURL(attachment) { 12780 this.compositionController.invalidateViewForObject(attachment); 12781 return this.notifyEditorElement("change"); 12782 } 12783 compositionDidRemoveAttachment(attachment) { 12784 const managedAttachment = this.attachmentManager.unmanageAttachment(attachment); 12785 return this.notifyEditorElement("attachment-remove", { 12786 attachment: managedAttachment 12787 }); 12788 } 12789 compositionDidStartEditingAttachment(attachment, options) { 12790 this.attachmentLocationRange = this.composition.document.getLocationRangeOfAttachment(attachment); 12791 this.compositionController.installAttachmentEditorForAttachment(attachment, options); 12792 return this.selectionManager.setLocationRange(this.attachmentLocationRange); 12793 } 12794 compositionDidStopEditingAttachment(attachment) { 12795 this.compositionController.uninstallAttachmentEditor(); 12796 this.attachmentLocationRange = null; 12797 } 12798 compositionDidRequestChangingSelectionToLocationRange(locationRange) { 12799 if (this.loadingSnapshot && !this.isFocused()) return; 12800 this.requestedLocationRange = locationRange; 12801 this.compositionRevisionWhenLocationRangeRequested = this.composition.revision; 12802 if (!this.handlingInput) { 12803 return this.render(); 12804 } 12805 } 12806 compositionWillLoadSnapshot() { 12807 this.loadingSnapshot = true; 12808 } 12809 compositionDidLoadSnapshot() { 12810 this.compositionController.refreshViewCache(); 12811 this.render(); 12812 this.loadingSnapshot = false; 12813 } 12814 getSelectionManager() { 12815 return this.selectionManager; 12816 } 12817 12818 // Attachment manager delegate 12819 12820 attachmentManagerDidRequestRemovalOfAttachment(attachment) { 12821 return this.removeAttachment(attachment); 12822 } 12823 12824 // Document controller delegate 12825 12826 compositionControllerWillSyncDocumentView() { 12827 this.inputController.editorWillSyncDocumentView(); 12828 this.selectionManager.lock(); 12829 return this.selectionManager.clearSelection(); 12830 } 12831 compositionControllerDidSyncDocumentView() { 12832 this.inputController.editorDidSyncDocumentView(); 12833 this.selectionManager.unlock(); 12834 this.updateCurrentActions(); 12835 return this.notifyEditorElement("sync"); 12836 } 12837 compositionControllerDidRender() { 12838 if (this.requestedLocationRange) { 12839 if (this.compositionRevisionWhenLocationRangeRequested === this.composition.revision) { 12840 this.selectionManager.setLocationRange(this.requestedLocationRange); 12841 } 12842 this.requestedLocationRange = null; 12843 this.compositionRevisionWhenLocationRangeRequested = null; 12844 } 12845 if (this.renderedCompositionRevision !== this.composition.revision) { 12846 this.runEditorFilters(); 12847 this.composition.updateCurrentAttributes(); 12848 this.notifyEditorElement("render"); 12849 } 12850 this.renderedCompositionRevision = this.composition.revision; 12851 } 12852 compositionControllerDidFocus() { 12853 if (this.isFocusedInvisibly()) { 12854 this.setLocationRange({ 12855 index: 0, 12856 offset: 0 12857 }); 12858 } 12859 this.toolbarController.hideDialog(); 12860 return this.notifyEditorElement("focus"); 12861 } 12862 compositionControllerDidBlur() { 12863 return this.notifyEditorElement("blur"); 12864 } 12865 compositionControllerDidSelectAttachment(attachment, options) { 12866 this.toolbarController.hideDialog(); 12867 return this.composition.editAttachment(attachment, options); 12868 } 12869 compositionControllerDidRequestDeselectingAttachment(attachment) { 12870 const locationRange = this.attachmentLocationRange || this.composition.document.getLocationRangeOfAttachment(attachment); 12871 return this.selectionManager.setLocationRange(locationRange[1]); 12872 } 12873 compositionControllerWillUpdateAttachment(attachment) { 12874 return this.editor.recordUndoEntry("Edit Attachment", { 12875 context: attachment.id, 12876 consolidatable: true 12877 }); 12878 } 12879 compositionControllerDidRequestRemovalOfAttachment(attachment) { 12880 return this.removeAttachment(attachment); 12881 } 12882 12883 // Input controller delegate 12884 12885 inputControllerWillHandleInput() { 12886 this.handlingInput = true; 12887 this.requestedRender = false; 12888 } 12889 inputControllerDidRequestRender() { 12890 this.requestedRender = true; 12891 } 12892 inputControllerDidHandleInput() { 12893 this.handlingInput = false; 12894 if (this.requestedRender) { 12895 this.requestedRender = false; 12896 return this.render(); 12897 } 12898 } 12899 inputControllerDidAllowUnhandledInput() { 12900 return this.notifyEditorElement("change"); 12901 } 12902 inputControllerDidRequestReparse() { 12903 return this.reparse(); 12904 } 12905 inputControllerWillPerformTyping() { 12906 return this.recordTypingUndoEntry(); 12907 } 12908 inputControllerWillPerformFormatting(attributeName) { 12909 return this.recordFormattingUndoEntry(attributeName); 12910 } 12911 inputControllerWillCutText() { 12912 return this.editor.recordUndoEntry("Cut"); 12913 } 12914 inputControllerWillPaste(paste) { 12915 this.editor.recordUndoEntry("Paste"); 12916 this.pasting = true; 12917 return this.notifyEditorElement("before-paste", { 12918 paste 12919 }); 12920 } 12921 inputControllerDidPaste(paste) { 12922 paste.range = this.pastedRange; 12923 this.pastedRange = null; 12924 this.pasting = null; 12925 return this.notifyEditorElement("paste", { 12926 paste 12927 }); 12928 } 12929 inputControllerWillMoveText() { 12930 return this.editor.recordUndoEntry("Move"); 12931 } 12932 inputControllerWillAttachFiles() { 12933 return this.editor.recordUndoEntry("Drop Files"); 12934 } 12935 inputControllerWillPerformUndo() { 12936 return this.editor.undo(); 12937 } 12938 inputControllerWillPerformRedo() { 12939 return this.editor.redo(); 12940 } 12941 inputControllerDidReceiveKeyboardCommand(keys) { 12942 return this.toolbarController.applyKeyboardCommand(keys); 12943 } 12944 inputControllerDidStartDrag() { 12945 this.locationRangeBeforeDrag = this.selectionManager.getLocationRange(); 12946 } 12947 inputControllerDidReceiveDragOverPoint(point) { 12948 return this.selectionManager.setLocationRangeFromPointRange(point); 12949 } 12950 inputControllerDidCancelDrag() { 12951 this.selectionManager.setLocationRange(this.locationRangeBeforeDrag); 12952 this.locationRangeBeforeDrag = null; 12953 } 12954 12955 // Selection manager delegate 12956 12957 locationRangeDidChange(locationRange) { 12958 this.composition.updateCurrentAttributes(); 12959 this.updateCurrentActions(); 12960 if (this.attachmentLocationRange && !rangesAreEqual(this.attachmentLocationRange, locationRange)) { 12961 this.composition.stopEditingAttachment(); 12962 } 12963 return this.notifyEditorElement("selection-change"); 12964 } 12965 12966 // Toolbar controller delegate 12967 12968 toolbarDidClickButton() { 12969 if (!this.getLocationRange()) { 12970 return this.setLocationRange({ 12971 index: 0, 12972 offset: 0 12973 }); 12974 } 12975 } 12976 toolbarDidInvokeAction(actionName, invokingElement) { 12977 return this.invokeAction(actionName, invokingElement); 12978 } 12979 toolbarDidToggleAttribute(attributeName) { 12980 this.recordFormattingUndoEntry(attributeName); 12981 this.composition.toggleCurrentAttribute(attributeName); 12982 this.render(); 12983 if (!this.selectionFrozen) { 12984 return this.editorElement.focus(); 12985 } 12986 } 12987 toolbarDidUpdateAttribute(attributeName, value) { 12988 this.recordFormattingUndoEntry(attributeName); 12989 this.composition.setCurrentAttribute(attributeName, value); 12990 this.render(); 12991 if (!this.selectionFrozen) { 12992 return this.editorElement.focus(); 12993 } 12994 } 12995 toolbarDidRemoveAttribute(attributeName) { 12996 this.recordFormattingUndoEntry(attributeName); 12997 this.composition.removeCurrentAttribute(attributeName); 12998 this.render(); 12999 if (!this.selectionFrozen) { 13000 return this.editorElement.focus(); 13001 } 13002 } 13003 toolbarWillShowDialog(dialogElement) { 13004 this.composition.expandSelectionForEditing(); 13005 return this.freezeSelection(); 13006 } 13007 toolbarDidShowDialog(dialogName) { 13008 return this.notifyEditorElement("toolbar-dialog-show", { 13009 dialogName 13010 }); 13011 } 13012 toolbarDidHideDialog(dialogName) { 13013 this.thawSelection(); 13014 this.editorElement.focus(); 13015 return this.notifyEditorElement("toolbar-dialog-hide", { 13016 dialogName 13017 }); 13018 } 13019 13020 // Selection 13021 13022 freezeSelection() { 13023 if (!this.selectionFrozen) { 13024 this.selectionManager.lock(); 13025 this.composition.freezeSelection(); 13026 this.selectionFrozen = true; 13027 return this.render(); 13028 } 13029 } 13030 thawSelection() { 13031 if (this.selectionFrozen) { 13032 this.composition.thawSelection(); 13033 this.selectionManager.unlock(); 13034 this.selectionFrozen = false; 13035 return this.render(); 13036 } 13037 } 13038 canInvokeAction(actionName) { 13039 if (this.actionIsExternal(actionName)) { 13040 return true; 13041 } else { 13042 var _this$actions$actionN; 13043 return !!((_this$actions$actionN = this.actions[actionName]) !== null && _this$actions$actionN !== void 0 && (_this$actions$actionN = _this$actions$actionN.test) !== null && _this$actions$actionN !== void 0 && _this$actions$actionN.call(this)); 13044 } 13045 } 13046 invokeAction(actionName, invokingElement) { 13047 if (this.actionIsExternal(actionName)) { 13048 return this.notifyEditorElement("action-invoke", { 13049 actionName, 13050 invokingElement 13051 }); 13052 } else { 13053 var _this$actions$actionN2; 13054 return (_this$actions$actionN2 = this.actions[actionName]) === null || _this$actions$actionN2 === void 0 || (_this$actions$actionN2 = _this$actions$actionN2.perform) === null || _this$actions$actionN2 === void 0 ? void 0 : _this$actions$actionN2.call(this); 13055 } 13056 } 13057 actionIsExternal(actionName) { 13058 return /^x-./.test(actionName); 13059 } 13060 getCurrentActions() { 13061 const result = {}; 13062 for (const actionName in this.actions) { 13063 result[actionName] = this.canInvokeAction(actionName); 13064 } 13065 return result; 13066 } 13067 updateCurrentActions() { 13068 const currentActions = this.getCurrentActions(); 13069 if (!objectsAreEqual(currentActions, this.currentActions)) { 13070 this.currentActions = currentActions; 13071 this.toolbarController.updateActions(this.currentActions); 13072 return this.notifyEditorElement("actions-change", { 13073 actions: this.currentActions 13074 }); 13075 } 13076 } 13077 13078 // Editor filters 13079 13080 runEditorFilters() { 13081 let snapshot = this.composition.getSnapshot(); 13082 Array.from(this.editor.filters).forEach(filter => { 13083 const { 13084 document, 13085 selectedRange 13086 } = snapshot; 13087 snapshot = filter.call(this.editor, snapshot) || {}; 13088 if (!snapshot.document) { 13089 snapshot.document = document; 13090 } 13091 if (!snapshot.selectedRange) { 13092 snapshot.selectedRange = selectedRange; 13093 } 13094 }); 13095 if (!snapshotsAreEqual(snapshot, this.composition.getSnapshot())) { 13096 return this.composition.loadSnapshot(snapshot); 13097 } 13098 } 13099 13100 // Private 13101 13102 updateInputElement() { 13103 const element = this.compositionController.getSerializableElement(); 13104 const value = serializeToContentType(element, "text/html"); 13105 return this.editorElement.setFormValue(value); 13106 } 13107 notifyEditorElement(message, data) { 13108 switch (message) { 13109 case "document-change": 13110 this.documentChangedSinceLastRender = true; 13111 break; 13112 case "render": 13113 if (this.documentChangedSinceLastRender) { 13114 this.documentChangedSinceLastRender = false; 13115 this.notifyEditorElement("change"); 13116 } 13117 break; 13118 case "change": 13119 case "attachment-add": 13120 case "attachment-edit": 13121 case "attachment-remove": 13122 this.updateInputElement(); 13123 break; 13124 } 13125 return this.editorElement.notify(message, data); 13126 } 13127 removeAttachment(attachment) { 13128 this.editor.recordUndoEntry("Delete Attachment"); 13129 this.composition.removeAttachment(attachment); 13130 return this.render(); 13131 } 13132 recordFormattingUndoEntry(attributeName) { 13133 const blockConfig = getBlockConfig(attributeName); 13134 const locationRange = this.selectionManager.getLocationRange(); 13135 if (blockConfig || !rangeIsCollapsed(locationRange)) { 13136 return this.editor.recordUndoEntry("Formatting", { 13137 context: this.getUndoContext(), 13138 consolidatable: true 13139 }); 13140 } 13141 } 13142 recordTypingUndoEntry() { 13143 return this.editor.recordUndoEntry("Typing", { 13144 context: this.getUndoContext(this.currentAttributes), 13145 consolidatable: true 13146 }); 13147 } 13148 getUndoContext() { 13149 for (var _len = arguments.length, context = new Array(_len), _key = 0; _key < _len; _key++) { 13150 context[_key] = arguments[_key]; 13151 } 13152 return [this.getLocationContext(), this.getTimeContext(), ...Array.from(context)]; 13153 } 13154 getLocationContext() { 13155 const locationRange = this.selectionManager.getLocationRange(); 13156 if (rangeIsCollapsed(locationRange)) { 13157 return locationRange[0].index; 13158 } else { 13159 return locationRange; 13160 } 13161 } 13162 getTimeContext() { 13163 if (undo.interval > 0) { 13164 return Math.floor(new Date().getTime() / undo.interval); 13165 } else { 13166 return 0; 13167 } 13168 } 13169 isFocused() { 13170 var _this$editorElement$o; 13171 return this.editorElement === ((_this$editorElement$o = this.editorElement.ownerDocument) === null || _this$editorElement$o === void 0 ? void 0 : _this$editorElement$o.activeElement); 13172 } 13173 13174 // Detect "Cursor disappears sporadically" Firefox bug. 13175 // - https://bugzilla.mozilla.org/show_bug.cgi?id=226301 13176 isFocusedInvisibly() { 13177 return this.isFocused() && !this.getLocationRange(); 13178 } 13179 get actions() { 13180 return this.constructor.actions; 13181 } 13182 } 13183 _defineProperty(EditorController, "actions", { 13184 undo: { 13185 test() { 13186 return this.editor.canUndo(); 13187 }, 13188 perform() { 13189 return this.editor.undo(); 13190 } 13191 }, 13192 redo: { 13193 test() { 13194 return this.editor.canRedo(); 13195 }, 13196 perform() { 13197 return this.editor.redo(); 13198 } 13199 }, 13200 link: { 13201 test() { 13202 return this.editor.canActivateAttribute("href"); 13203 } 13204 }, 13205 increaseNestingLevel: { 13206 test() { 13207 return this.editor.canIncreaseNestingLevel(); 13208 }, 13209 perform() { 13210 return this.editor.increaseNestingLevel() && this.render(); 13211 } 13212 }, 13213 decreaseNestingLevel: { 13214 test() { 13215 return this.editor.canDecreaseNestingLevel(); 13216 }, 13217 perform() { 13218 return this.editor.decreaseNestingLevel() && this.render(); 13219 } 13220 }, 13221 attachFiles: { 13222 test() { 13223 return true; 13224 }, 13225 perform() { 13226 return input.pickFiles(this.editor.insertFiles); 13227 } 13228 } 13229 }); 13230 EditorController.proxyMethod("getSelectionManager().setLocationRange"); 13231 EditorController.proxyMethod("getSelectionManager().getLocationRange"); 13232 13233 var controllers = /*#__PURE__*/Object.freeze({ 13234 __proto__: null, 13235 AttachmentEditorController: AttachmentEditorController, 13236 CompositionController: CompositionController, 13237 Controller: Controller, 13238 EditorController: EditorController, 13239 InputController: InputController, 13240 Level0InputController: Level0InputController, 13241 Level2InputController: Level2InputController, 13242 ToolbarController: ToolbarController 13243 }); 13244 13245 var observers = /*#__PURE__*/Object.freeze({ 13246 __proto__: null, 13247 MutationObserver: MutationObserver, 13248 SelectionChangeObserver: SelectionChangeObserver 13249 }); 13250 13251 var operations = /*#__PURE__*/Object.freeze({ 13252 __proto__: null, 13253 FileVerificationOperation: FileVerificationOperation, 13254 ImagePreloadOperation: ImagePreloadOperation 13255 }); 13256 13257 installDefaultCSSForTagName("trix-toolbar", "%t {\n display: block;\n}\n\n%t {\n white-space: nowrap;\n}\n\n%t [data-trix-dialog] {\n display: none;\n}\n\n%t [data-trix-dialog][data-trix-active] {\n display: block;\n}\n\n%t [data-trix-dialog] [data-trix-validate]:invalid {\n background-color: #ffdddd;\n}"); 13258 class TrixToolbarElement extends HTMLElement { 13259 // Element lifecycle 13260 13261 connectedCallback() { 13262 if (this.innerHTML === "") { 13263 this.innerHTML = toolbar.getDefaultHTML(); 13264 } 13265 } 13266 13267 // Properties 13268 13269 get editorElements() { 13270 if (this.id) { 13271 var _this$ownerDocument; 13272 const nodeList = (_this$ownerDocument = this.ownerDocument) === null || _this$ownerDocument === void 0 ? void 0 : _this$ownerDocument.querySelectorAll("trix-editor[toolbar=\"".concat(this.id, "\"]")); 13273 return Array.from(nodeList); 13274 } else { 13275 return []; 13276 } 13277 } 13278 get editorElement() { 13279 const [editorElement] = this.editorElements; 13280 return editorElement; 13281 } 13282 } 13283 13284 let id = 0; 13285 13286 // Contenteditable support helpers 13287 13288 const autofocus = function (element) { 13289 if (!document.querySelector(":focus")) { 13290 if (element.hasAttribute("autofocus") && document.querySelector("[autofocus]") === element) { 13291 return element.focus(); 13292 } 13293 } 13294 }; 13295 const makeEditable = function (element) { 13296 if (element.hasAttribute("contenteditable")) { 13297 return; 13298 } 13299 element.toggleAttribute("contenteditable", !element.disabled); 13300 return handleEventOnce("focus", { 13301 onElement: element, 13302 withCallback() { 13303 return configureContentEditable(element); 13304 } 13305 }); 13306 }; 13307 const configureContentEditable = function (element) { 13308 disableObjectResizing(element); 13309 return setDefaultParagraphSeparator(element); 13310 }; 13311 const disableObjectResizing = function (element) { 13312 var _document$queryComman, _document; 13313 if ((_document$queryComman = (_document = document).queryCommandSupported) !== null && _document$queryComman !== void 0 && _document$queryComman.call(_document, "enableObjectResizing")) { 13314 document.execCommand("enableObjectResizing", false, false); 13315 return handleEvent("mscontrolselect", { 13316 onElement: element, 13317 preventDefault: true 13318 }); 13319 } 13320 }; 13321 const setDefaultParagraphSeparator = function (element) { 13322 var _document$queryComman2, _document2; 13323 if ((_document$queryComman2 = (_document2 = document).queryCommandSupported) !== null && _document$queryComman2 !== void 0 && _document$queryComman2.call(_document2, "DefaultParagraphSeparator")) { 13324 const { 13325 tagName 13326 } = attributes.default; 13327 if (["div", "p"].includes(tagName)) { 13328 return document.execCommand("DefaultParagraphSeparator", false, tagName); 13329 } 13330 } 13331 }; 13332 13333 // Accessibility helpers 13334 13335 const addAccessibilityRole = function (element) { 13336 if (element.hasAttribute("role")) { 13337 return; 13338 } 13339 return element.setAttribute("role", "textbox"); 13340 }; 13341 const ensureAriaLabel = function (element) { 13342 if (element.hasAttribute("aria-label") || element.hasAttribute("aria-labelledby")) { 13343 return; 13344 } 13345 const update = function () { 13346 const texts = Array.from(element.labels).map(label => { 13347 if (!label.contains(element)) return label.textContent; 13348 }).filter(text => text); 13349 const text = texts.join(" "); 13350 if (text) { 13351 return element.setAttribute("aria-label", text); 13352 } else { 13353 return element.removeAttribute("aria-label"); 13354 } 13355 }; 13356 update(); 13357 return handleEvent("focus", { 13358 onElement: element, 13359 withCallback: update 13360 }); 13361 }; 13362 13363 // Style 13364 13365 const cursorTargetStyles = function () { 13366 if (browser$1.forcesObjectResizing) { 13367 return { 13368 display: "inline", 13369 width: "auto" 13370 }; 13371 } else { 13372 return { 13373 display: "inline-block", 13374 width: "1px" 13375 }; 13376 } 13377 }(); 13378 installDefaultCSSForTagName("trix-editor", "%t {\n display: block;\n}\n\n%t:empty::before {\n content: attr(placeholder);\n color: graytext;\n cursor: text;\n pointer-events: none;\n white-space: pre-line;\n}\n\n%t a[contenteditable=false] {\n cursor: text;\n}\n\n%t img {\n max-width: 100%;\n height: auto;\n}\n\n%t ".concat(attachmentSelector, " figcaption textarea {\n resize: none;\n}\n\n%t ").concat(attachmentSelector, " figcaption textarea.trix-autoresize-clone {\n position: absolute;\n left: -9999px;\n max-height: 0px;\n}\n\n%t ").concat(attachmentSelector, " figcaption[data-trix-placeholder]:empty::before {\n content: attr(data-trix-placeholder);\n color: graytext;\n}\n\n%t [data-trix-cursor-target] {\n display: ").concat(cursorTargetStyles.display, " !important;\n width: ").concat(cursorTargetStyles.width, " !important;\n padding: 0 !important;\n margin: 0 !important;\n border: none !important;\n}\n\n%t [data-trix-cursor-target=left] {\n vertical-align: top !important;\n margin-left: -1px !important;\n}\n\n%t [data-trix-cursor-target=right] {\n vertical-align: bottom !important;\n margin-right: -1px !important;\n}")); 13379 var _internals = /*#__PURE__*/new WeakMap(); 13380 var _formDisabled = /*#__PURE__*/new WeakMap(); 13381 var _validate = /*#__PURE__*/new WeakSet(); 13382 class ElementInternalsDelegate { 13383 constructor(element) { 13384 _classPrivateMethodInitSpec(this, _validate); 13385 _defineProperty(this, "value", ""); 13386 _classPrivateFieldInitSpec(this, _internals, { 13387 writable: true, 13388 value: void 0 13389 }); 13390 _classPrivateFieldInitSpec(this, _formDisabled, { 13391 writable: true, 13392 value: void 0 13393 }); 13394 this.element = element; 13395 _classPrivateFieldSet(this, _internals, element.attachInternals()); 13396 _classPrivateFieldSet(this, _formDisabled, false); 13397 } 13398 connectedCallback() { 13399 _classPrivateMethodGet(this, _validate, _validate2).call(this); 13400 } 13401 disconnectedCallback() {} 13402 get form() { 13403 return _classPrivateFieldGet(this, _internals).form; 13404 } 13405 get name() { 13406 return this.element.getAttribute("name"); 13407 } 13408 set name(value) { 13409 this.element.setAttribute("name", value); 13410 } 13411 get labels() { 13412 return _classPrivateFieldGet(this, _internals).labels; 13413 } 13414 get disabled() { 13415 return _classPrivateFieldGet(this, _formDisabled) || this.element.hasAttribute("disabled"); 13416 } 13417 set disabled(value) { 13418 this.element.toggleAttribute("disabled", value); 13419 } 13420 get required() { 13421 return this.element.hasAttribute("required"); 13422 } 13423 set required(value) { 13424 this.element.toggleAttribute("required", value); 13425 _classPrivateMethodGet(this, _validate, _validate2).call(this); 13426 } 13427 get validity() { 13428 return _classPrivateFieldGet(this, _internals).validity; 13429 } 13430 get validationMessage() { 13431 return _classPrivateFieldGet(this, _internals).validationMessage; 13432 } 13433 get willValidate() { 13434 return _classPrivateFieldGet(this, _internals).willValidate; 13435 } 13436 formDisabledCallback(disabled) { 13437 _classPrivateFieldSet(this, _formDisabled, disabled); 13438 } 13439 setFormValue(value) { 13440 this.value = value; 13441 _classPrivateMethodGet(this, _validate, _validate2).call(this); 13442 _classPrivateFieldGet(this, _internals).setFormValue(this.element.disabled ? undefined : this.value); 13443 } 13444 checkValidity() { 13445 return _classPrivateFieldGet(this, _internals).checkValidity(); 13446 } 13447 reportValidity() { 13448 return _classPrivateFieldGet(this, _internals).reportValidity(); 13449 } 13450 setCustomValidity(validationMessage) { 13451 _classPrivateMethodGet(this, _validate, _validate2).call(this, validationMessage); 13452 } 13453 } 13454 function _validate2() { 13455 let customValidationMessage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; 13456 const { 13457 required, 13458 value 13459 } = this.element; 13460 const valueMissing = required && !value; 13461 const customError = !!customValidationMessage; 13462 const input = makeElement("input", { 13463 required 13464 }); 13465 const validationMessage = customValidationMessage || input.validationMessage; 13466 _classPrivateFieldGet(this, _internals).setValidity({ 13467 valueMissing, 13468 customError 13469 }, validationMessage); 13470 } 13471 var _focusHandler = /*#__PURE__*/new WeakMap(); 13472 var _resetBubbled = /*#__PURE__*/new WeakMap(); 13473 var _clickBubbled = /*#__PURE__*/new WeakMap(); 13474 class LegacyDelegate { 13475 constructor(element) { 13476 _classPrivateFieldInitSpec(this, _focusHandler, { 13477 writable: true, 13478 value: void 0 13479 }); 13480 _classPrivateFieldInitSpec(this, _resetBubbled, { 13481 writable: true, 13482 value: event => { 13483 if (event.defaultPrevented) return; 13484 if (event.target !== this.element.form) return; 13485 this.element.reset(); 13486 } 13487 }); 13488 _classPrivateFieldInitSpec(this, _clickBubbled, { 13489 writable: true, 13490 value: event => { 13491 if (event.defaultPrevented) return; 13492 if (this.element.contains(event.target)) return; 13493 const label = findClosestElementFromNode(event.target, { 13494 matchingSelector: "label" 13495 }); 13496 if (!label) return; 13497 if (!Array.from(this.labels).includes(label)) return; 13498 this.element.focus(); 13499 } 13500 }); 13501 this.element = element; 13502 } 13503 connectedCallback() { 13504 _classPrivateFieldSet(this, _focusHandler, ensureAriaLabel(this.element)); 13505 window.addEventListener("reset", _classPrivateFieldGet(this, _resetBubbled), false); 13506 window.addEventListener("click", _classPrivateFieldGet(this, _clickBubbled), false); 13507 } 13508 disconnectedCallback() { 13509 var _classPrivateFieldGet2; 13510 (_classPrivateFieldGet2 = _classPrivateFieldGet(this, _focusHandler)) === null || _classPrivateFieldGet2 === void 0 || _classPrivateFieldGet2.destroy(); 13511 window.removeEventListener("reset", _classPrivateFieldGet(this, _resetBubbled), false); 13512 window.removeEventListener("click", _classPrivateFieldGet(this, _clickBubbled), false); 13513 } 13514 get labels() { 13515 const labels = []; 13516 if (this.element.id && this.element.ownerDocument) { 13517 labels.push(...Array.from(this.element.ownerDocument.querySelectorAll("label[for='".concat(this.element.id, "']")) || [])); 13518 } 13519 const label = findClosestElementFromNode(this.element, { 13520 matchingSelector: "label" 13521 }); 13522 if (label) { 13523 if ([this.element, null].includes(label.control)) { 13524 labels.push(label); 13525 } 13526 } 13527 return labels; 13528 } 13529 get form() { 13530 console.warn("This browser does not support the .form property for trix-editor elements."); 13531 return null; 13532 } 13533 get name() { 13534 console.warn("This browser does not support the .name property for trix-editor elements."); 13535 return null; 13536 } 13537 set name(value) { 13538 console.warn("This browser does not support the .name property for trix-editor elements."); 13539 } 13540 get disabled() { 13541 console.warn("This browser does not support the [disabled] attribute for trix-editor elements."); 13542 return false; 13543 } 13544 set disabled(value) { 13545 console.warn("This browser does not support the [disabled] attribute for trix-editor elements."); 13546 } 13547 get required() { 13548 console.warn("This browser does not support the [required] attribute for trix-editor elements."); 13549 return false; 13550 } 13551 set required(value) { 13552 console.warn("This browser does not support the [required] attribute for trix-editor elements."); 13553 } 13554 get validity() { 13555 console.warn("This browser does not support the validity property for trix-editor elements."); 13556 return null; 13557 } 13558 get validationMessage() { 13559 console.warn("This browser does not support the validationMessage property for trix-editor elements."); 13560 return ""; 13561 } 13562 get willValidate() { 13563 console.warn("This browser does not support the willValidate property for trix-editor elements."); 13564 return false; 13565 } 13566 formDisabledCallback(value) {} 13567 setFormValue(value) {} 13568 checkValidity() { 13569 console.warn("This browser does not support checkValidity() for trix-editor elements."); 13570 return true; 13571 } 13572 reportValidity() { 13573 console.warn("This browser does not support reportValidity() for trix-editor elements."); 13574 return true; 13575 } 13576 setCustomValidity(validationMessage) { 13577 console.warn("This browser does not support setCustomValidity(validationMessage) for trix-editor elements."); 13578 } 13579 } 13580 var _delegate = /*#__PURE__*/new WeakMap(); 13581 class TrixEditorElement extends HTMLElement { 13582 constructor() { 13583 super(); 13584 _classPrivateFieldInitSpec(this, _delegate, { 13585 writable: true, 13586 value: void 0 13587 }); 13588 this.willCreateInput = true; 13589 _classPrivateFieldSet(this, _delegate, this.constructor.formAssociated ? new ElementInternalsDelegate(this) : new LegacyDelegate(this)); 13590 } 13591 13592 // Properties 13593 13594 get trixId() { 13595 if (this.hasAttribute("trix-id")) { 13596 return this.getAttribute("trix-id"); 13597 } else { 13598 this.setAttribute("trix-id", ++id); 13599 return this.trixId; 13600 } 13601 } 13602 get labels() { 13603 return _classPrivateFieldGet(this, _delegate).labels; 13604 } 13605 get disabled() { 13606 const { 13607 inputElement 13608 } = this; 13609 if (inputElement) { 13610 return inputElement.disabled; 13611 } else { 13612 return _classPrivateFieldGet(this, _delegate).disabled; 13613 } 13614 } 13615 set disabled(value) { 13616 const { 13617 inputElement 13618 } = this; 13619 if (inputElement) { 13620 inputElement.disabled = value; 13621 } 13622 _classPrivateFieldGet(this, _delegate).disabled = value; 13623 } 13624 get required() { 13625 return _classPrivateFieldGet(this, _delegate).required; 13626 } 13627 set required(value) { 13628 _classPrivateFieldGet(this, _delegate).required = value; 13629 } 13630 get validity() { 13631 return _classPrivateFieldGet(this, _delegate).validity; 13632 } 13633 get validationMessage() { 13634 return _classPrivateFieldGet(this, _delegate).validationMessage; 13635 } 13636 get willValidate() { 13637 return _classPrivateFieldGet(this, _delegate).willValidate; 13638 } 13639 get type() { 13640 return this.localName; 13641 } 13642 get toolbarElement() { 13643 if (this.hasAttribute("toolbar")) { 13644 var _this$ownerDocument; 13645 return (_this$ownerDocument = this.ownerDocument) === null || _this$ownerDocument === void 0 ? void 0 : _this$ownerDocument.getElementById(this.getAttribute("toolbar")); 13646 } else if (this.parentNode) { 13647 const toolbarId = "trix-toolbar-".concat(this.trixId); 13648 this.setAttribute("toolbar", toolbarId); 13649 this.internalToolbar = makeElement("trix-toolbar", { 13650 id: toolbarId 13651 }); 13652 this.parentNode.insertBefore(this.internalToolbar, this); 13653 return this.internalToolbar; 13654 } else { 13655 return undefined; 13656 } 13657 } 13658 get form() { 13659 const { 13660 inputElement 13661 } = this; 13662 if (inputElement) { 13663 return inputElement.form; 13664 } else { 13665 return _classPrivateFieldGet(this, _delegate).form; 13666 } 13667 } 13668 get inputElement() { 13669 if (this.hasAttribute("input")) { 13670 var _this$ownerDocument2; 13671 return (_this$ownerDocument2 = this.ownerDocument) === null || _this$ownerDocument2 === void 0 ? void 0 : _this$ownerDocument2.getElementById(this.getAttribute("input")); 13672 } else { 13673 return undefined; 13674 } 13675 } 13676 get editor() { 13677 var _this$editorControlle; 13678 return (_this$editorControlle = this.editorController) === null || _this$editorControlle === void 0 ? void 0 : _this$editorControlle.editor; 13679 } 13680 get name() { 13681 const { 13682 inputElement 13683 } = this; 13684 if (inputElement) { 13685 return inputElement.name; 13686 } else { 13687 return _classPrivateFieldGet(this, _delegate).name; 13688 } 13689 } 13690 set name(value) { 13691 const { 13692 inputElement 13693 } = this; 13694 if (inputElement) { 13695 inputElement.name = value; 13696 } else { 13697 _classPrivateFieldGet(this, _delegate).name = value; 13698 } 13699 } 13700 get value() { 13701 const { 13702 inputElement 13703 } = this; 13704 if (inputElement) { 13705 return inputElement.value; 13706 } else { 13707 return _classPrivateFieldGet(this, _delegate).value; 13708 } 13709 } 13710 set value(defaultValue) { 13711 var _this$editor; 13712 this.defaultValue = defaultValue; 13713 (_this$editor = this.editor) === null || _this$editor === void 0 || _this$editor.loadHTML(this.defaultValue); 13714 } 13715 13716 // Element callbacks 13717 13718 attributeChangedCallback(name, oldValue, newValue) { 13719 if (name === "connected" && this.isConnected && oldValue != null && oldValue !== newValue) { 13720 requestAnimationFrame(() => this.reconnect()); 13721 } 13722 } 13723 13724 // Controller delegate methods 13725 13726 notify(message, data) { 13727 if (this.editorController) { 13728 return triggerEvent("trix-".concat(message), { 13729 onElement: this, 13730 attributes: data 13731 }); 13732 } 13733 } 13734 setFormValue(value) { 13735 const { 13736 inputElement 13737 } = this; 13738 if (inputElement) { 13739 inputElement.value = value; 13740 } 13741 _classPrivateFieldGet(this, _delegate).setFormValue(value); 13742 } 13743 13744 // Element lifecycle 13745 13746 connectedCallback() { 13747 if (!this.hasAttribute("data-trix-internal")) { 13748 makeEditable(this); 13749 addAccessibilityRole(this); 13750 if (!this.editorController) { 13751 triggerEvent("trix-before-initialize", { 13752 onElement: this 13753 }); 13754 this.defaultValue = this.inputElement ? this.inputElement.value : this.innerHTML; 13755 if (!this.hasAttribute("input") && this.parentNode && this.willCreateInput) { 13756 const inputId = "trix-input-".concat(this.trixId); 13757 this.setAttribute("input", inputId); 13758 const element = makeElement("input", { 13759 type: "hidden", 13760 id: inputId 13761 }); 13762 this.parentNode.insertBefore(element, this.nextElementSibling); 13763 } 13764 this.editorController = new EditorController({ 13765 editorElement: this, 13766 html: this.defaultValue 13767 }); 13768 requestAnimationFrame(() => triggerEvent("trix-initialize", { 13769 onElement: this 13770 })); 13771 } 13772 this.editorController.registerSelectionManager(); 13773 _classPrivateFieldGet(this, _delegate).connectedCallback(); 13774 this.toggleAttribute("connected", true); 13775 autofocus(this); 13776 } 13777 } 13778 disconnectedCallback() { 13779 var _this$editorControlle2; 13780 (_this$editorControlle2 = this.editorController) === null || _this$editorControlle2 === void 0 || _this$editorControlle2.unregisterSelectionManager(); 13781 _classPrivateFieldGet(this, _delegate).disconnectedCallback(); 13782 this.toggleAttribute("connected", false); 13783 } 13784 reconnect() { 13785 this.removeInternalToolbar(); 13786 this.disconnectedCallback(); 13787 this.connectedCallback(); 13788 } 13789 removeInternalToolbar() { 13790 var _this$internalToolbar; 13791 (_this$internalToolbar = this.internalToolbar) === null || _this$internalToolbar === void 0 || _this$internalToolbar.remove(); 13792 this.internalToolbar = null; 13793 } 13794 13795 // Form support 13796 13797 checkValidity() { 13798 return _classPrivateFieldGet(this, _delegate).checkValidity(); 13799 } 13800 reportValidity() { 13801 return _classPrivateFieldGet(this, _delegate).reportValidity(); 13802 } 13803 setCustomValidity(validationMessage) { 13804 _classPrivateFieldGet(this, _delegate).setCustomValidity(validationMessage); 13805 } 13806 formDisabledCallback(disabled) { 13807 const { 13808 inputElement 13809 } = this; 13810 if (inputElement) { 13811 inputElement.disabled = disabled; 13812 } 13813 this.toggleAttribute("contenteditable", !disabled); 13814 _classPrivateFieldGet(this, _delegate).formDisabledCallback(disabled); 13815 } 13816 formResetCallback() { 13817 this.reset(); 13818 } 13819 reset() { 13820 this.value = this.defaultValue; 13821 } 13822 } 13823 _defineProperty(TrixEditorElement, "formAssociated", "ElementInternals" in window); 13824 _defineProperty(TrixEditorElement, "observedAttributes", ["connected"]); 13825 13826 var elements = /*#__PURE__*/Object.freeze({ 13827 __proto__: null, 13828 TrixEditorElement: TrixEditorElement, 13829 TrixToolbarElement: TrixToolbarElement 13830 }); 13831 13832 var filters = /*#__PURE__*/Object.freeze({ 13833 __proto__: null, 13834 Filter: Filter, 13835 attachmentGalleryFilter: attachmentGalleryFilter 13836 }); 13837 13838 const Trix = { 13839 VERSION: version, 13840 config, 13841 core, 13842 models, 13843 views, 13844 controllers, 13845 observers, 13846 operations, 13847 elements, 13848 filters 13849 }; 13850 13851 // Expose models under the Trix constant for compatibility with v1 13852 Object.assign(Trix, models); 13853 function start() { 13854 if (!customElements.get("trix-toolbar")) { 13855 customElements.define("trix-toolbar", TrixToolbarElement); 13856 } 13857 if (!customElements.get("trix-editor")) { 13858 customElements.define("trix-editor", TrixEditorElement); 13859 } 13860 } 13861 window.Trix = Trix; 13862 setTimeout(start, 0); 13863 13864 return Trix; 13865 13866}));
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.