summaryrefslogtreecommitdiff
path: root/public/assets/trix-488ac88b50edee8aab73dd826e9967075eed9000a13fd13cbcc17745f86650cc.js
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-06-26 13:40:55 +0200
committererdgeist <erdgeist@erdgeist.org>2026-06-26 13:40:55 +0200
commit811bb04649365b0faaa00b1e0810bb101a4d19b1 (patch)
tree581d52faa6e1bf21a1cdfd4da7127a0f95786bad /public/assets/trix-488ac88b50edee8aab73dd826e9967075eed9000a13fd13cbcc17745f86650cc.js
parenta1ddc25da0d2aa79a4d9216ef7792f26233bd38e (diff)
Stage 5 click-testing fixes
- Fix link_to :method → button_to for all PUT/DELETE actions - Add button_to CSS reset to admin.css for visual consistency - Fix admin layout: replace broken jquery/jquery_ujs pipeline refs with admin_bundle via sprockets; add sprockets-rails, jquery-ui-rails gems - Add app/assets/javascripts/admin_bundle.js pipeline manifest - Fix event_information helper: use safe_join to avoid double-escaping - Fix nodes_helper: to_s(:db) → to_fs(:db) for event times - Fix revisions view: eliminate nested forms; diff button uses vanilla JS to collect radio button values before POST - Fix config/environments/development.rb and test.rb: cache_classes → enable_reloading - Add routing_filter_rails71_patch.rb version guard - Move LockedByAnotherUser to own file for Zeitwerk autoloading - Fix Globalize fallbacks via config.i18n.fallbacks in application.rb
Diffstat (limited to 'public/assets/trix-488ac88b50edee8aab73dd826e9967075eed9000a13fd13cbcc17745f86650cc.js')
-rw-r--r--public/assets/trix-488ac88b50edee8aab73dd826e9967075eed9000a13fd13cbcc17745f86650cc.js13720
1 files changed, 13720 insertions, 0 deletions
diff --git a/public/assets/trix-488ac88b50edee8aab73dd826e9967075eed9000a13fd13cbcc17745f86650cc.js b/public/assets/trix-488ac88b50edee8aab73dd826e9967075eed9000a13fd13cbcc17745f86650cc.js
new file mode 100644
index 00000000..1cd185f6
--- /dev/null
+++ b/public/assets/trix-488ac88b50edee8aab73dd826e9967075eed9000a13fd13cbcc17745f86650cc.js
@@ -0,0 +1,13720 @@
1/*
2Trix 2.1.10
3Copyright © 2024 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.10";
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 concurrently: "^7.4.0",
48 eslint: "^7.32.0",
49 esm: "^3.2.25",
50 karma: "6.4.1",
51 "karma-chrome-launcher": "3.2.0",
52 "karma-qunit": "^4.1.2",
53 "karma-sauce-launcher": "^4.3.6",
54 "node-sass": "^7.0.1",
55 qunit: "2.19.1",
56 rangy: "^1.3.0",
57 rollup: "^2.56.3",
58 "rollup-plugin-includepaths": "^0.2.4",
59 "rollup-plugin-terser": "^7.0.2",
60 svgo: "^2.8.0",
61 webdriverio: "^7.19.5"
62 };
63 var resolutions = {
64 webdriverio: "^7.19.5"
65 };
66 var scripts = {
67 "build-css": "node-sass --functions=./assets/trix/stylesheets/functions assets/trix.scss dist/trix.css",
68 "build-js": "rollup -c",
69 "build-assets": "cp -f assets/*.html dist/",
70 build: "yarn run build-js && yarn run build-css && yarn run build-assets",
71 watch: "rollup -c -w",
72 lint: "eslint .",
73 pretest: "yarn run lint && yarn run build",
74 test: "karma start",
75 prerelease: "yarn version && yarn test",
76 release: "npm adduser && npm publish",
77 postrelease: "git push && git push --tags",
78 dev: "web-dev-server --app-index index.html --root-dir dist --node-resolve --open",
79 start: "yarn build-assets && concurrently --kill-others --names js,css,dev-server 'yarn watch' 'yarn build-css --watch' 'yarn dev'"
80 };
81 var dependencies = {
82 dompurify: "^3.2.3"
83 };
84 var _package = {
85 name: name,
86 version: version,
87 description: description,
88 main: main,
89 module: module,
90 style: style,
91 files: files,
92 repository: repository,
93 keywords: keywords,
94 author: author,
95 license: license,
96 bugs: bugs,
97 homepage: homepage,
98 devDependencies: devDependencies,
99 resolutions: resolutions,
100 scripts: scripts,
101 dependencies: dependencies
102 };
103
104 const attachmentSelector = "[data-trix-attachment]";
105 const attachments = {
106 preview: {
107 presentation: "gallery",
108 caption: {
109 name: true,
110 size: true
111 }
112 },
113 file: {
114 caption: {
115 size: true
116 }
117 }
118 };
119
120 const attributes = {
121 default: {
122 tagName: "div",
123 parse: false
124 },
125 quote: {
126 tagName: "blockquote",
127 nestable: true
128 },
129 heading1: {
130 tagName: "h1",
131 terminal: true,
132 breakOnReturn: true,
133 group: false
134 },
135 code: {
136 tagName: "pre",
137 terminal: true,
138 htmlAttributes: ["language"],
139 text: {
140 plaintext: true
141 }
142 },
143 bulletList: {
144 tagName: "ul",
145 parse: false
146 },
147 bullet: {
148 tagName: "li",
149 listAttribute: "bulletList",
150 group: false,
151 nestable: true,
152 test(element) {
153 return tagName$1(element.parentNode) === attributes[this.listAttribute].tagName;
154 }
155 },
156 numberList: {
157 tagName: "ol",
158 parse: false
159 },
160 number: {
161 tagName: "li",
162 listAttribute: "numberList",
163 group: false,
164 nestable: true,
165 test(element) {
166 return tagName$1(element.parentNode) === attributes[this.listAttribute].tagName;
167 }
168 },
169 attachmentGallery: {
170 tagName: "div",
171 exclusive: true,
172 terminal: true,
173 parse: false,
174 group: false
175 }
176 };
177 const tagName$1 = element => {
178 var _element$tagName;
179 return element === null || element === void 0 || (_element$tagName = element.tagName) === null || _element$tagName === void 0 ? void 0 : _element$tagName.toLowerCase();
180 };
181
182 const androidVersionMatch = navigator.userAgent.match(/android\s([0-9]+.*Chrome)/i);
183 const androidVersion = androidVersionMatch && parseInt(androidVersionMatch[1]);
184 var browser$1 = {
185 // Android emits composition events when moving the cursor through existing text
186 // Introduced in Chrome 65: https://bugs.chromium.org/p/chromium/issues/detail?id=764439#c9
187 composesExistingText: /Android.*Chrome/.test(navigator.userAgent),
188 // Android 13, especially on Samsung keyboards, emits extra compositionend and beforeinput events
189 // that can make the input handler lose the current selection or enter an infinite input -> render -> input
190 // loop.
191 recentAndroid: androidVersion && androidVersion > 12,
192 samsungAndroid: androidVersion && navigator.userAgent.match(/Android.*SM-/),
193 // IE 11 activates resizing handles on editable elements that have "layout"
194 forcesObjectResizing: /Trident.*rv:11/.test(navigator.userAgent),
195 // https://www.w3.org/TR/input-events-1/ + https://www.w3.org/TR/input-events-2/
196 supportsInputEvents: typeof InputEvent !== "undefined" && ["data", "getTargetRanges", "inputType"].every(prop => prop in InputEvent.prototype)
197 };
198
199 var css$3 = {
200 attachment: "attachment",
201 attachmentCaption: "attachment__caption",
202 attachmentCaptionEditor: "attachment__caption-editor",
203 attachmentMetadata: "attachment__metadata",
204 attachmentMetadataContainer: "attachment__metadata-container",
205 attachmentName: "attachment__name",
206 attachmentProgress: "attachment__progress",
207 attachmentSize: "attachment__size",
208 attachmentToolbar: "attachment__toolbar",
209 attachmentGallery: "attachment-gallery"
210 };
211
212 var lang$1 = {
213 attachFiles: "Attach Files",
214 bold: "Bold",
215 bullets: "Bullets",
216 byte: "Byte",
217 bytes: "Bytes",
218 captionPlaceholder: "Add a caption…",
219 code: "Code",
220 heading1: "Heading",
221 indent: "Increase Level",
222 italic: "Italic",
223 link: "Link",
224 numbers: "Numbers",
225 outdent: "Decrease Level",
226 quote: "Quote",
227 redo: "Redo",
228 remove: "Remove",
229 strike: "Strikethrough",
230 undo: "Undo",
231 unlink: "Unlink",
232 url: "URL",
233 urlPlaceholder: "Enter a URL…",
234 GB: "GB",
235 KB: "KB",
236 MB: "MB",
237 PB: "PB",
238 TB: "TB"
239 };
240
241 /* eslint-disable
242 no-case-declarations,
243 */
244 const sizes = [lang$1.bytes, lang$1.KB, lang$1.MB, lang$1.GB, lang$1.TB, lang$1.PB];
245 var file_size_formatting = {
246 prefix: "IEC",
247 precision: 2,
248 formatter(number) {
249 switch (number) {
250 case 0:
251 return "0 ".concat(lang$1.bytes);
252 case 1:
253 return "1 ".concat(lang$1.byte);
254 default:
255 let base;
256 if (this.prefix === "SI") {
257 base = 1000;
258 } else if (this.prefix === "IEC") {
259 base = 1024;
260 }
261 const exp = Math.floor(Math.log(number) / Math.log(base));
262 const humanSize = number / Math.pow(base, exp);
263 const string = humanSize.toFixed(this.precision);
264 const withoutInsignificantZeros = string.replace(/0*$/, "").replace(/\.$/, "");
265 return "".concat(withoutInsignificantZeros, " ").concat(sizes[exp]);
266 }
267 }
268 };
269
270 const ZERO_WIDTH_SPACE = "\uFEFF";
271 const NON_BREAKING_SPACE = "\u00A0";
272 const OBJECT_REPLACEMENT_CHARACTER = "\uFFFC";
273
274 const extend = function (properties) {
275 for (const key in properties) {
276 const value = properties[key];
277 this[key] = value;
278 }
279 return this;
280 };
281
282 const html$2 = document.documentElement;
283 const match = html$2.matches;
284 const handleEvent = function (eventName) {
285 let {
286 onElement,
287 matchingSelector,
288 withCallback,
289 inPhase,
290 preventDefault,
291 times
292 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
293 const element = onElement ? onElement : html$2;
294 const selector = matchingSelector;
295 const useCapture = inPhase === "capturing";
296 const handler = function (event) {
297 if (times != null && --times === 0) {
298 handler.destroy();
299 }
300 const target = findClosestElementFromNode(event.target, {
301 matchingSelector: selector
302 });
303 if (target != null) {
304 withCallback === null || withCallback === void 0 || withCallback.call(target, event, target);
305 if (preventDefault) {
306 event.preventDefault();
307 }
308 }
309 };
310 handler.destroy = () => element.removeEventListener(eventName, handler, useCapture);
311 element.addEventListener(eventName, handler, useCapture);
312 return handler;
313 };
314 const handleEventOnce = function (eventName) {
315 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
316 options.times = 1;
317 return handleEvent(eventName, options);
318 };
319 const triggerEvent = function (eventName) {
320 let {
321 onElement,
322 bubbles,
323 cancelable,
324 attributes
325 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
326 const element = onElement != null ? onElement : html$2;
327 bubbles = bubbles !== false;
328 cancelable = cancelable !== false;
329 const event = document.createEvent("Events");
330 event.initEvent(eventName, bubbles, cancelable);
331 if (attributes != null) {
332 extend.call(event, attributes);
333 }
334 return element.dispatchEvent(event);
335 };
336 const elementMatchesSelector = function (element, selector) {
337 if ((element === null || element === void 0 ? void 0 : element.nodeType) === 1) {
338 return match.call(element, selector);
339 }
340 };
341 const findClosestElementFromNode = function (node) {
342 let {
343 matchingSelector,
344 untilNode
345 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
346 while (node && node.nodeType !== Node.ELEMENT_NODE) {
347 node = node.parentNode;
348 }
349 if (node == null) {
350 return;
351 }
352 if (matchingSelector != null) {
353 if (node.closest && untilNode == null) {
354 return node.closest(matchingSelector);
355 } else {
356 while (node && node !== untilNode) {
357 if (elementMatchesSelector(node, matchingSelector)) {
358 return node;
359 }
360 node = node.parentNode;
361 }
362 }
363 } else {
364 return node;
365 }
366 };
367 const findInnerElement = function (element) {
368 while ((_element = element) !== null && _element !== void 0 && _element.firstElementChild) {
369 var _element;
370 element = element.firstElementChild;
371 }
372 return element;
373 };
374 const innerElementIsActive = element => document.activeElement !== element && elementContainsNode(element, document.activeElement);
375 const elementContainsNode = function (element, node) {
376 if (!element || !node) {
377 return;
378 }
379 while (node) {
380 if (node === element) {
381 return true;
382 }
383 node = node.parentNode;
384 }
385 };
386 const findNodeFromContainerAndOffset = function (container, offset) {
387 if (!container) {
388 return;
389 }
390 if (container.nodeType === Node.TEXT_NODE) {
391 return container;
392 } else if (offset === 0) {
393 return container.firstChild != null ? container.firstChild : container;
394 } else {
395 return container.childNodes.item(offset - 1);
396 }
397 };
398 const findElementFromContainerAndOffset = function (container, offset) {
399 const node = findNodeFromContainerAndOffset(container, offset);
400 return findClosestElementFromNode(node);
401 };
402 const findChildIndexOfNode = function (node) {
403 var _node;
404 if (!((_node = node) !== null && _node !== void 0 && _node.parentNode)) {
405 return;
406 }
407 let childIndex = 0;
408 node = node.previousSibling;
409 while (node) {
410 childIndex++;
411 node = node.previousSibling;
412 }
413 return childIndex;
414 };
415 const removeNode = node => {
416 var _node$parentNode;
417 return node === null || node === void 0 || (_node$parentNode = node.parentNode) === null || _node$parentNode === void 0 ? void 0 : _node$parentNode.removeChild(node);
418 };
419 const walkTree = function (tree) {
420 let {
421 onlyNodesOfType,
422 usingFilter,
423 expandEntityReferences
424 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
425 const whatToShow = (() => {
426 switch (onlyNodesOfType) {
427 case "element":
428 return NodeFilter.SHOW_ELEMENT;
429 case "text":
430 return NodeFilter.SHOW_TEXT;
431 case "comment":
432 return NodeFilter.SHOW_COMMENT;
433 default:
434 return NodeFilter.SHOW_ALL;
435 }
436 })();
437 return document.createTreeWalker(tree, whatToShow, usingFilter != null ? usingFilter : null, expandEntityReferences === true);
438 };
439 const tagName = element => {
440 var _element$tagName;
441 return element === null || element === void 0 || (_element$tagName = element.tagName) === null || _element$tagName === void 0 ? void 0 : _element$tagName.toLowerCase();
442 };
443 const makeElement = function (tag) {
444 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
445 let key, value;
446 if (typeof tag === "object") {
447 options = tag;
448 tag = options.tagName;
449 } else {
450 options = {
451 attributes: options
452 };
453 }
454 const element = document.createElement(tag);
455 if (options.editable != null) {
456 if (options.attributes == null) {
457 options.attributes = {};
458 }
459 options.attributes.contenteditable = options.editable;
460 }
461 if (options.attributes) {
462 for (key in options.attributes) {
463 value = options.attributes[key];
464 element.setAttribute(key, value);
465 }
466 }
467 if (options.style) {
468 for (key in options.style) {
469 value = options.style[key];
470 element.style[key] = value;
471 }
472 }
473 if (options.data) {
474 for (key in options.data) {
475 value = options.data[key];
476 element.dataset[key] = value;
477 }
478 }
479 if (options.className) {
480 options.className.split(" ").forEach(className => {
481 element.classList.add(className);
482 });
483 }
484 if (options.textContent) {
485 element.textContent = options.textContent;
486 }
487 if (options.childNodes) {
488 [].concat(options.childNodes).forEach(childNode => {
489 element.appendChild(childNode);
490 });
491 }
492 return element;
493 };
494 let blockTagNames = undefined;
495 const getBlockTagNames = function () {
496 if (blockTagNames != null) {
497 return blockTagNames;
498 }
499 blockTagNames = [];
500 for (const key in attributes) {
501 const attributes$1 = attributes[key];
502 if (attributes$1.tagName) {
503 blockTagNames.push(attributes$1.tagName);
504 }
505 }
506 return blockTagNames;
507 };
508 const nodeIsBlockContainer = node => nodeIsBlockStartComment(node === null || node === void 0 ? void 0 : node.firstChild);
509 const nodeProbablyIsBlockContainer = function (node) {
510 return getBlockTagNames().includes(tagName(node)) && !getBlockTagNames().includes(tagName(node.firstChild));
511 };
512 const nodeIsBlockStart = function (node) {
513 let {
514 strict
515 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
516 strict: true
517 };
518 if (strict) {
519 return nodeIsBlockStartComment(node);
520 } else {
521 return nodeIsBlockStartComment(node) || !nodeIsBlockStartComment(node.firstChild) && nodeProbablyIsBlockContainer(node);
522 }
523 };
524 const nodeIsBlockStartComment = node => nodeIsCommentNode(node) && (node === null || node === void 0 ? void 0 : node.data) === "block";
525 const nodeIsCommentNode = node => (node === null || node === void 0 ? void 0 : node.nodeType) === Node.COMMENT_NODE;
526 const nodeIsCursorTarget = function (node) {
527 let {
528 name
529 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
530 if (!node) {
531 return;
532 }
533 if (nodeIsTextNode(node)) {
534 if (node.data === ZERO_WIDTH_SPACE) {
535 if (name) {
536 return node.parentNode.dataset.trixCursorTarget === name;
537 } else {
538 return true;
539 }
540 }
541 } else {
542 return nodeIsCursorTarget(node.firstChild);
543 }
544 };
545 const nodeIsAttachmentElement = node => elementMatchesSelector(node, attachmentSelector);
546 const nodeIsEmptyTextNode = node => nodeIsTextNode(node) && (node === null || node === void 0 ? void 0 : node.data) === "";
547 const nodeIsTextNode = node => (node === null || node === void 0 ? void 0 : node.nodeType) === Node.TEXT_NODE;
548
549 const input = {
550 level2Enabled: true,
551 getLevel() {
552 if (this.level2Enabled && browser$1.supportsInputEvents) {
553 return 2;
554 } else {
555 return 0;
556 }
557 },
558 pickFiles(callback) {
559 const input = makeElement("input", {
560 type: "file",
561 multiple: true,
562 hidden: true,
563 id: this.fileInputId
564 });
565 input.addEventListener("change", () => {
566 callback(input.files);
567 removeNode(input);
568 });
569 removeNode(document.getElementById(this.fileInputId));
570 document.body.appendChild(input);
571 input.click();
572 }
573 };
574
575 var key_names = {
576 8: "backspace",
577 9: "tab",
578 13: "return",
579 27: "escape",
580 37: "left",
581 39: "right",
582 46: "delete",
583 68: "d",
584 72: "h",
585 79: "o"
586 };
587
588 var parser = {
589 removeBlankTableCells: false,
590 tableCellSeparator: " | ",
591 tableRowSeparator: "\n"
592 };
593
594 var text_attributes = {
595 bold: {
596 tagName: "strong",
597 inheritable: true,
598 parser(element) {
599 const style = window.getComputedStyle(element);
600 return style.fontWeight === "bold" || style.fontWeight >= 600;
601 }
602 },
603 italic: {
604 tagName: "em",
605 inheritable: true,
606 parser(element) {
607 const style = window.getComputedStyle(element);
608 return style.fontStyle === "italic";
609 }
610 },
611 href: {
612 groupTagName: "a",
613 parser(element) {
614 const matchingSelector = "a:not(".concat(attachmentSelector, ")");
615 const link = element.closest(matchingSelector);
616 if (link) {
617 return link.getAttribute("href");
618 }
619 }
620 },
621 strike: {
622 tagName: "del",
623 inheritable: true
624 },
625 frozen: {
626 style: {
627 backgroundColor: "highlight"
628 }
629 }
630 };
631
632 var toolbar = {
633 getDefaultHTML() {
634 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, "\" 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>");
635 }
636 };
637
638 const undo = {
639 interval: 5000
640 };
641
642 var config = /*#__PURE__*/Object.freeze({
643 __proto__: null,
644 attachments: attachments,
645 blockAttributes: attributes,
646 browser: browser$1,
647 css: css$3,
648 fileSize: file_size_formatting,
649 input: input,
650 keyNames: key_names,
651 lang: lang$1,
652 parser: parser,
653 textAttributes: text_attributes,
654 toolbar: toolbar,
655 undo: undo
656 });
657
658 class BasicObject {
659 static proxyMethod(expression) {
660 const {
661 name,
662 toMethod,
663 toProperty,
664 optional
665 } = parseProxyMethodExpression(expression);
666 this.prototype[name] = function () {
667 let subject;
668 let object;
669 if (toMethod) {
670 if (optional) {
671 var _this$toMethod;
672 object = (_this$toMethod = this[toMethod]) === null || _this$toMethod === void 0 ? void 0 : _this$toMethod.call(this);
673 } else {
674 object = this[toMethod]();
675 }
676 } else if (toProperty) {
677 object = this[toProperty];
678 }
679 if (optional) {
680 var _object;
681 subject = (_object = object) === null || _object === void 0 ? void 0 : _object[name];
682 if (subject) {
683 return apply$1.call(subject, object, arguments);
684 }
685 } else {
686 subject = object[name];
687 return apply$1.call(subject, object, arguments);
688 }
689 };
690 }
691 }
692 const parseProxyMethodExpression = function (expression) {
693 const match = expression.match(proxyMethodExpressionPattern);
694 if (!match) {
695 throw new Error("can't parse @proxyMethod expression: ".concat(expression));
696 }
697 const args = {
698 name: match[4]
699 };
700 if (match[2] != null) {
701 args.toMethod = match[1];
702 } else {
703 args.toProperty = match[1];
704 }
705 if (match[3] != null) {
706 args.optional = true;
707 }
708 return args;
709 };
710 const {
711 apply: apply$1
712 } = Function.prototype;
713 const proxyMethodExpressionPattern = new RegExp("\
714^\
715(.+?)\
716(\\(\\))?\
717(\\?)?\
718\\.\
719(.+?)\
720$\
721");
722
723 var _Array$from, _$codePointAt$1, _$1, _String$fromCodePoint;
724 class UTF16String extends BasicObject {
725 static box() {
726 let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
727 if (value instanceof this) {
728 return value;
729 } else {
730 return this.fromUCS2String(value === null || value === void 0 ? void 0 : value.toString());
731 }
732 }
733 static fromUCS2String(ucs2String) {
734 return new this(ucs2String, ucs2decode(ucs2String));
735 }
736 static fromCodepoints(codepoints) {
737 return new this(ucs2encode(codepoints), codepoints);
738 }
739 constructor(ucs2String, codepoints) {
740 super(...arguments);
741 this.ucs2String = ucs2String;
742 this.codepoints = codepoints;
743 this.length = this.codepoints.length;
744 this.ucs2Length = this.ucs2String.length;
745 }
746 offsetToUCS2Offset(offset) {
747 return ucs2encode(this.codepoints.slice(0, Math.max(0, offset))).length;
748 }
749 offsetFromUCS2Offset(ucs2Offset) {
750 return ucs2decode(this.ucs2String.slice(0, Math.max(0, ucs2Offset))).length;
751 }
752 slice() {
753 return this.constructor.fromCodepoints(this.codepoints.slice(...arguments));
754 }
755 charAt(offset) {
756 return this.slice(offset, offset + 1);
757 }
758 isEqualTo(value) {
759 return this.constructor.box(value).ucs2String === this.ucs2String;
760 }
761 toJSON() {
762 return this.ucs2String;
763 }
764 getCacheKey() {
765 return this.ucs2String;
766 }
767 toString() {
768 return this.ucs2String;
769 }
770 }
771 const hasArrayFrom = ((_Array$from = Array.from) === null || _Array$from === void 0 ? void 0 : _Array$from.call(Array, "\ud83d\udc7c").length) === 1;
772 const hasStringCodePointAt$1 = ((_$codePointAt$1 = (_$1 = " ").codePointAt) === null || _$codePointAt$1 === void 0 ? void 0 : _$codePointAt$1.call(_$1, 0)) != null;
773 const hasStringFromCodePoint = ((_String$fromCodePoint = String.fromCodePoint) === null || _String$fromCodePoint === void 0 ? void 0 : _String$fromCodePoint.call(String, 32, 128124)) === " \ud83d\udc7c";
774
775 // UCS-2 conversion helpers ported from Mathias Bynens' Punycode.js:
776 // https://github.com/bestiejs/punycode.js#punycodeucs2
777
778 let ucs2decode, ucs2encode;
779
780 // Creates an array containing the numeric code points of each Unicode
781 // character in the string. While JavaScript uses UCS-2 internally,
782 // this function will convert a pair of surrogate halves (each of which
783 // UCS-2 exposes as separate characters) into a single code point,
784 // matching UTF-16.
785 if (hasArrayFrom && hasStringCodePointAt$1) {
786 ucs2decode = string => Array.from(string).map(char => char.codePointAt(0));
787 } else {
788 ucs2decode = function (string) {
789 const output = [];
790 let counter = 0;
791 const {
792 length
793 } = string;
794 while (counter < length) {
795 let value = string.charCodeAt(counter++);
796 if (0xd800 <= value && value <= 0xdbff && counter < length) {
797 // high surrogate, and there is a next character
798 const extra = string.charCodeAt(counter++);
799 if ((extra & 0xfc00) === 0xdc00) {
800 // low surrogate
801 value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
802 } else {
803 // unmatched surrogate; only append this code unit, in case the
804 // next code unit is the high surrogate of a surrogate pair
805 counter--;
806 }
807 }
808 output.push(value);
809 }
810 return output;
811 };
812 }
813
814 // Creates a string based on an array of numeric code points.
815 if (hasStringFromCodePoint) {
816 ucs2encode = array => String.fromCodePoint(...Array.from(array || []));
817 } else {
818 ucs2encode = function (array) {
819 const characters = (() => {
820 const result = [];
821 Array.from(array).forEach(value => {
822 let output = "";
823 if (value > 0xffff) {
824 value -= 0x10000;
825 output += String.fromCharCode(value >>> 10 & 0x3ff | 0xd800);
826 value = 0xdc00 | value & 0x3ff;
827 }
828 result.push(output + String.fromCharCode(value));
829 });
830 return result;
831 })();
832 return characters.join("");
833 };
834 }
835
836 let id$2 = 0;
837 class TrixObject extends BasicObject {
838 static fromJSONString(jsonString) {
839 return this.fromJSON(JSON.parse(jsonString));
840 }
841 constructor() {
842 super(...arguments);
843 this.id = ++id$2;
844 }
845 hasSameConstructorAs(object) {
846 return this.constructor === (object === null || object === void 0 ? void 0 : object.constructor);
847 }
848 isEqualTo(object) {
849 return this === object;
850 }
851 inspect() {
852 const parts = [];
853 const contents = this.contentsForInspection() || {};
854 for (const key in contents) {
855 const value = contents[key];
856 parts.push("".concat(key, "=").concat(value));
857 }
858 return "#<".concat(this.constructor.name, ":").concat(this.id).concat(parts.length ? " ".concat(parts.join(", ")) : "", ">");
859 }
860 contentsForInspection() {}
861 toJSONString() {
862 return JSON.stringify(this);
863 }
864 toUTF16String() {
865 return UTF16String.box(this);
866 }
867 getCacheKey() {
868 return this.id.toString();
869 }
870 }
871
872 /* eslint-disable
873 id-length,
874 */
875 const arraysAreEqual = function () {
876 let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
877 let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
878 if (a.length !== b.length) {
879 return false;
880 }
881 for (let index = 0; index < a.length; index++) {
882 const value = a[index];
883 if (value !== b[index]) {
884 return false;
885 }
886 }
887 return true;
888 };
889 const arrayStartsWith = function () {
890 let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
891 let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
892 return arraysAreEqual(a.slice(0, b.length), b);
893 };
894 const spliceArray = function (array) {
895 const result = array.slice(0);
896 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
897 args[_key - 1] = arguments[_key];
898 }
899 result.splice(...args);
900 return result;
901 };
902 const summarizeArrayChange = function () {
903 let oldArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
904 let newArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
905 const added = [];
906 const removed = [];
907 const existingValues = new Set();
908 oldArray.forEach(value => {
909 existingValues.add(value);
910 });
911 const currentValues = new Set();
912 newArray.forEach(value => {
913 currentValues.add(value);
914 if (!existingValues.has(value)) {
915 added.push(value);
916 }
917 });
918 oldArray.forEach(value => {
919 if (!currentValues.has(value)) {
920 removed.push(value);
921 }
922 });
923 return {
924 added,
925 removed
926 };
927 };
928
929 // https://github.com/mathiasbynens/unicode-2.1.8/blob/master/Bidi_Class/Right_To_Left/regex.js
930 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]/;
931 const getDirection = function () {
932 const input = makeElement("input", {
933 dir: "auto",
934 name: "x",
935 dirName: "x.dir"
936 });
937 const textArea = makeElement("textarea", {
938 dir: "auto",
939 name: "y",
940 dirName: "y.dir"
941 });
942 const form = makeElement("form");
943 form.appendChild(input);
944 form.appendChild(textArea);
945 const supportsDirName = function () {
946 try {
947 return new FormData(form).has(textArea.dirName);
948 } catch (error) {
949 return false;
950 }
951 }();
952 const supportsDirSelector = function () {
953 try {
954 return input.matches(":dir(ltr),:dir(rtl)");
955 } catch (error) {
956 return false;
957 }
958 }();
959 if (supportsDirName) {
960 return function (string) {
961 textArea.value = string;
962 return new FormData(form).get(textArea.dirName);
963 };
964 } else if (supportsDirSelector) {
965 return function (string) {
966 input.value = string;
967 if (input.matches(":dir(rtl)")) {
968 return "rtl";
969 } else {
970 return "ltr";
971 }
972 };
973 } else {
974 return function (string) {
975 const char = string.trim().charAt(0);
976 if (RTL_PATTERN.test(char)) {
977 return "rtl";
978 } else {
979 return "ltr";
980 }
981 };
982 }
983 }();
984
985 let allAttributeNames = null;
986 let blockAttributeNames = null;
987 let textAttributeNames = null;
988 let listAttributeNames = null;
989 const getAllAttributeNames = () => {
990 if (!allAttributeNames) {
991 allAttributeNames = getTextAttributeNames().concat(getBlockAttributeNames());
992 }
993 return allAttributeNames;
994 };
995 const getBlockConfig = attributeName => attributes[attributeName];
996 const getBlockAttributeNames = () => {
997 if (!blockAttributeNames) {
998 blockAttributeNames = Object.keys(attributes);
999 }
1000 return blockAttributeNames;
1001 };
1002 const getTextConfig = attributeName => text_attributes[attributeName];
1003 const getTextAttributeNames = () => {
1004 if (!textAttributeNames) {
1005 textAttributeNames = Object.keys(text_attributes);
1006 }
1007 return textAttributeNames;
1008 };
1009 const getListAttributeNames = () => {
1010 if (!listAttributeNames) {
1011 listAttributeNames = [];
1012 for (const key in attributes) {
1013 const {
1014 listAttribute
1015 } = attributes[key];
1016 if (listAttribute != null) {
1017 listAttributeNames.push(listAttribute);
1018 }
1019 }
1020 }
1021 return listAttributeNames;
1022 };
1023
1024 /* eslint-disable
1025 */
1026 const installDefaultCSSForTagName = function (tagName, defaultCSS) {
1027 const styleElement = insertStyleElementForTagName(tagName);
1028 styleElement.textContent = defaultCSS.replace(/%t/g, tagName);
1029 };
1030 const insertStyleElementForTagName = function (tagName) {
1031 const element = document.createElement("style");
1032 element.setAttribute("type", "text/css");
1033 element.setAttribute("data-tag-name", tagName.toLowerCase());
1034 const nonce = getCSPNonce();
1035 if (nonce) {
1036 element.setAttribute("nonce", nonce);
1037 }
1038 document.head.insertBefore(element, document.head.firstChild);
1039 return element;
1040 };
1041 const getCSPNonce = function () {
1042 const element = getMetaElement("trix-csp-nonce") || getMetaElement("csp-nonce");
1043 if (element) {
1044 const {
1045 nonce,
1046 content
1047 } = element;
1048 return nonce == "" ? content : nonce;
1049 }
1050 };
1051 const getMetaElement = name => document.head.querySelector("meta[name=".concat(name, "]"));
1052
1053 const testTransferData = {
1054 "application/x-trix-feature-detection": "test"
1055 };
1056 const dataTransferIsPlainText = function (dataTransfer) {
1057 const text = dataTransfer.getData("text/plain");
1058 const html = dataTransfer.getData("text/html");
1059 if (text && html) {
1060 const {
1061 body
1062 } = new DOMParser().parseFromString(html, "text/html");
1063 if (body.textContent === text) {
1064 return !body.querySelector("*");
1065 }
1066 } else {
1067 return text === null || text === void 0 ? void 0 : text.length;
1068 }
1069 };
1070 const dataTransferIsMsOfficePaste = _ref => {
1071 let {
1072 dataTransfer
1073 } = _ref;
1074 return dataTransfer.types.includes("Files") && dataTransfer.types.includes("text/html") && dataTransfer.getData("text/html").includes("urn:schemas-microsoft-com:office:office");
1075 };
1076 const dataTransferIsWritable = function (dataTransfer) {
1077 if (!(dataTransfer !== null && dataTransfer !== void 0 && dataTransfer.setData)) return false;
1078 for (const key in testTransferData) {
1079 const value = testTransferData[key];
1080 try {
1081 dataTransfer.setData(key, value);
1082 if (!dataTransfer.getData(key) === value) return false;
1083 } catch (error) {
1084 return false;
1085 }
1086 }
1087 return true;
1088 };
1089 const keyEventIsKeyboardCommand = function () {
1090 if (/Mac|^iP/.test(navigator.platform)) {
1091 return event => event.metaKey;
1092 } else {
1093 return event => event.ctrlKey;
1094 }
1095 }();
1096 function shouldRenderInmmediatelyToDealWithIOSDictation(inputEvent) {
1097 if (/iPhone|iPad/.test(navigator.userAgent)) {
1098 // Handle garbled content and duplicated newlines when using dictation on iOS 18+. Upon dictation completion, iOS sends
1099 // the list of insertText / insertParagraph events in a quick sequence. If we don't render
1100 // the editor synchronously, the internal range fails to update and results in garbled content or duplicated newlines.
1101 //
1102 // This workaround is necessary because iOS doesn't send composing events as expected while dictating:
1103 // https://bugs.webkit.org/show_bug.cgi?id=261764
1104 return !inputEvent.inputType || inputEvent.inputType === "insertParagraph";
1105 } else {
1106 return false;
1107 }
1108 }
1109
1110 const defer = fn => setTimeout(fn, 1);
1111
1112 /* eslint-disable
1113 id-length,
1114 */
1115 const copyObject = function () {
1116 let object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1117 const result = {};
1118 for (const key in object) {
1119 const value = object[key];
1120 result[key] = value;
1121 }
1122 return result;
1123 };
1124 const objectsAreEqual = function () {
1125 let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1126 let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1127 if (Object.keys(a).length !== Object.keys(b).length) {
1128 return false;
1129 }
1130 for (const key in a) {
1131 const value = a[key];
1132 if (value !== b[key]) {
1133 return false;
1134 }
1135 }
1136 return true;
1137 };
1138
1139 const normalizeRange = function (range) {
1140 if (range == null) return;
1141 if (!Array.isArray(range)) {
1142 range = [range, range];
1143 }
1144 return [copyValue(range[0]), copyValue(range[1] != null ? range[1] : range[0])];
1145 };
1146 const rangeIsCollapsed = function (range) {
1147 if (range == null) return;
1148 const [start, end] = normalizeRange(range);
1149 return rangeValuesAreEqual(start, end);
1150 };
1151 const rangesAreEqual = function (leftRange, rightRange) {
1152 if (leftRange == null || rightRange == null) return;
1153 const [leftStart, leftEnd] = normalizeRange(leftRange);
1154 const [rightStart, rightEnd] = normalizeRange(rightRange);
1155 return rangeValuesAreEqual(leftStart, rightStart) && rangeValuesAreEqual(leftEnd, rightEnd);
1156 };
1157 const copyValue = function (value) {
1158 if (typeof value === "number") {
1159 return value;
1160 } else {
1161 return copyObject(value);
1162 }
1163 };
1164 const rangeValuesAreEqual = function (left, right) {
1165 if (typeof left === "number") {
1166 return left === right;
1167 } else {
1168 return objectsAreEqual(left, right);
1169 }
1170 };
1171
1172 class SelectionChangeObserver extends BasicObject {
1173 constructor() {
1174 super(...arguments);
1175 this.update = this.update.bind(this);
1176 this.selectionManagers = [];
1177 }
1178 start() {
1179 if (!this.started) {
1180 this.started = true;
1181 document.addEventListener("selectionchange", this.update, true);
1182 }
1183 }
1184 stop() {
1185 if (this.started) {
1186 this.started = false;
1187 return document.removeEventListener("selectionchange", this.update, true);
1188 }
1189 }
1190 registerSelectionManager(selectionManager) {
1191 if (!this.selectionManagers.includes(selectionManager)) {
1192 this.selectionManagers.push(selectionManager);
1193 return this.start();
1194 }
1195 }
1196 unregisterSelectionManager(selectionManager) {
1197 this.selectionManagers = this.selectionManagers.filter(sm => sm !== selectionManager);
1198 if (this.selectionManagers.length === 0) {
1199 return this.stop();
1200 }
1201 }
1202 notifySelectionManagersOfSelectionChange() {
1203 return this.selectionManagers.map(selectionManager => selectionManager.selectionDidChange());
1204 }
1205 update() {
1206 this.notifySelectionManagersOfSelectionChange();
1207 }
1208 reset() {
1209 this.update();
1210 }
1211 }
1212 const selectionChangeObserver = new SelectionChangeObserver();
1213 const getDOMSelection = function () {
1214 const selection = window.getSelection();
1215 if (selection.rangeCount > 0) {
1216 return selection;
1217 }
1218 };
1219 const getDOMRange = function () {
1220 var _getDOMSelection;
1221 const domRange = (_getDOMSelection = getDOMSelection()) === null || _getDOMSelection === void 0 ? void 0 : _getDOMSelection.getRangeAt(0);
1222 if (domRange) {
1223 if (!domRangeIsPrivate(domRange)) {
1224 return domRange;
1225 }
1226 }
1227 };
1228 const setDOMRange = function (domRange) {
1229 const selection = window.getSelection();
1230 selection.removeAllRanges();
1231 selection.addRange(domRange);
1232 return selectionChangeObserver.update();
1233 };
1234
1235 // In Firefox, clicking certain <input> elements changes the selection to a
1236 // private element used to draw its UI. Attempting to access properties of those
1237 // elements throws an error.
1238 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
1239 const domRangeIsPrivate = domRange => nodeIsPrivate(domRange.startContainer) || nodeIsPrivate(domRange.endContainer);
1240 const nodeIsPrivate = node => !Object.getPrototypeOf(node);
1241
1242 /* eslint-disable
1243 id-length,
1244 no-useless-escape,
1245 */
1246 const normalizeSpaces = string => string.replace(new RegExp("".concat(ZERO_WIDTH_SPACE), "g"), "").replace(new RegExp("".concat(NON_BREAKING_SPACE), "g"), " ");
1247 const normalizeNewlines = string => string.replace(/\r\n?/g, "\n");
1248 const breakableWhitespacePattern = new RegExp("[^\\S".concat(NON_BREAKING_SPACE, "]"));
1249 const squishBreakableWhitespace = string => string
1250 // Replace all breakable whitespace characters with a space
1251 .replace(new RegExp("".concat(breakableWhitespacePattern.source), "g"), " ")
1252 // Replace two or more spaces with a single space
1253 .replace(/\ {2,}/g, " ");
1254 const summarizeStringChange = function (oldString, newString) {
1255 let added, removed;
1256 oldString = UTF16String.box(oldString);
1257 newString = UTF16String.box(newString);
1258 if (newString.length < oldString.length) {
1259 [removed, added] = utf16StringDifferences(oldString, newString);
1260 } else {
1261 [added, removed] = utf16StringDifferences(newString, oldString);
1262 }
1263 return {
1264 added,
1265 removed
1266 };
1267 };
1268 const utf16StringDifferences = function (a, b) {
1269 if (a.isEqualTo(b)) {
1270 return ["", ""];
1271 }
1272 const diffA = utf16StringDifference(a, b);
1273 const {
1274 length
1275 } = diffA.utf16String;
1276 let diffB;
1277 if (length) {
1278 const {
1279 offset
1280 } = diffA;
1281 const codepoints = a.codepoints.slice(0, offset).concat(a.codepoints.slice(offset + length));
1282 diffB = utf16StringDifference(b, UTF16String.fromCodepoints(codepoints));
1283 } else {
1284 diffB = utf16StringDifference(b, a);
1285 }
1286 return [diffA.utf16String.toString(), diffB.utf16String.toString()];
1287 };
1288 const utf16StringDifference = function (a, b) {
1289 let leftIndex = 0;
1290 let rightIndexA = a.length;
1291 let rightIndexB = b.length;
1292 while (leftIndex < rightIndexA && a.charAt(leftIndex).isEqualTo(b.charAt(leftIndex))) {
1293 leftIndex++;
1294 }
1295 while (rightIndexA > leftIndex + 1 && a.charAt(rightIndexA - 1).isEqualTo(b.charAt(rightIndexB - 1))) {
1296 rightIndexA--;
1297 rightIndexB--;
1298 }
1299 return {
1300 utf16String: a.slice(leftIndex, rightIndexA),
1301 offset: leftIndex
1302 };
1303 };
1304
1305 class Hash extends TrixObject {
1306 static fromCommonAttributesOfObjects() {
1307 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1308 if (!objects.length) {
1309 return new this();
1310 }
1311 let hash = box(objects[0]);
1312 let keys = hash.getKeys();
1313 objects.slice(1).forEach(object => {
1314 keys = hash.getKeysCommonToHash(box(object));
1315 hash = hash.slice(keys);
1316 });
1317 return hash;
1318 }
1319 static box(values) {
1320 return box(values);
1321 }
1322 constructor() {
1323 let values = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1324 super(...arguments);
1325 this.values = copy(values);
1326 }
1327 add(key, value) {
1328 return this.merge(object(key, value));
1329 }
1330 remove(key) {
1331 return new Hash(copy(this.values, key));
1332 }
1333 get(key) {
1334 return this.values[key];
1335 }
1336 has(key) {
1337 return key in this.values;
1338 }
1339 merge(values) {
1340 return new Hash(merge(this.values, unbox(values)));
1341 }
1342 slice(keys) {
1343 const values = {};
1344 Array.from(keys).forEach(key => {
1345 if (this.has(key)) {
1346 values[key] = this.values[key];
1347 }
1348 });
1349 return new Hash(values);
1350 }
1351 getKeys() {
1352 return Object.keys(this.values);
1353 }
1354 getKeysCommonToHash(hash) {
1355 hash = box(hash);
1356 return this.getKeys().filter(key => this.values[key] === hash.values[key]);
1357 }
1358 isEqualTo(values) {
1359 return arraysAreEqual(this.toArray(), box(values).toArray());
1360 }
1361 isEmpty() {
1362 return this.getKeys().length === 0;
1363 }
1364 toArray() {
1365 if (!this.array) {
1366 const result = [];
1367 for (const key in this.values) {
1368 const value = this.values[key];
1369 result.push(result.push(key, value));
1370 }
1371 this.array = result.slice(0);
1372 }
1373 return this.array;
1374 }
1375 toObject() {
1376 return copy(this.values);
1377 }
1378 toJSON() {
1379 return this.toObject();
1380 }
1381 contentsForInspection() {
1382 return {
1383 values: JSON.stringify(this.values)
1384 };
1385 }
1386 }
1387 const object = function (key, value) {
1388 const result = {};
1389 result[key] = value;
1390 return result;
1391 };
1392 const merge = function (object, values) {
1393 const result = copy(object);
1394 for (const key in values) {
1395 const value = values[key];
1396 result[key] = value;
1397 }
1398 return result;
1399 };
1400 const copy = function (object, keyToRemove) {
1401 const result = {};
1402 const sortedKeys = Object.keys(object).sort();
1403 sortedKeys.forEach(key => {
1404 if (key !== keyToRemove) {
1405 result[key] = object[key];
1406 }
1407 });
1408 return result;
1409 };
1410 const box = function (object) {
1411 if (object instanceof Hash) {
1412 return object;
1413 } else {
1414 return new Hash(object);
1415 }
1416 };
1417 const unbox = function (object) {
1418 if (object instanceof Hash) {
1419 return object.values;
1420 } else {
1421 return object;
1422 }
1423 };
1424
1425 class ObjectGroup {
1426 static groupObjects() {
1427 let ungroupedObjects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1428 let {
1429 depth,
1430 asTree
1431 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1432 let group;
1433 if (asTree) {
1434 if (depth == null) {
1435 depth = 0;
1436 }
1437 }
1438 const objects = [];
1439 Array.from(ungroupedObjects).forEach(object => {
1440 var _object$canBeGrouped2;
1441 if (group) {
1442 var _object$canBeGrouped, _group$canBeGroupedWi, _group;
1443 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)) {
1444 group.push(object);
1445 return;
1446 } else {
1447 objects.push(new this(group, {
1448 depth,
1449 asTree
1450 }));
1451 group = null;
1452 }
1453 }
1454 if ((_object$canBeGrouped2 = object.canBeGrouped) !== null && _object$canBeGrouped2 !== void 0 && _object$canBeGrouped2.call(object, depth)) {
1455 group = [object];
1456 } else {
1457 objects.push(object);
1458 }
1459 });
1460 if (group) {
1461 objects.push(new this(group, {
1462 depth,
1463 asTree
1464 }));
1465 }
1466 return objects;
1467 }
1468 constructor() {
1469 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1470 let {
1471 depth,
1472 asTree
1473 } = arguments.length > 1 ? arguments[1] : undefined;
1474 this.objects = objects;
1475 if (asTree) {
1476 this.depth = depth;
1477 this.objects = this.constructor.groupObjects(this.objects, {
1478 asTree,
1479 depth: this.depth + 1
1480 });
1481 }
1482 }
1483 getObjects() {
1484 return this.objects;
1485 }
1486 getDepth() {
1487 return this.depth;
1488 }
1489 getCacheKey() {
1490 const keys = ["objectGroup"];
1491 Array.from(this.getObjects()).forEach(object => {
1492 keys.push(object.getCacheKey());
1493 });
1494 return keys.join("/");
1495 }
1496 }
1497
1498 class ObjectMap extends BasicObject {
1499 constructor() {
1500 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1501 super(...arguments);
1502 this.objects = {};
1503 Array.from(objects).forEach(object => {
1504 const hash = JSON.stringify(object);
1505 if (this.objects[hash] == null) {
1506 this.objects[hash] = object;
1507 }
1508 });
1509 }
1510 find(object) {
1511 const hash = JSON.stringify(object);
1512 return this.objects[hash];
1513 }
1514 }
1515
1516 class ElementStore {
1517 constructor(elements) {
1518 this.reset(elements);
1519 }
1520 add(element) {
1521 const key = getKey(element);
1522 this.elements[key] = element;
1523 }
1524 remove(element) {
1525 const key = getKey(element);
1526 const value = this.elements[key];
1527 if (value) {
1528 delete this.elements[key];
1529 return value;
1530 }
1531 }
1532 reset() {
1533 let elements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1534 this.elements = {};
1535 Array.from(elements).forEach(element => {
1536 this.add(element);
1537 });
1538 return elements;
1539 }
1540 }
1541 const getKey = element => element.dataset.trixStoreKey;
1542
1543 class Operation extends BasicObject {
1544 isPerforming() {
1545 return this.performing === true;
1546 }
1547 hasPerformed() {
1548 return this.performed === true;
1549 }
1550 hasSucceeded() {
1551 return this.performed && this.succeeded;
1552 }
1553 hasFailed() {
1554 return this.performed && !this.succeeded;
1555 }
1556 getPromise() {
1557 if (!this.promise) {
1558 this.promise = new Promise((resolve, reject) => {
1559 this.performing = true;
1560 return this.perform((succeeded, result) => {
1561 this.succeeded = succeeded;
1562 this.performing = false;
1563 this.performed = true;
1564 if (this.succeeded) {
1565 resolve(result);
1566 } else {
1567 reject(result);
1568 }
1569 });
1570 });
1571 }
1572 return this.promise;
1573 }
1574 perform(callback) {
1575 return callback(false);
1576 }
1577 release() {
1578 var _this$promise, _this$promise$cancel;
1579 (_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);
1580 this.promise = null;
1581 this.performing = null;
1582 this.performed = null;
1583 this.succeeded = null;
1584 }
1585 }
1586 Operation.proxyMethod("getPromise().then");
1587 Operation.proxyMethod("getPromise().catch");
1588
1589 class ObjectView extends BasicObject {
1590 constructor(object) {
1591 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1592 super(...arguments);
1593 this.object = object;
1594 this.options = options;
1595 this.childViews = [];
1596 this.rootView = this;
1597 }
1598 getNodes() {
1599 if (!this.nodes) {
1600 this.nodes = this.createNodes();
1601 }
1602 return this.nodes.map(node => node.cloneNode(true));
1603 }
1604 invalidate() {
1605 var _this$parentView;
1606 this.nodes = null;
1607 this.childViews = [];
1608 return (_this$parentView = this.parentView) === null || _this$parentView === void 0 ? void 0 : _this$parentView.invalidate();
1609 }
1610 invalidateViewForObject(object) {
1611 var _this$findViewForObje;
1612 return (_this$findViewForObje = this.findViewForObject(object)) === null || _this$findViewForObje === void 0 ? void 0 : _this$findViewForObje.invalidate();
1613 }
1614 findOrCreateCachedChildView(viewClass, object, options) {
1615 let view = this.getCachedViewForObject(object);
1616 if (view) {
1617 this.recordChildView(view);
1618 } else {
1619 view = this.createChildView(...arguments);
1620 this.cacheViewForObject(view, object);
1621 }
1622 return view;
1623 }
1624 createChildView(viewClass, object) {
1625 let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1626 if (object instanceof ObjectGroup) {
1627 options.viewClass = viewClass;
1628 viewClass = ObjectGroupView;
1629 }
1630 const view = new viewClass(object, options);
1631 return this.recordChildView(view);
1632 }
1633 recordChildView(view) {
1634 view.parentView = this;
1635 view.rootView = this.rootView;
1636 this.childViews.push(view);
1637 return view;
1638 }
1639 getAllChildViews() {
1640 let views = [];
1641 this.childViews.forEach(childView => {
1642 views.push(childView);
1643 views = views.concat(childView.getAllChildViews());
1644 });
1645 return views;
1646 }
1647 findElement() {
1648 return this.findElementForObject(this.object);
1649 }
1650 findElementForObject(object) {
1651 const id = object === null || object === void 0 ? void 0 : object.id;
1652 if (id) {
1653 return this.rootView.element.querySelector("[data-trix-id='".concat(id, "']"));
1654 }
1655 }
1656 findViewForObject(object) {
1657 for (const view of this.getAllChildViews()) {
1658 if (view.object === object) {
1659 return view;
1660 }
1661 }
1662 }
1663 getViewCache() {
1664 if (this.rootView === this) {
1665 if (this.isViewCachingEnabled()) {
1666 if (!this.viewCache) {
1667 this.viewCache = {};
1668 }
1669 return this.viewCache;
1670 }
1671 } else {
1672 return this.rootView.getViewCache();
1673 }
1674 }
1675 isViewCachingEnabled() {
1676 return this.shouldCacheViews !== false;
1677 }
1678 enableViewCaching() {
1679 this.shouldCacheViews = true;
1680 }
1681 disableViewCaching() {
1682 this.shouldCacheViews = false;
1683 }
1684 getCachedViewForObject(object) {
1685 var _this$getViewCache;
1686 return (_this$getViewCache = this.getViewCache()) === null || _this$getViewCache === void 0 ? void 0 : _this$getViewCache[object.getCacheKey()];
1687 }
1688 cacheViewForObject(view, object) {
1689 const cache = this.getViewCache();
1690 if (cache) {
1691 cache[object.getCacheKey()] = view;
1692 }
1693 }
1694 garbageCollectCachedViews() {
1695 const cache = this.getViewCache();
1696 if (cache) {
1697 const views = this.getAllChildViews().concat(this);
1698 const objectKeys = views.map(view => view.object.getCacheKey());
1699 for (const key in cache) {
1700 if (!objectKeys.includes(key)) {
1701 delete cache[key];
1702 }
1703 }
1704 }
1705 }
1706 }
1707 class ObjectGroupView extends ObjectView {
1708 constructor() {
1709 super(...arguments);
1710 this.objectGroup = this.object;
1711 this.viewClass = this.options.viewClass;
1712 delete this.options.viewClass;
1713 }
1714 getChildViews() {
1715 if (!this.childViews.length) {
1716 Array.from(this.objectGroup.getObjects()).forEach(object => {
1717 this.findOrCreateCachedChildView(this.viewClass, object, this.options);
1718 });
1719 }
1720 return this.childViews;
1721 }
1722 createNodes() {
1723 const element = this.createContainerElement();
1724 this.getChildViews().forEach(view => {
1725 Array.from(view.getNodes()).forEach(node => {
1726 element.appendChild(node);
1727 });
1728 });
1729 return [element];
1730 }
1731 createContainerElement() {
1732 let depth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.objectGroup.getDepth();
1733 return this.getChildViews()[0].createContainerElement(depth);
1734 }
1735 }
1736
1737 /*! @license DOMPurify 3.2.3 | (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.3/LICENSE */
1738
1739 const {
1740 entries,
1741 setPrototypeOf,
1742 isFrozen,
1743 getPrototypeOf,
1744 getOwnPropertyDescriptor
1745 } = Object;
1746 let {
1747 freeze,
1748 seal,
1749 create
1750 } = Object; // eslint-disable-line import/no-mutable-exports
1751 let {
1752 apply,
1753 construct
1754 } = typeof Reflect !== 'undefined' && Reflect;
1755 if (!freeze) {
1756 freeze = function freeze(x) {
1757 return x;
1758 };
1759 }
1760 if (!seal) {
1761 seal = function seal(x) {
1762 return x;
1763 };
1764 }
1765 if (!apply) {
1766 apply = function apply(fun, thisValue, args) {
1767 return fun.apply(thisValue, args);
1768 };
1769 }
1770 if (!construct) {
1771 construct = function construct(Func, args) {
1772 return new Func(...args);
1773 };
1774 }
1775 const arrayForEach = unapply(Array.prototype.forEach);
1776 const arrayPop = unapply(Array.prototype.pop);
1777 const arrayPush = unapply(Array.prototype.push);
1778 const stringToLowerCase = unapply(String.prototype.toLowerCase);
1779 const stringToString = unapply(String.prototype.toString);
1780 const stringMatch = unapply(String.prototype.match);
1781 const stringReplace = unapply(String.prototype.replace);
1782 const stringIndexOf = unapply(String.prototype.indexOf);
1783 const stringTrim = unapply(String.prototype.trim);
1784 const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
1785 const regExpTest = unapply(RegExp.prototype.test);
1786 const typeErrorCreate = unconstruct(TypeError);
1787 /**
1788 * Creates a new function that calls the given function with a specified thisArg and arguments.
1789 *
1790 * @param func - The function to be wrapped and called.
1791 * @returns A new function that calls the given function with a specified thisArg and arguments.
1792 */
1793 function unapply(func) {
1794 return function (thisArg) {
1795 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1796 args[_key - 1] = arguments[_key];
1797 }
1798 return apply(func, thisArg, args);
1799 };
1800 }
1801 /**
1802 * Creates a new function that constructs an instance of the given constructor function with the provided arguments.
1803 *
1804 * @param func - The constructor function to be wrapped and called.
1805 * @returns A new function that constructs an instance of the given constructor function with the provided arguments.
1806 */
1807 function unconstruct(func) {
1808 return function () {
1809 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
1810 args[_key2] = arguments[_key2];
1811 }
1812 return construct(func, args);
1813 };
1814 }
1815 /**
1816 * Add properties to a lookup table
1817 *
1818 * @param set - The set to which elements will be added.
1819 * @param array - The array containing elements to be added to the set.
1820 * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.
1821 * @returns The modified set with added elements.
1822 */
1823 function addToSet(set, array) {
1824 let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
1825 if (setPrototypeOf) {
1826 // Make 'in' and truthy checks like Boolean(set.constructor)
1827 // independent of any properties defined on Object.prototype.
1828 // Prevent prototype setters from intercepting set as a this value.
1829 setPrototypeOf(set, null);
1830 }
1831 let l = array.length;
1832 while (l--) {
1833 let element = array[l];
1834 if (typeof element === 'string') {
1835 const lcElement = transformCaseFunc(element);
1836 if (lcElement !== element) {
1837 // Config presets (e.g. tags.js, attrs.js) are immutable.
1838 if (!isFrozen(array)) {
1839 array[l] = lcElement;
1840 }
1841 element = lcElement;
1842 }
1843 }
1844 set[element] = true;
1845 }
1846 return set;
1847 }
1848 /**
1849 * Clean up an array to harden against CSPP
1850 *
1851 * @param array - The array to be cleaned.
1852 * @returns The cleaned version of the array
1853 */
1854 function cleanArray(array) {
1855 for (let index = 0; index < array.length; index++) {
1856 const isPropertyExist = objectHasOwnProperty(array, index);
1857 if (!isPropertyExist) {
1858 array[index] = null;
1859 }
1860 }
1861 return array;
1862 }
1863 /**
1864 * Shallow clone an object
1865 *
1866 * @param object - The object to be cloned.
1867 * @returns A new object that copies the original.
1868 */
1869 function clone(object) {
1870 const newObject = create(null);
1871 for (const [property, value] of entries(object)) {
1872 const isPropertyExist = objectHasOwnProperty(object, property);
1873 if (isPropertyExist) {
1874 if (Array.isArray(value)) {
1875 newObject[property] = cleanArray(value);
1876 } else if (value && typeof value === 'object' && value.constructor === Object) {
1877 newObject[property] = clone(value);
1878 } else {
1879 newObject[property] = value;
1880 }
1881 }
1882 }
1883 return newObject;
1884 }
1885 /**
1886 * This method automatically checks if the prop is function or getter and behaves accordingly.
1887 *
1888 * @param object - The object to look up the getter function in its prototype chain.
1889 * @param prop - The property name for which to find the getter function.
1890 * @returns The getter function found in the prototype chain or a fallback function.
1891 */
1892 function lookupGetter(object, prop) {
1893 while (object !== null) {
1894 const desc = getOwnPropertyDescriptor(object, prop);
1895 if (desc) {
1896 if (desc.get) {
1897 return unapply(desc.get);
1898 }
1899 if (typeof desc.value === 'function') {
1900 return unapply(desc.value);
1901 }
1902 }
1903 object = getPrototypeOf(object);
1904 }
1905 function fallbackValue() {
1906 return null;
1907 }
1908 return fallbackValue;
1909 }
1910 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', 'section', 'select', 'shadow', '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']);
1911 const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
1912 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']);
1913 // List of SVG elements that are disallowed by default.
1914 // We still need to know them so that we can do namespace
1915 // checks properly in case one wants to add them to
1916 // allow-list.
1917 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']);
1918 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']);
1919 // Similarly to SVG, we want to know all MathML elements,
1920 // even those that we disallow by default.
1921 const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
1922 const text = freeze(['#text']);
1923 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', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', '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', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
1924 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']);
1925 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', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
1926 const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
1927
1928 // eslint-disable-next-line unicorn/better-regex
1929 const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
1930 const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
1931 const TMPLIT_EXPR = seal(/\$\{[\w\W]*}/gm); // eslint-disable-line unicorn/better-regex
1932 const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
1933 const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
1934 const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
1935 );
1936
1937 const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
1938 const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
1939 );
1940
1941 const DOCTYPE_NAME = seal(/^html$/i);
1942 const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
1943 var EXPRESSIONS = /*#__PURE__*/Object.freeze({
1944 __proto__: null,
1945 ARIA_ATTR: ARIA_ATTR,
1946 ATTR_WHITESPACE: ATTR_WHITESPACE,
1947 CUSTOM_ELEMENT: CUSTOM_ELEMENT,
1948 DATA_ATTR: DATA_ATTR,
1949 DOCTYPE_NAME: DOCTYPE_NAME,
1950 ERB_EXPR: ERB_EXPR,
1951 IS_ALLOWED_URI: IS_ALLOWED_URI,
1952 IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
1953 MUSTACHE_EXPR: MUSTACHE_EXPR,
1954 TMPLIT_EXPR: TMPLIT_EXPR
1955 });
1956
1957 /* eslint-disable @typescript-eslint/indent */
1958 // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
1959 const NODE_TYPE = {
1960 element: 1,
1961 attribute: 2,
1962 text: 3,
1963 cdataSection: 4,
1964 entityReference: 5,
1965 // Deprecated
1966 entityNode: 6,
1967 // Deprecated
1968 progressingInstruction: 7,
1969 comment: 8,
1970 document: 9,
1971 documentType: 10,
1972 documentFragment: 11,
1973 notation: 12 // Deprecated
1974 };
1975
1976 const getGlobal = function getGlobal() {
1977 return typeof window === 'undefined' ? null : window;
1978 };
1979 /**
1980 * Creates a no-op policy for internal use only.
1981 * Don't export this function outside this module!
1982 * @param trustedTypes The policy factory.
1983 * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).
1984 * @return The policy created (or null, if Trusted Types
1985 * are not supported or creating the policy failed).
1986 */
1987 const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
1988 if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
1989 return null;
1990 }
1991 // Allow the callers to control the unique policy name
1992 // by adding a data-tt-policy-suffix to the script element with the DOMPurify.
1993 // Policy creation with duplicate names throws in Trusted Types.
1994 let suffix = null;
1995 const ATTR_NAME = 'data-tt-policy-suffix';
1996 if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
1997 suffix = purifyHostElement.getAttribute(ATTR_NAME);
1998 }
1999 const policyName = 'dompurify' + (suffix ? '#' + suffix : '');
2000 try {
2001 return trustedTypes.createPolicy(policyName, {
2002 createHTML(html) {
2003 return html;
2004 },
2005 createScriptURL(scriptUrl) {
2006 return scriptUrl;
2007 }
2008 });
2009 } catch (_) {
2010 // Policy creation failed (most likely another DOMPurify script has
2011 // already run). Skip creating the policy, as this will only cause errors
2012 // if TT are enforced.
2013 console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
2014 return null;
2015 }
2016 };
2017 const _createHooksMap = function _createHooksMap() {
2018 return {
2019 afterSanitizeAttributes: [],
2020 afterSanitizeElements: [],
2021 afterSanitizeShadowDOM: [],
2022 beforeSanitizeAttributes: [],
2023 beforeSanitizeElements: [],
2024 beforeSanitizeShadowDOM: [],
2025 uponSanitizeAttribute: [],
2026 uponSanitizeElement: [],
2027 uponSanitizeShadowNode: []
2028 };
2029 };
2030 function createDOMPurify() {
2031 let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
2032 const DOMPurify = root => createDOMPurify(root);
2033 DOMPurify.version = '3.2.3';
2034 DOMPurify.removed = [];
2035 if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document) {
2036 // Not running in a browser, provide a factory function
2037 // so that you can pass your own Window
2038 DOMPurify.isSupported = false;
2039 return DOMPurify;
2040 }
2041 let {
2042 document
2043 } = window;
2044 const originalDocument = document;
2045 const currentScript = originalDocument.currentScript;
2046 const {
2047 DocumentFragment,
2048 HTMLTemplateElement,
2049 Node,
2050 Element,
2051 NodeFilter,
2052 NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,
2053 HTMLFormElement,
2054 DOMParser,
2055 trustedTypes
2056 } = window;
2057 const ElementPrototype = Element.prototype;
2058 const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
2059 const remove = lookupGetter(ElementPrototype, 'remove');
2060 const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
2061 const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
2062 const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
2063 // As per issue #47, the web-components registry is inherited by a
2064 // new document created via createHTMLDocument. As per the spec
2065 // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
2066 // a new empty registry is used when creating a template contents owner
2067 // document, so we use that as our parent document to ensure nothing
2068 // is inherited.
2069 if (typeof HTMLTemplateElement === 'function') {
2070 const template = document.createElement('template');
2071 if (template.content && template.content.ownerDocument) {
2072 document = template.content.ownerDocument;
2073 }
2074 }
2075 let trustedTypesPolicy;
2076 let emptyHTML = '';
2077 const {
2078 implementation,
2079 createNodeIterator,
2080 createDocumentFragment,
2081 getElementsByTagName
2082 } = document;
2083 const {
2084 importNode
2085 } = originalDocument;
2086 let hooks = _createHooksMap();
2087 /**
2088 * Expose whether this browser supports running the full DOMPurify.
2089 */
2090 DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
2091 const {
2092 MUSTACHE_EXPR,
2093 ERB_EXPR,
2094 TMPLIT_EXPR,
2095 DATA_ATTR,
2096 ARIA_ATTR,
2097 IS_SCRIPT_OR_DATA,
2098 ATTR_WHITESPACE,
2099 CUSTOM_ELEMENT
2100 } = EXPRESSIONS;
2101 let {
2102 IS_ALLOWED_URI: IS_ALLOWED_URI$1
2103 } = EXPRESSIONS;
2104 /**
2105 * We consider the elements and attributes below to be safe. Ideally
2106 * don't add any new ones but feel free to remove unwanted ones.
2107 */
2108 /* allowed element names */
2109 let ALLOWED_TAGS = null;
2110 const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
2111 /* Allowed attribute names */
2112 let ALLOWED_ATTR = null;
2113 const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
2114 /*
2115 * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.
2116 * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
2117 * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
2118 * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
2119 */
2120 let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
2121 tagNameCheck: {
2122 writable: true,
2123 configurable: false,
2124 enumerable: true,
2125 value: null
2126 },
2127 attributeNameCheck: {
2128 writable: true,
2129 configurable: false,
2130 enumerable: true,
2131 value: null
2132 },
2133 allowCustomizedBuiltInElements: {
2134 writable: true,
2135 configurable: false,
2136 enumerable: true,
2137 value: false
2138 }
2139 }));
2140 /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
2141 let FORBID_TAGS = null;
2142 /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
2143 let FORBID_ATTR = null;
2144 /* Decide if ARIA attributes are okay */
2145 let ALLOW_ARIA_ATTR = true;
2146 /* Decide if custom data attributes are okay */
2147 let ALLOW_DATA_ATTR = true;
2148 /* Decide if unknown protocols are okay */
2149 let ALLOW_UNKNOWN_PROTOCOLS = false;
2150 /* Decide if self-closing tags in attributes are allowed.
2151 * Usually removed due to a mXSS issue in jQuery 3.0 */
2152 let ALLOW_SELF_CLOSE_IN_ATTR = true;
2153 /* Output should be safe for common template engines.
2154 * This means, DOMPurify removes data attributes, mustaches and ERB
2155 */
2156 let SAFE_FOR_TEMPLATES = false;
2157 /* Output should be safe even for XML used within HTML and alike.
2158 * This means, DOMPurify removes comments when containing risky content.
2159 */
2160 let SAFE_FOR_XML = true;
2161 /* Decide if document with <html>... should be returned */
2162 let WHOLE_DOCUMENT = false;
2163 /* Track whether config is already set on this instance of DOMPurify. */
2164 let SET_CONFIG = false;
2165 /* Decide if all elements (e.g. style, script) must be children of
2166 * document.body. By default, browsers might move them to document.head */
2167 let FORCE_BODY = false;
2168 /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
2169 * string (or a TrustedHTML object if Trusted Types are supported).
2170 * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
2171 */
2172 let RETURN_DOM = false;
2173 /* Decide if a DOM `DocumentFragment` should be returned, instead of a html
2174 * string (or a TrustedHTML object if Trusted Types are supported) */
2175 let RETURN_DOM_FRAGMENT = false;
2176 /* Try to return a Trusted Type object instead of a string, return a string in
2177 * case Trusted Types are not supported */
2178 let RETURN_TRUSTED_TYPE = false;
2179 /* Output should be free from DOM clobbering attacks?
2180 * This sanitizes markups named with colliding, clobberable built-in DOM APIs.
2181 */
2182 let SANITIZE_DOM = true;
2183 /* Achieve full DOM Clobbering protection by isolating the namespace of named
2184 * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
2185 *
2186 * HTML/DOM spec rules that enable DOM Clobbering:
2187 * - Named Access on Window (§7.3.3)
2188 * - DOM Tree Accessors (§3.1.5)
2189 * - Form Element Parent-Child Relations (§4.10.3)
2190 * - Iframe srcdoc / Nested WindowProxies (§4.8.5)
2191 * - HTMLCollection (§4.2.10.2)
2192 *
2193 * Namespace isolation is implemented by prefixing `id` and `name` attributes
2194 * with a constant string, i.e., `user-content-`
2195 */
2196 let SANITIZE_NAMED_PROPS = false;
2197 const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
2198 /* Keep element content when removing element? */
2199 let KEEP_CONTENT = true;
2200 /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
2201 * of importing it into a new Document and returning a sanitized copy */
2202 let IN_PLACE = false;
2203 /* Allow usage of profiles like html, svg and mathMl */
2204 let USE_PROFILES = {};
2205 /* Tags to ignore content of when KEEP_CONTENT is true */
2206 let FORBID_CONTENTS = null;
2207 const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);
2208 /* Tags that are safe for data: URIs */
2209 let DATA_URI_TAGS = null;
2210 const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
2211 /* Attributes safe for values like "javascript:" */
2212 let URI_SAFE_ATTRIBUTES = null;
2213 const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
2214 const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
2215 const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
2216 const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
2217 /* Document namespace */
2218 let NAMESPACE = HTML_NAMESPACE;
2219 let IS_EMPTY_INPUT = false;
2220 /* Allowed XHTML+XML namespaces */
2221 let ALLOWED_NAMESPACES = null;
2222 const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
2223 let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
2224 let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);
2225 // Certain elements are allowed in both SVG and HTML
2226 // namespace. We need to specify them explicitly
2227 // so that they don't get erroneously deleted from
2228 // HTML namespace.
2229 const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
2230 /* Parsing of strict XHTML documents */
2231 let PARSER_MEDIA_TYPE = null;
2232 const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
2233 const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
2234 let transformCaseFunc = null;
2235 /* Keep a reference to config to pass to hooks */
2236 let CONFIG = null;
2237 /* Ideally, do not touch anything below this line */
2238 /* ______________________________________________ */
2239 const formElement = document.createElement('form');
2240 const isRegexOrFunction = function isRegexOrFunction(testValue) {
2241 return testValue instanceof RegExp || testValue instanceof Function;
2242 };
2243 /**
2244 * _parseConfig
2245 *
2246 * @param cfg optional config literal
2247 */
2248 // eslint-disable-next-line complexity
2249 const _parseConfig = function _parseConfig() {
2250 let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2251 if (CONFIG && CONFIG === cfg) {
2252 return;
2253 }
2254 /* Shield configuration object from tampering */
2255 if (!cfg || typeof cfg !== 'object') {
2256 cfg = {};
2257 }
2258 /* Shield configuration object from prototype pollution */
2259 cfg = clone(cfg);
2260 PARSER_MEDIA_TYPE =
2261 // eslint-disable-next-line unicorn/prefer-includes
2262 SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
2263 // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
2264 transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
2265 /* Set configuration parameters */
2266 ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
2267 ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
2268 ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
2269 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;
2270 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;
2271 FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
2272 FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
2273 FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
2274 USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;
2275 ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
2276 ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
2277 ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
2278 ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
2279 SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
2280 SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true
2281 WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
2282 RETURN_DOM = cfg.RETURN_DOM || false; // Default false
2283 RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
2284 RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
2285 FORCE_BODY = cfg.FORCE_BODY || false; // Default false
2286 SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
2287 SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
2288 KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
2289 IN_PLACE = cfg.IN_PLACE || false; // Default false
2290 IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;
2291 NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
2292 MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;
2293 HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;
2294 CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
2295 if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
2296 CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
2297 }
2298 if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {
2299 CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;
2300 }
2301 if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {
2302 CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
2303 }
2304 if (SAFE_FOR_TEMPLATES) {
2305 ALLOW_DATA_ATTR = false;
2306 }
2307 if (RETURN_DOM_FRAGMENT) {
2308 RETURN_DOM = true;
2309 }
2310 /* Parse profile info */
2311 if (USE_PROFILES) {
2312 ALLOWED_TAGS = addToSet({}, text);
2313 ALLOWED_ATTR = [];
2314 if (USE_PROFILES.html === true) {
2315 addToSet(ALLOWED_TAGS, html$1);
2316 addToSet(ALLOWED_ATTR, html);
2317 }
2318 if (USE_PROFILES.svg === true) {
2319 addToSet(ALLOWED_TAGS, svg$1);
2320 addToSet(ALLOWED_ATTR, svg);
2321 addToSet(ALLOWED_ATTR, xml);
2322 }
2323 if (USE_PROFILES.svgFilters === true) {
2324 addToSet(ALLOWED_TAGS, svgFilters);
2325 addToSet(ALLOWED_ATTR, svg);
2326 addToSet(ALLOWED_ATTR, xml);
2327 }
2328 if (USE_PROFILES.mathMl === true) {
2329 addToSet(ALLOWED_TAGS, mathMl$1);
2330 addToSet(ALLOWED_ATTR, mathMl);
2331 addToSet(ALLOWED_ATTR, xml);
2332 }
2333 }
2334 /* Merge configuration parameters */
2335 if (cfg.ADD_TAGS) {
2336 if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
2337 ALLOWED_TAGS = clone(ALLOWED_TAGS);
2338 }
2339 addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
2340 }
2341 if (cfg.ADD_ATTR) {
2342 if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
2343 ALLOWED_ATTR = clone(ALLOWED_ATTR);
2344 }
2345 addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
2346 }
2347 if (cfg.ADD_URI_SAFE_ATTR) {
2348 addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
2349 }
2350 if (cfg.FORBID_CONTENTS) {
2351 if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
2352 FORBID_CONTENTS = clone(FORBID_CONTENTS);
2353 }
2354 addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
2355 }
2356 /* Add #text in case KEEP_CONTENT is set to true */
2357 if (KEEP_CONTENT) {
2358 ALLOWED_TAGS['#text'] = true;
2359 }
2360 /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
2361 if (WHOLE_DOCUMENT) {
2362 addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
2363 }
2364 /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
2365 if (ALLOWED_TAGS.table) {
2366 addToSet(ALLOWED_TAGS, ['tbody']);
2367 delete FORBID_TAGS.tbody;
2368 }
2369 if (cfg.TRUSTED_TYPES_POLICY) {
2370 if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {
2371 throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
2372 }
2373 if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {
2374 throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
2375 }
2376 // Overwrite existing TrustedTypes policy.
2377 trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
2378 // Sign local variables required by `sanitize`.
2379 emptyHTML = trustedTypesPolicy.createHTML('');
2380 } else {
2381 // Uninitialized policy, attempt to initialize the internal dompurify policy.
2382 if (trustedTypesPolicy === undefined) {
2383 trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
2384 }
2385 // If creating the internal policy succeeded sign internal variables.
2386 if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {
2387 emptyHTML = trustedTypesPolicy.createHTML('');
2388 }
2389 }
2390 // Prevent further manipulation of configuration.
2391 // Not available in IE8, Safari 5, etc.
2392 if (freeze) {
2393 freeze(cfg);
2394 }
2395 CONFIG = cfg;
2396 };
2397 /* Keep track of all possible SVG and MathML tags
2398 * so that we can perform the namespace checks
2399 * correctly. */
2400 const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
2401 const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
2402 /**
2403 * @param element a DOM element whose namespace is being checked
2404 * @returns Return false if the element has a
2405 * namespace that a spec-compliant parser would never
2406 * return. Return true otherwise.
2407 */
2408 const _checkValidNamespace = function _checkValidNamespace(element) {
2409 let parent = getParentNode(element);
2410 // In JSDOM, if we're inside shadow DOM, then parentNode
2411 // can be null. We just simulate parent in this case.
2412 if (!parent || !parent.tagName) {
2413 parent = {
2414 namespaceURI: NAMESPACE,
2415 tagName: 'template'
2416 };
2417 }
2418 const tagName = stringToLowerCase(element.tagName);
2419 const parentTagName = stringToLowerCase(parent.tagName);
2420 if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
2421 return false;
2422 }
2423 if (element.namespaceURI === SVG_NAMESPACE) {
2424 // The only way to switch from HTML namespace to SVG
2425 // is via <svg>. If it happens via any other tag, then
2426 // it should be killed.
2427 if (parent.namespaceURI === HTML_NAMESPACE) {
2428 return tagName === 'svg';
2429 }
2430 // The only way to switch from MathML to SVG is via`
2431 // svg if parent is either <annotation-xml> or MathML
2432 // text integration points.
2433 if (parent.namespaceURI === MATHML_NAMESPACE) {
2434 return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
2435 }
2436 // We only allow elements that are defined in SVG
2437 // spec. All others are disallowed in SVG namespace.
2438 return Boolean(ALL_SVG_TAGS[tagName]);
2439 }
2440 if (element.namespaceURI === MATHML_NAMESPACE) {
2441 // The only way to switch from HTML namespace to MathML
2442 // is via <math>. If it happens via any other tag, then
2443 // it should be killed.
2444 if (parent.namespaceURI === HTML_NAMESPACE) {
2445 return tagName === 'math';
2446 }
2447 // The only way to switch from SVG to MathML is via
2448 // <math> and HTML integration points
2449 if (parent.namespaceURI === SVG_NAMESPACE) {
2450 return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
2451 }
2452 // We only allow elements that are defined in MathML
2453 // spec. All others are disallowed in MathML namespace.
2454 return Boolean(ALL_MATHML_TAGS[tagName]);
2455 }
2456 if (element.namespaceURI === HTML_NAMESPACE) {
2457 // The only way to switch from SVG to HTML is via
2458 // HTML integration points, and from MathML to HTML
2459 // is via MathML text integration points
2460 if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
2461 return false;
2462 }
2463 if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
2464 return false;
2465 }
2466 // We disallow tags that are specific for MathML
2467 // or SVG and should never appear in HTML namespace
2468 return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
2469 }
2470 // For XHTML and XML documents that support custom namespaces
2471 if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {
2472 return true;
2473 }
2474 // The code should never reach this place (this means
2475 // that the element somehow got namespace that is not
2476 // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).
2477 // Return false just in case.
2478 return false;
2479 };
2480 /**
2481 * _forceRemove
2482 *
2483 * @param node a DOM node
2484 */
2485 const _forceRemove = function _forceRemove(node) {
2486 arrayPush(DOMPurify.removed, {
2487 element: node
2488 });
2489 try {
2490 // eslint-disable-next-line unicorn/prefer-dom-node-remove
2491 getParentNode(node).removeChild(node);
2492 } catch (_) {
2493 remove(node);
2494 }
2495 };
2496 /**
2497 * _removeAttribute
2498 *
2499 * @param name an Attribute name
2500 * @param element a DOM node
2501 */
2502 const _removeAttribute = function _removeAttribute(name, element) {
2503 try {
2504 arrayPush(DOMPurify.removed, {
2505 attribute: element.getAttributeNode(name),
2506 from: element
2507 });
2508 } catch (_) {
2509 arrayPush(DOMPurify.removed, {
2510 attribute: null,
2511 from: element
2512 });
2513 }
2514 element.removeAttribute(name);
2515 // We void attribute values for unremovable "is" attributes
2516 if (name === 'is') {
2517 if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
2518 try {
2519 _forceRemove(element);
2520 } catch (_) {}
2521 } else {
2522 try {
2523 element.setAttribute(name, '');
2524 } catch (_) {}
2525 }
2526 }
2527 };
2528 /**
2529 * _initDocument
2530 *
2531 * @param dirty - a string of dirty markup
2532 * @return a DOM, filled with the dirty markup
2533 */
2534 const _initDocument = function _initDocument(dirty) {
2535 /* Create a HTML document */
2536 let doc = null;
2537 let leadingWhitespace = null;
2538 if (FORCE_BODY) {
2539 dirty = '<remove></remove>' + dirty;
2540 } else {
2541 /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
2542 const matches = stringMatch(dirty, /^[\r\n\t ]+/);
2543 leadingWhitespace = matches && matches[0];
2544 }
2545 if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {
2546 // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
2547 dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
2548 }
2549 const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
2550 /*
2551 * Use the DOMParser API by default, fallback later if needs be
2552 * DOMParser not work for svg when has multiple root element.
2553 */
2554 if (NAMESPACE === HTML_NAMESPACE) {
2555 try {
2556 doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
2557 } catch (_) {}
2558 }
2559 /* Use createHTMLDocument in case DOMParser is not available */
2560 if (!doc || !doc.documentElement) {
2561 doc = implementation.createDocument(NAMESPACE, 'template', null);
2562 try {
2563 doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
2564 } catch (_) {
2565 // Syntax error if dirtyPayload is invalid xml
2566 }
2567 }
2568 const body = doc.body || doc.documentElement;
2569 if (dirty && leadingWhitespace) {
2570 body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
2571 }
2572 /* Work on whole document or just its body */
2573 if (NAMESPACE === HTML_NAMESPACE) {
2574 return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
2575 }
2576 return WHOLE_DOCUMENT ? doc.documentElement : body;
2577 };
2578 /**
2579 * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
2580 *
2581 * @param root The root element or node to start traversing on.
2582 * @return The created NodeIterator
2583 */
2584 const _createNodeIterator = function _createNodeIterator(root) {
2585 return createNodeIterator.call(root.ownerDocument || root, root,
2586 // eslint-disable-next-line no-bitwise
2587 NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
2588 };
2589 /**
2590 * _isClobbered
2591 *
2592 * @param element element to check for clobbering attacks
2593 * @return true if clobbered, false if safe
2594 */
2595 const _isClobbered = function _isClobbered(element) {
2596 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');
2597 };
2598 /**
2599 * Checks whether the given object is a DOM node.
2600 *
2601 * @param value object to check whether it's a DOM node
2602 * @return true is object is a DOM node
2603 */
2604 const _isNode = function _isNode(value) {
2605 return typeof Node === 'function' && value instanceof Node;
2606 };
2607 function _executeHooks(hooks, currentNode, data) {
2608 arrayForEach(hooks, hook => {
2609 hook.call(DOMPurify, currentNode, data, CONFIG);
2610 });
2611 }
2612 /**
2613 * _sanitizeElements
2614 *
2615 * @protect nodeName
2616 * @protect textContent
2617 * @protect removeChild
2618 * @param currentNode to check for permission to exist
2619 * @return true if node was killed, false if left alive
2620 */
2621 const _sanitizeElements = function _sanitizeElements(currentNode) {
2622 let content = null;
2623 /* Execute a hook if present */
2624 _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
2625 /* Check if element is clobbered or can clobber */
2626 if (_isClobbered(currentNode)) {
2627 _forceRemove(currentNode);
2628 return true;
2629 }
2630 /* Now let's check the element's type and name */
2631 const tagName = transformCaseFunc(currentNode.nodeName);
2632 /* Execute a hook if present */
2633 _executeHooks(hooks.uponSanitizeElement, currentNode, {
2634 tagName,
2635 allowedTags: ALLOWED_TAGS
2636 });
2637 /* Detect mXSS attempts abusing namespace confusion */
2638 if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
2639 _forceRemove(currentNode);
2640 return true;
2641 }
2642 /* Remove any occurrence of processing instructions */
2643 if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
2644 _forceRemove(currentNode);
2645 return true;
2646 }
2647 /* Remove any kind of possibly harmful comments */
2648 if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
2649 _forceRemove(currentNode);
2650 return true;
2651 }
2652 /* Remove element if anything forbids its presence */
2653 if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
2654 /* Check if we have a custom element to handle */
2655 if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
2656 if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
2657 return false;
2658 }
2659 if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
2660 return false;
2661 }
2662 }
2663 /* Keep content except for bad-listed elements */
2664 if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
2665 const parentNode = getParentNode(currentNode) || currentNode.parentNode;
2666 const childNodes = getChildNodes(currentNode) || currentNode.childNodes;
2667 if (childNodes && parentNode) {
2668 const childCount = childNodes.length;
2669 for (let i = childCount - 1; i >= 0; --i) {
2670 const childClone = cloneNode(childNodes[i], true);
2671 childClone.__removalCount = (currentNode.__removalCount || 0) + 1;
2672 parentNode.insertBefore(childClone, getNextSibling(currentNode));
2673 }
2674 }
2675 }
2676 _forceRemove(currentNode);
2677 return true;
2678 }
2679 /* Check whether element has a valid namespace */
2680 if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
2681 _forceRemove(currentNode);
2682 return true;
2683 }
2684 /* Make sure that older browsers don't get fallback-tag mXSS */
2685 if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
2686 _forceRemove(currentNode);
2687 return true;
2688 }
2689 /* Sanitize element content to be template-safe */
2690 if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
2691 /* Get the element's text content */
2692 content = currentNode.textContent;
2693 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
2694 content = stringReplace(content, expr, ' ');
2695 });
2696 if (currentNode.textContent !== content) {
2697 arrayPush(DOMPurify.removed, {
2698 element: currentNode.cloneNode()
2699 });
2700 currentNode.textContent = content;
2701 }
2702 }
2703 /* Execute a hook if present */
2704 _executeHooks(hooks.afterSanitizeElements, currentNode, null);
2705 return false;
2706 };
2707 /**
2708 * _isValidAttribute
2709 *
2710 * @param lcTag Lowercase tag name of containing element.
2711 * @param lcName Lowercase attribute name.
2712 * @param value Attribute value.
2713 * @return Returns true if `value` is valid, otherwise false.
2714 */
2715 // eslint-disable-next-line complexity
2716 const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
2717 /* Make sure attribute cannot clobber */
2718 if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
2719 return false;
2720 }
2721 /* Allow valid data-* attributes: At least one character after "-"
2722 (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
2723 XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
2724 We don't need to check the value; it's always URI safe. */
2725 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]) {
2726 if (
2727 // First condition does a very basic check if a) it's basically a valid custom element tagname AND
2728 // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
2729 // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
2730 _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)) ||
2731 // Alternative, second condition checks if it's an `is`-attribute, AND
2732 // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
2733 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 {
2734 return false;
2735 }
2736 /* Check value is safe. First, is attr inert? If so, is safe */
2737 } 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) {
2738 return false;
2739 } else ;
2740 return true;
2741 };
2742 /**
2743 * _isBasicCustomElement
2744 * checks if at least one dash is included in tagName, and it's not the first char
2745 * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
2746 *
2747 * @param tagName name of the tag of the node to sanitize
2748 * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
2749 */
2750 const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
2751 return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);
2752 };
2753 /**
2754 * _sanitizeAttributes
2755 *
2756 * @protect attributes
2757 * @protect nodeName
2758 * @protect removeAttribute
2759 * @protect setAttribute
2760 *
2761 * @param currentNode to sanitize
2762 */
2763 const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
2764 /* Execute a hook if present */
2765 _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
2766 const {
2767 attributes
2768 } = currentNode;
2769 /* Check if we have attributes; if not we might have a text node */
2770 if (!attributes || _isClobbered(currentNode)) {
2771 return;
2772 }
2773 const hookEvent = {
2774 attrName: '',
2775 attrValue: '',
2776 keepAttr: true,
2777 allowedAttributes: ALLOWED_ATTR,
2778 forceKeepAttr: undefined
2779 };
2780 let l = attributes.length;
2781 /* Go backwards over all attributes; safely remove bad ones */
2782 while (l--) {
2783 const attr = attributes[l];
2784 const {
2785 name,
2786 namespaceURI,
2787 value: attrValue
2788 } = attr;
2789 const lcName = transformCaseFunc(name);
2790 let value = name === 'value' ? attrValue : stringTrim(attrValue);
2791 /* Execute a hook if present */
2792 hookEvent.attrName = lcName;
2793 hookEvent.attrValue = value;
2794 hookEvent.keepAttr = true;
2795 hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
2796 _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
2797 value = hookEvent.attrValue;
2798 /* Full DOM Clobbering protection via namespace isolation,
2799 * Prefix id and name attributes with `user-content-`
2800 */
2801 if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
2802 // Remove the attribute with this value
2803 _removeAttribute(name, currentNode);
2804 // Prefix the value and later re-create the attribute with the sanitized value
2805 value = SANITIZE_NAMED_PROPS_PREFIX + value;
2806 }
2807 /* Work around a security issue with comments inside attributes */
2808 if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
2809 _removeAttribute(name, currentNode);
2810 continue;
2811 }
2812 /* Did the hooks approve of the attribute? */
2813 if (hookEvent.forceKeepAttr) {
2814 continue;
2815 }
2816 /* Remove attribute */
2817 _removeAttribute(name, currentNode);
2818 /* Did the hooks approve of the attribute? */
2819 if (!hookEvent.keepAttr) {
2820 continue;
2821 }
2822 /* Work around a security issue in jQuery 3.0 */
2823 if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
2824 _removeAttribute(name, currentNode);
2825 continue;
2826 }
2827 /* Sanitize attribute content to be template-safe */
2828 if (SAFE_FOR_TEMPLATES) {
2829 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
2830 value = stringReplace(value, expr, ' ');
2831 });
2832 }
2833 /* Is `value` valid for this attribute? */
2834 const lcTag = transformCaseFunc(currentNode.nodeName);
2835 if (!_isValidAttribute(lcTag, lcName, value)) {
2836 continue;
2837 }
2838 /* Handle attributes that require Trusted Types */
2839 if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {
2840 if (namespaceURI) ;else {
2841 switch (trustedTypes.getAttributeType(lcTag, lcName)) {
2842 case 'TrustedHTML':
2843 {
2844 value = trustedTypesPolicy.createHTML(value);
2845 break;
2846 }
2847 case 'TrustedScriptURL':
2848 {
2849 value = trustedTypesPolicy.createScriptURL(value);
2850 break;
2851 }
2852 }
2853 }
2854 }
2855 /* Handle invalid data-* attribute set by try-catching it */
2856 try {
2857 if (namespaceURI) {
2858 currentNode.setAttributeNS(namespaceURI, name, value);
2859 } else {
2860 /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
2861 currentNode.setAttribute(name, value);
2862 }
2863 if (_isClobbered(currentNode)) {
2864 _forceRemove(currentNode);
2865 } else {
2866 arrayPop(DOMPurify.removed);
2867 }
2868 } catch (_) {}
2869 }
2870 /* Execute a hook if present */
2871 _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
2872 };
2873 /**
2874 * _sanitizeShadowDOM
2875 *
2876 * @param fragment to iterate over recursively
2877 */
2878 const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
2879 let shadowNode = null;
2880 const shadowIterator = _createNodeIterator(fragment);
2881 /* Execute a hook if present */
2882 _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
2883 while (shadowNode = shadowIterator.nextNode()) {
2884 /* Execute a hook if present */
2885 _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
2886 /* Sanitize tags and elements */
2887 _sanitizeElements(shadowNode);
2888 /* Check attributes next */
2889 _sanitizeAttributes(shadowNode);
2890 /* Deep shadow DOM detected */
2891 if (shadowNode.content instanceof DocumentFragment) {
2892 _sanitizeShadowDOM(shadowNode.content);
2893 }
2894 }
2895 /* Execute a hook if present */
2896 _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
2897 };
2898 // eslint-disable-next-line complexity
2899 DOMPurify.sanitize = function (dirty) {
2900 let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2901 let body = null;
2902 let importedNode = null;
2903 let currentNode = null;
2904 let returnNode = null;
2905 /* Make sure we have a string to sanitize.
2906 DO NOT return early, as this will return the wrong type if
2907 the user has requested a DOM object rather than a string */
2908 IS_EMPTY_INPUT = !dirty;
2909 if (IS_EMPTY_INPUT) {
2910 dirty = '<!-->';
2911 }
2912 /* Stringify, in case dirty is an object */
2913 if (typeof dirty !== 'string' && !_isNode(dirty)) {
2914 if (typeof dirty.toString === 'function') {
2915 dirty = dirty.toString();
2916 if (typeof dirty !== 'string') {
2917 throw typeErrorCreate('dirty is not a string, aborting');
2918 }
2919 } else {
2920 throw typeErrorCreate('toString is not a function');
2921 }
2922 }
2923 /* Return dirty HTML if DOMPurify cannot run */
2924 if (!DOMPurify.isSupported) {
2925 return dirty;
2926 }
2927 /* Assign config vars */
2928 if (!SET_CONFIG) {
2929 _parseConfig(cfg);
2930 }
2931 /* Clean up removed elements */
2932 DOMPurify.removed = [];
2933 /* Check if dirty is correctly typed for IN_PLACE */
2934 if (typeof dirty === 'string') {
2935 IN_PLACE = false;
2936 }
2937 if (IN_PLACE) {
2938 /* Do some early pre-sanitization to avoid unsafe root nodes */
2939 if (dirty.nodeName) {
2940 const tagName = transformCaseFunc(dirty.nodeName);
2941 if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
2942 throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
2943 }
2944 }
2945 } else if (dirty instanceof Node) {
2946 /* If dirty is a DOM element, append to an empty document to avoid
2947 elements being stripped by the parser */
2948 body = _initDocument('<!---->');
2949 importedNode = body.ownerDocument.importNode(dirty, true);
2950 if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {
2951 /* Node is already a body, use as is */
2952 body = importedNode;
2953 } else if (importedNode.nodeName === 'HTML') {
2954 body = importedNode;
2955 } else {
2956 // eslint-disable-next-line unicorn/prefer-dom-node-append
2957 body.appendChild(importedNode);
2958 }
2959 } else {
2960 /* Exit directly if we have nothing to do */
2961 if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
2962 // eslint-disable-next-line unicorn/prefer-includes
2963 dirty.indexOf('<') === -1) {
2964 return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
2965 }
2966 /* Initialize the document to work on */
2967 body = _initDocument(dirty);
2968 /* Check we have a DOM node from the data */
2969 if (!body) {
2970 return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
2971 }
2972 }
2973 /* Remove first element node (ours) if FORCE_BODY is set */
2974 if (body && FORCE_BODY) {
2975 _forceRemove(body.firstChild);
2976 }
2977 /* Get node iterator */
2978 const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
2979 /* Now start iterating over the created document */
2980 while (currentNode = nodeIterator.nextNode()) {
2981 /* Sanitize tags and elements */
2982 _sanitizeElements(currentNode);
2983 /* Check attributes next */
2984 _sanitizeAttributes(currentNode);
2985 /* Shadow DOM detected, sanitize it */
2986 if (currentNode.content instanceof DocumentFragment) {
2987 _sanitizeShadowDOM(currentNode.content);
2988 }
2989 }
2990 /* If we sanitized `dirty` in-place, return it. */
2991 if (IN_PLACE) {
2992 return dirty;
2993 }
2994 /* Return sanitized string or DOM */
2995 if (RETURN_DOM) {
2996 if (RETURN_DOM_FRAGMENT) {
2997 returnNode = createDocumentFragment.call(body.ownerDocument);
2998 while (body.firstChild) {
2999 // eslint-disable-next-line unicorn/prefer-dom-node-append
3000 returnNode.appendChild(body.firstChild);
3001 }
3002 } else {
3003 returnNode = body;
3004 }
3005 if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
3006 /*
3007 AdoptNode() is not used because internal state is not reset
3008 (e.g. the past names map of a HTMLFormElement), this is safe
3009 in theory but we would rather not risk another attack vector.
3010 The state that is cloned by importNode() is explicitly defined
3011 by the specs.
3012 */
3013 returnNode = importNode.call(originalDocument, returnNode, true);
3014 }
3015 return returnNode;
3016 }
3017 let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
3018 /* Serialize doctype if allowed */
3019 if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
3020 serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
3021 }
3022 /* Sanitize final string template-safe */
3023 if (SAFE_FOR_TEMPLATES) {
3024 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
3025 serializedHTML = stringReplace(serializedHTML, expr, ' ');
3026 });
3027 }
3028 return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
3029 };
3030 DOMPurify.setConfig = function () {
3031 let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3032 _parseConfig(cfg);
3033 SET_CONFIG = true;
3034 };
3035 DOMPurify.clearConfig = function () {
3036 CONFIG = null;
3037 SET_CONFIG = false;
3038 };
3039 DOMPurify.isValidAttribute = function (tag, attr, value) {
3040 /* Initialize shared config vars if necessary. */
3041 if (!CONFIG) {
3042 _parseConfig({});
3043 }
3044 const lcTag = transformCaseFunc(tag);
3045 const lcName = transformCaseFunc(attr);
3046 return _isValidAttribute(lcTag, lcName, value);
3047 };
3048 DOMPurify.addHook = function (entryPoint, hookFunction) {
3049 if (typeof hookFunction !== 'function') {
3050 return;
3051 }
3052 arrayPush(hooks[entryPoint], hookFunction);
3053 };
3054 DOMPurify.removeHook = function (entryPoint) {
3055 return arrayPop(hooks[entryPoint]);
3056 };
3057 DOMPurify.removeHooks = function (entryPoint) {
3058 hooks[entryPoint] = [];
3059 };
3060 DOMPurify.removeAllHooks = function () {
3061 hooks = _createHooksMap();
3062 };
3063 return DOMPurify;
3064 }
3065 var purify = createDOMPurify();
3066
3067 const DEFAULT_ALLOWED_ATTRIBUTES = "style href src width height language class".split(" ");
3068 const DEFAULT_FORBIDDEN_PROTOCOLS = "javascript:".split(" ");
3069 const DEFAULT_FORBIDDEN_ELEMENTS = "script iframe form noscript".split(" ");
3070 class HTMLSanitizer extends BasicObject {
3071 static setHTML(element, html) {
3072 const sanitizedElement = new this(html).sanitize();
3073 const sanitizedHtml = sanitizedElement.getHTML ? sanitizedElement.getHTML() : sanitizedElement.outerHTML;
3074 element.innerHTML = sanitizedHtml;
3075 }
3076 static sanitize(html, options) {
3077 const sanitizer = new this(html, options);
3078 sanitizer.sanitize();
3079 return sanitizer;
3080 }
3081 constructor(html) {
3082 let {
3083 allowedAttributes,
3084 forbiddenProtocols,
3085 forbiddenElements
3086 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3087 super(...arguments);
3088 this.allowedAttributes = allowedAttributes || DEFAULT_ALLOWED_ATTRIBUTES;
3089 this.forbiddenProtocols = forbiddenProtocols || DEFAULT_FORBIDDEN_PROTOCOLS;
3090 this.forbiddenElements = forbiddenElements || DEFAULT_FORBIDDEN_ELEMENTS;
3091 this.body = createBodyElementForHTML(html);
3092 }
3093 sanitize() {
3094 this.sanitizeElements();
3095 this.normalizeListElementNesting();
3096 return purify.sanitize(this.body, {
3097 ADD_ATTR: ["language"],
3098 RETURN_DOM: true
3099 });
3100 }
3101 getHTML() {
3102 return this.body.innerHTML;
3103 }
3104 getBody() {
3105 return this.body;
3106 }
3107
3108 // Private
3109
3110 sanitizeElements() {
3111 const walker = walkTree(this.body);
3112 const nodesToRemove = [];
3113 while (walker.nextNode()) {
3114 const node = walker.currentNode;
3115 switch (node.nodeType) {
3116 case Node.ELEMENT_NODE:
3117 if (this.elementIsRemovable(node)) {
3118 nodesToRemove.push(node);
3119 } else {
3120 this.sanitizeElement(node);
3121 }
3122 break;
3123 case Node.COMMENT_NODE:
3124 nodesToRemove.push(node);
3125 break;
3126 }
3127 }
3128 nodesToRemove.forEach(node => removeNode(node));
3129 return this.body;
3130 }
3131 sanitizeElement(element) {
3132 if (element.hasAttribute("href")) {
3133 if (this.forbiddenProtocols.includes(element.protocol)) {
3134 element.removeAttribute("href");
3135 }
3136 }
3137 Array.from(element.attributes).forEach(_ref => {
3138 let {
3139 name
3140 } = _ref;
3141 if (!this.allowedAttributes.includes(name) && name.indexOf("data-trix") !== 0) {
3142 element.removeAttribute(name);
3143 }
3144 });
3145 return element;
3146 }
3147 normalizeListElementNesting() {
3148 Array.from(this.body.querySelectorAll("ul,ol")).forEach(listElement => {
3149 const previousElement = listElement.previousElementSibling;
3150 if (previousElement) {
3151 if (tagName(previousElement) === "li") {
3152 previousElement.appendChild(listElement);
3153 }
3154 }
3155 });
3156 return this.body;
3157 }
3158 elementIsRemovable(element) {
3159 if ((element === null || element === void 0 ? void 0 : element.nodeType) !== Node.ELEMENT_NODE) return;
3160 return this.elementIsForbidden(element) || this.elementIsntSerializable(element);
3161 }
3162 elementIsForbidden(element) {
3163 return this.forbiddenElements.includes(tagName(element));
3164 }
3165 elementIsntSerializable(element) {
3166 return element.getAttribute("data-trix-serialize") === "false" && !nodeIsAttachmentElement(element);
3167 }
3168 }
3169 const createBodyElementForHTML = function () {
3170 let html = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
3171 // Remove everything after </html>
3172 html = html.replace(/<\/html[^>]*>[^]*$/i, "</html>");
3173 const doc = document.implementation.createHTMLDocument("");
3174 doc.documentElement.innerHTML = html;
3175 Array.from(doc.head.querySelectorAll("style")).forEach(element => {
3176 doc.body.appendChild(element);
3177 });
3178 return doc.body;
3179 };
3180
3181 const {
3182 css: css$2
3183 } = config;
3184 class AttachmentView extends ObjectView {
3185 constructor() {
3186 super(...arguments);
3187 this.attachment = this.object;
3188 this.attachment.uploadProgressDelegate = this;
3189 this.attachmentPiece = this.options.piece;
3190 }
3191 createContentNodes() {
3192 return [];
3193 }
3194 createNodes() {
3195 let innerElement;
3196 const figure = innerElement = makeElement({
3197 tagName: "figure",
3198 className: this.getClassName(),
3199 data: this.getData(),
3200 editable: false
3201 });
3202 const href = this.getHref();
3203 if (href) {
3204 innerElement = makeElement({
3205 tagName: "a",
3206 editable: false,
3207 attributes: {
3208 href,
3209 tabindex: -1
3210 }
3211 });
3212 figure.appendChild(innerElement);
3213 }
3214 if (this.attachment.hasContent()) {
3215 HTMLSanitizer.setHTML(innerElement, this.attachment.getContent());
3216 } else {
3217 this.createContentNodes().forEach(node => {
3218 innerElement.appendChild(node);
3219 });
3220 }
3221 innerElement.appendChild(this.createCaptionElement());
3222 if (this.attachment.isPending()) {
3223 this.progressElement = makeElement({
3224 tagName: "progress",
3225 attributes: {
3226 class: css$2.attachmentProgress,
3227 value: this.attachment.getUploadProgress(),
3228 max: 100
3229 },
3230 data: {
3231 trixMutable: true,
3232 trixStoreKey: ["progressElement", this.attachment.id].join("/")
3233 }
3234 });
3235 figure.appendChild(this.progressElement);
3236 }
3237 return [createCursorTarget("left"), figure, createCursorTarget("right")];
3238 }
3239 createCaptionElement() {
3240 const figcaption = makeElement({
3241 tagName: "figcaption",
3242 className: css$2.attachmentCaption
3243 });
3244 const caption = this.attachmentPiece.getCaption();
3245 if (caption) {
3246 figcaption.classList.add("".concat(css$2.attachmentCaption, "--edited"));
3247 figcaption.textContent = caption;
3248 } else {
3249 let name, size;
3250 const captionConfig = this.getCaptionConfig();
3251 if (captionConfig.name) {
3252 name = this.attachment.getFilename();
3253 }
3254 if (captionConfig.size) {
3255 size = this.attachment.getFormattedFilesize();
3256 }
3257 if (name) {
3258 const nameElement = makeElement({
3259 tagName: "span",
3260 className: css$2.attachmentName,
3261 textContent: name
3262 });
3263 figcaption.appendChild(nameElement);
3264 }
3265 if (size) {
3266 if (name) {
3267 figcaption.appendChild(document.createTextNode(" "));
3268 }
3269 const sizeElement = makeElement({
3270 tagName: "span",
3271 className: css$2.attachmentSize,
3272 textContent: size
3273 });
3274 figcaption.appendChild(sizeElement);
3275 }
3276 }
3277 return figcaption;
3278 }
3279 getClassName() {
3280 const names = [css$2.attachment, "".concat(css$2.attachment, "--").concat(this.attachment.getType())];
3281 const extension = this.attachment.getExtension();
3282 if (extension) {
3283 names.push("".concat(css$2.attachment, "--").concat(extension));
3284 }
3285 return names.join(" ");
3286 }
3287 getData() {
3288 const data = {
3289 trixAttachment: JSON.stringify(this.attachment),
3290 trixContentType: this.attachment.getContentType(),
3291 trixId: this.attachment.id
3292 };
3293 const {
3294 attributes
3295 } = this.attachmentPiece;
3296 if (!attributes.isEmpty()) {
3297 data.trixAttributes = JSON.stringify(attributes);
3298 }
3299 if (this.attachment.isPending()) {
3300 data.trixSerialize = false;
3301 }
3302 return data;
3303 }
3304 getHref() {
3305 if (!htmlContainsTagName(this.attachment.getContent(), "a")) {
3306 return this.attachment.getHref();
3307 }
3308 }
3309 getCaptionConfig() {
3310 var _config$attachments$t;
3311 const type = this.attachment.getType();
3312 const captionConfig = copyObject((_config$attachments$t = attachments[type]) === null || _config$attachments$t === void 0 ? void 0 : _config$attachments$t.caption);
3313 if (type === "file") {
3314 captionConfig.name = true;
3315 }
3316 return captionConfig;
3317 }
3318 findProgressElement() {
3319 var _this$findElement;
3320 return (_this$findElement = this.findElement()) === null || _this$findElement === void 0 ? void 0 : _this$findElement.querySelector("progress");
3321 }
3322
3323 // Attachment delegate
3324
3325 attachmentDidChangeUploadProgress() {
3326 const value = this.attachment.getUploadProgress();
3327 const progressElement = this.findProgressElement();
3328 if (progressElement) {
3329 progressElement.value = value;
3330 }
3331 }
3332 }
3333 const createCursorTarget = name => makeElement({
3334 tagName: "span",
3335 textContent: ZERO_WIDTH_SPACE,
3336 data: {
3337 trixCursorTarget: name,
3338 trixSerialize: false
3339 }
3340 });
3341 const htmlContainsTagName = function (html, tagName) {
3342 const div = makeElement("div");
3343 HTMLSanitizer.setHTML(div, html || "");
3344 return div.querySelector(tagName);
3345 };
3346
3347 class PreviewableAttachmentView extends AttachmentView {
3348 constructor() {
3349 super(...arguments);
3350 this.attachment.previewDelegate = this;
3351 }
3352 createContentNodes() {
3353 this.image = makeElement({
3354 tagName: "img",
3355 attributes: {
3356 src: ""
3357 },
3358 data: {
3359 trixMutable: true
3360 }
3361 });
3362 this.refresh(this.image);
3363 return [this.image];
3364 }
3365 createCaptionElement() {
3366 const figcaption = super.createCaptionElement(...arguments);
3367 if (!figcaption.textContent) {
3368 figcaption.setAttribute("data-trix-placeholder", lang$1.captionPlaceholder);
3369 }
3370 return figcaption;
3371 }
3372 refresh(image) {
3373 if (!image) {
3374 var _this$findElement;
3375 image = (_this$findElement = this.findElement()) === null || _this$findElement === void 0 ? void 0 : _this$findElement.querySelector("img");
3376 }
3377 if (image) {
3378 return this.updateAttributesForImage(image);
3379 }
3380 }
3381 updateAttributesForImage(image) {
3382 const url = this.attachment.getURL();
3383 const previewURL = this.attachment.getPreviewURL();
3384 image.src = previewURL || url;
3385 if (previewURL === url) {
3386 image.removeAttribute("data-trix-serialized-attributes");
3387 } else {
3388 const serializedAttributes = JSON.stringify({
3389 src: url
3390 });
3391 image.setAttribute("data-trix-serialized-attributes", serializedAttributes);
3392 }
3393 const width = this.attachment.getWidth();
3394 const height = this.attachment.getHeight();
3395 if (width != null) {
3396 image.width = width;
3397 }
3398 if (height != null) {
3399 image.height = height;
3400 }
3401 const storeKey = ["imageElement", this.attachment.id, image.src, image.width, image.height].join("/");
3402 image.dataset.trixStoreKey = storeKey;
3403 }
3404
3405 // Attachment delegate
3406
3407 attachmentDidChangeAttributes() {
3408 this.refresh(this.image);
3409 return this.refresh();
3410 }
3411 }
3412
3413 /* eslint-disable
3414 no-useless-escape,
3415 no-var,
3416 */
3417 class PieceView extends ObjectView {
3418 constructor() {
3419 super(...arguments);
3420 this.piece = this.object;
3421 this.attributes = this.piece.getAttributes();
3422 this.textConfig = this.options.textConfig;
3423 this.context = this.options.context;
3424 if (this.piece.attachment) {
3425 this.attachment = this.piece.attachment;
3426 } else {
3427 this.string = this.piece.toString();
3428 }
3429 }
3430 createNodes() {
3431 let nodes = this.attachment ? this.createAttachmentNodes() : this.createStringNodes();
3432 const element = this.createElement();
3433 if (element) {
3434 const innerElement = findInnerElement(element);
3435 Array.from(nodes).forEach(node => {
3436 innerElement.appendChild(node);
3437 });
3438 nodes = [element];
3439 }
3440 return nodes;
3441 }
3442 createAttachmentNodes() {
3443 const constructor = this.attachment.isPreviewable() ? PreviewableAttachmentView : AttachmentView;
3444 const view = this.createChildView(constructor, this.piece.attachment, {
3445 piece: this.piece
3446 });
3447 return view.getNodes();
3448 }
3449 createStringNodes() {
3450 var _this$textConfig;
3451 if ((_this$textConfig = this.textConfig) !== null && _this$textConfig !== void 0 && _this$textConfig.plaintext) {
3452 return [document.createTextNode(this.string)];
3453 } else {
3454 const nodes = [];
3455 const iterable = this.string.split("\n");
3456 for (let index = 0; index < iterable.length; index++) {
3457 const substring = iterable[index];
3458 if (index > 0) {
3459 const element = makeElement("br");
3460 nodes.push(element);
3461 }
3462 if (substring.length) {
3463 const node = document.createTextNode(this.preserveSpaces(substring));
3464 nodes.push(node);
3465 }
3466 }
3467 return nodes;
3468 }
3469 }
3470 createElement() {
3471 let element, key, value;
3472 const styles = {};
3473 for (key in this.attributes) {
3474 value = this.attributes[key];
3475 const config = getTextConfig(key);
3476 if (config) {
3477 if (config.tagName) {
3478 var innerElement;
3479 const pendingElement = makeElement(config.tagName);
3480 if (innerElement) {
3481 innerElement.appendChild(pendingElement);
3482 innerElement = pendingElement;
3483 } else {
3484 element = innerElement = pendingElement;
3485 }
3486 }
3487 if (config.styleProperty) {
3488 styles[config.styleProperty] = value;
3489 }
3490 if (config.style) {
3491 for (key in config.style) {
3492 value = config.style[key];
3493 styles[key] = value;
3494 }
3495 }
3496 }
3497 }
3498 if (Object.keys(styles).length) {
3499 if (!element) {
3500 element = makeElement("span");
3501 }
3502 for (key in styles) {
3503 value = styles[key];
3504 element.style[key] = value;
3505 }
3506 }
3507 return element;
3508 }
3509 createContainerElement() {
3510 for (const key in this.attributes) {
3511 const value = this.attributes[key];
3512 const config = getTextConfig(key);
3513 if (config) {
3514 if (config.groupTagName) {
3515 const attributes = {};
3516 attributes[key] = value;
3517 return makeElement(config.groupTagName, attributes);
3518 }
3519 }
3520 }
3521 }
3522 preserveSpaces(string) {
3523 if (this.context.isLast) {
3524 string = string.replace(/\ $/, NON_BREAKING_SPACE);
3525 }
3526 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));
3527 if (this.context.isFirst || this.context.followsWhitespace) {
3528 string = string.replace(/^\ /, NON_BREAKING_SPACE);
3529 }
3530 return string;
3531 }
3532 }
3533
3534 /* eslint-disable
3535 no-var,
3536 */
3537 class TextView extends ObjectView {
3538 constructor() {
3539 super(...arguments);
3540 this.text = this.object;
3541 this.textConfig = this.options.textConfig;
3542 }
3543 createNodes() {
3544 const nodes = [];
3545 const pieces = ObjectGroup.groupObjects(this.getPieces());
3546 const lastIndex = pieces.length - 1;
3547 for (let index = 0; index < pieces.length; index++) {
3548 const piece = pieces[index];
3549 const context = {};
3550 if (index === 0) {
3551 context.isFirst = true;
3552 }
3553 if (index === lastIndex) {
3554 context.isLast = true;
3555 }
3556 if (endsWithWhitespace(previousPiece)) {
3557 context.followsWhitespace = true;
3558 }
3559 const view = this.findOrCreateCachedChildView(PieceView, piece, {
3560 textConfig: this.textConfig,
3561 context
3562 });
3563 nodes.push(...Array.from(view.getNodes() || []));
3564 var previousPiece = piece;
3565 }
3566 return nodes;
3567 }
3568 getPieces() {
3569 return Array.from(this.text.getPieces()).filter(piece => !piece.hasAttribute("blockBreak"));
3570 }
3571 }
3572 const endsWithWhitespace = piece => /\s$/.test(piece === null || piece === void 0 ? void 0 : piece.toString());
3573
3574 const {
3575 css: css$1
3576 } = config;
3577 class BlockView extends ObjectView {
3578 constructor() {
3579 super(...arguments);
3580 this.block = this.object;
3581 this.attributes = this.block.getAttributes();
3582 }
3583 createNodes() {
3584 const comment = document.createComment("block");
3585 const nodes = [comment];
3586 if (this.block.isEmpty()) {
3587 nodes.push(makeElement("br"));
3588 } else {
3589 var _getBlockConfig;
3590 const textConfig = (_getBlockConfig = getBlockConfig(this.block.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.text;
3591 const textView = this.findOrCreateCachedChildView(TextView, this.block.text, {
3592 textConfig
3593 });
3594 nodes.push(...Array.from(textView.getNodes() || []));
3595 if (this.shouldAddExtraNewlineElement()) {
3596 nodes.push(makeElement("br"));
3597 }
3598 }
3599 if (this.attributes.length) {
3600 return nodes;
3601 } else {
3602 let attributes$1;
3603 const {
3604 tagName
3605 } = attributes.default;
3606 if (this.block.isRTL()) {
3607 attributes$1 = {
3608 dir: "rtl"
3609 };
3610 }
3611 const element = makeElement({
3612 tagName,
3613 attributes: attributes$1
3614 });
3615 nodes.forEach(node => element.appendChild(node));
3616 return [element];
3617 }
3618 }
3619 createContainerElement(depth) {
3620 const attributes = {};
3621 let className;
3622 const attributeName = this.attributes[depth];
3623 const {
3624 tagName,
3625 htmlAttributes = []
3626 } = getBlockConfig(attributeName);
3627 if (depth === 0 && this.block.isRTL()) {
3628 Object.assign(attributes, {
3629 dir: "rtl"
3630 });
3631 }
3632 if (attributeName === "attachmentGallery") {
3633 const size = this.block.getBlockBreakPosition();
3634 className = "".concat(css$1.attachmentGallery, " ").concat(css$1.attachmentGallery, "--").concat(size);
3635 }
3636 Object.entries(this.block.htmlAttributes).forEach(_ref => {
3637 let [name, value] = _ref;
3638 if (htmlAttributes.includes(name)) {
3639 attributes[name] = value;
3640 }
3641 });
3642 return makeElement({
3643 tagName,
3644 className,
3645 attributes
3646 });
3647 }
3648
3649 // A single <br> at the end of a block element has no visual representation
3650 // so add an extra one.
3651 shouldAddExtraNewlineElement() {
3652 return /\n\n$/.test(this.block.toString());
3653 }
3654 }
3655
3656 class DocumentView extends ObjectView {
3657 static render(document) {
3658 const element = makeElement("div");
3659 const view = new this(document, {
3660 element
3661 });
3662 view.render();
3663 view.sync();
3664 return element;
3665 }
3666 constructor() {
3667 super(...arguments);
3668 this.element = this.options.element;
3669 this.elementStore = new ElementStore();
3670 this.setDocument(this.object);
3671 }
3672 setDocument(document) {
3673 if (!document.isEqualTo(this.document)) {
3674 this.document = this.object = document;
3675 }
3676 }
3677 render() {
3678 this.childViews = [];
3679 this.shadowElement = makeElement("div");
3680 if (!this.document.isEmpty()) {
3681 const objects = ObjectGroup.groupObjects(this.document.getBlocks(), {
3682 asTree: true
3683 });
3684 Array.from(objects).forEach(object => {
3685 const view = this.findOrCreateCachedChildView(BlockView, object);
3686 Array.from(view.getNodes()).map(node => this.shadowElement.appendChild(node));
3687 });
3688 }
3689 }
3690 isSynced() {
3691 return elementsHaveEqualHTML(this.shadowElement, this.element);
3692 }
3693 sync() {
3694 const fragment = this.createDocumentFragmentForSync();
3695 while (this.element.lastChild) {
3696 this.element.removeChild(this.element.lastChild);
3697 }
3698 this.element.appendChild(fragment);
3699 return this.didSync();
3700 }
3701
3702 // Private
3703
3704 didSync() {
3705 this.elementStore.reset(findStoredElements(this.element));
3706 return defer(() => this.garbageCollectCachedViews());
3707 }
3708 createDocumentFragmentForSync() {
3709 const fragment = document.createDocumentFragment();
3710 Array.from(this.shadowElement.childNodes).forEach(node => {
3711 fragment.appendChild(node.cloneNode(true));
3712 });
3713 Array.from(findStoredElements(fragment)).forEach(element => {
3714 const storedElement = this.elementStore.remove(element);
3715 if (storedElement) {
3716 element.parentNode.replaceChild(storedElement, element);
3717 }
3718 });
3719 return fragment;
3720 }
3721 }
3722 const findStoredElements = element => element.querySelectorAll("[data-trix-store-key]");
3723 const elementsHaveEqualHTML = (element, otherElement) => ignoreSpaces(element.innerHTML) === ignoreSpaces(otherElement.innerHTML);
3724 const ignoreSpaces = html => html.replace(/&nbsp;/g, " ");
3725
3726 function _AsyncGenerator(e) {
3727 var r, t;
3728 function resume(r, t) {
3729 try {
3730 var n = e[r](t),
3731 o = n.value,
3732 u = o instanceof _OverloadYield;
3733 Promise.resolve(u ? o.v : o).then(function (t) {
3734 if (u) {
3735 var i = "return" === r ? "return" : "next";
3736 if (!o.k || t.done) return resume(i, t);
3737 t = e[i](t).value;
3738 }
3739 settle(n.done ? "return" : "normal", t);
3740 }, function (e) {
3741 resume("throw", e);
3742 });
3743 } catch (e) {
3744 settle("throw", e);
3745 }
3746 }
3747 function settle(e, n) {
3748 switch (e) {
3749 case "return":
3750 r.resolve({
3751 value: n,
3752 done: !0
3753 });
3754 break;
3755 case "throw":
3756 r.reject(n);
3757 break;
3758 default:
3759 r.resolve({
3760 value: n,
3761 done: !1
3762 });
3763 }
3764 (r = r.next) ? resume(r.key, r.arg) : t = null;
3765 }
3766 this._invoke = function (e, n) {
3767 return new Promise(function (o, u) {
3768 var i = {
3769 key: e,
3770 arg: n,
3771 resolve: o,
3772 reject: u,
3773 next: null
3774 };
3775 t ? t = t.next = i : (r = t = i, resume(e, n));
3776 });
3777 }, "function" != typeof e.return && (this.return = void 0);
3778 }
3779 _AsyncGenerator.prototype["function" == typeof Symbol && Symbol.asyncIterator || "@@asyncIterator"] = function () {
3780 return this;
3781 }, _AsyncGenerator.prototype.next = function (e) {
3782 return this._invoke("next", e);
3783 }, _AsyncGenerator.prototype.throw = function (e) {
3784 return this._invoke("throw", e);
3785 }, _AsyncGenerator.prototype.return = function (e) {
3786 return this._invoke("return", e);
3787 };
3788 function _OverloadYield(t, e) {
3789 this.v = t, this.k = e;
3790 }
3791 function old_createMetadataMethodsForProperty(e, t, a, r) {
3792 return {
3793 getMetadata: function (o) {
3794 old_assertNotFinished(r, "getMetadata"), old_assertMetadataKey(o);
3795 var i = e[o];
3796 if (void 0 !== i) if (1 === t) {
3797 var n = i.public;
3798 if (void 0 !== n) return n[a];
3799 } else if (2 === t) {
3800 var l = i.private;
3801 if (void 0 !== l) return l.get(a);
3802 } else if (Object.hasOwnProperty.call(i, "constructor")) return i.constructor;
3803 },
3804 setMetadata: function (o, i) {
3805 old_assertNotFinished(r, "setMetadata"), old_assertMetadataKey(o);
3806 var n = e[o];
3807 if (void 0 === n && (n = e[o] = {}), 1 === t) {
3808 var l = n.public;
3809 void 0 === l && (l = n.public = {}), l[a] = i;
3810 } else if (2 === t) {
3811 var s = n.priv;
3812 void 0 === s && (s = n.private = new Map()), s.set(a, i);
3813 } else n.constructor = i;
3814 }
3815 };
3816 }
3817 function old_convertMetadataMapToFinal(e, t) {
3818 var a = e[Symbol.metadata || Symbol.for("Symbol.metadata")],
3819 r = Object.getOwnPropertySymbols(t);
3820 if (0 !== r.length) {
3821 for (var o = 0; o < r.length; o++) {
3822 var i = r[o],
3823 n = t[i],
3824 l = a ? a[i] : null,
3825 s = n.public,
3826 c = l ? l.public : null;
3827 s && c && Object.setPrototypeOf(s, c);
3828 var d = n.private;
3829 if (d) {
3830 var u = Array.from(d.values()),
3831 f = l ? l.private : null;
3832 f && (u = u.concat(f)), n.private = u;
3833 }
3834 l && Object.setPrototypeOf(n, l);
3835 }
3836 a && Object.setPrototypeOf(t, a), e[Symbol.metadata || Symbol.for("Symbol.metadata")] = t;
3837 }
3838 }
3839 function old_createAddInitializerMethod(e, t) {
3840 return function (a) {
3841 old_assertNotFinished(t, "addInitializer"), old_assertCallable(a, "An initializer"), e.push(a);
3842 };
3843 }
3844 function old_memberDec(e, t, a, r, o, i, n, l, s) {
3845 var c;
3846 switch (i) {
3847 case 1:
3848 c = "accessor";
3849 break;
3850 case 2:
3851 c = "method";
3852 break;
3853 case 3:
3854 c = "getter";
3855 break;
3856 case 4:
3857 c = "setter";
3858 break;
3859 default:
3860 c = "field";
3861 }
3862 var d,
3863 u,
3864 f = {
3865 kind: c,
3866 name: l ? "#" + t : t,
3867 isStatic: n,
3868 isPrivate: l
3869 },
3870 p = {
3871 v: !1
3872 };
3873 if (0 !== i && (f.addInitializer = old_createAddInitializerMethod(o, p)), l) {
3874 d = 2, u = Symbol(t);
3875 var v = {};
3876 0 === i ? (v.get = a.get, v.set = a.set) : 2 === i ? v.get = function () {
3877 return a.value;
3878 } : (1 !== i && 3 !== i || (v.get = function () {
3879 return a.get.call(this);
3880 }), 1 !== i && 4 !== i || (v.set = function (e) {
3881 a.set.call(this, e);
3882 })), f.access = v;
3883 } else d = 1, u = t;
3884 try {
3885 return e(s, Object.assign(f, old_createMetadataMethodsForProperty(r, d, u, p)));
3886 } finally {
3887 p.v = !0;
3888 }
3889 }
3890 function old_assertNotFinished(e, t) {
3891 if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
3892 }
3893 function old_assertMetadataKey(e) {
3894 if ("symbol" != typeof e) throw new TypeError("Metadata keys must be symbols, received: " + e);
3895 }
3896 function old_assertCallable(e, t) {
3897 if ("function" != typeof e) throw new TypeError(t + " must be a function");
3898 }
3899 function old_assertValidReturnValue(e, t) {
3900 var a = typeof t;
3901 if (1 === e) {
3902 if ("object" !== a || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
3903 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");
3904 } else if ("function" !== a) {
3905 var r;
3906 throw r = 0 === e ? "field" : 10 === e ? "class" : "method", new TypeError(r + " decorators must return a function or void 0");
3907 }
3908 }
3909 function old_getInit(e) {
3910 var t;
3911 return null == (t = e.init) && (t = e.initializer) && "undefined" != typeof console && console.warn(".initializer has been renamed to .init as of March 2022"), t;
3912 }
3913 function old_applyMemberDec(e, t, a, r, o, i, n, l, s) {
3914 var c,
3915 d,
3916 u,
3917 f,
3918 p,
3919 v,
3920 h = a[0];
3921 if (n ? c = 0 === o || 1 === o ? {
3922 get: a[3],
3923 set: a[4]
3924 } : 3 === o ? {
3925 get: a[3]
3926 } : 4 === o ? {
3927 set: a[3]
3928 } : {
3929 value: a[3]
3930 } : 0 !== o && (c = Object.getOwnPropertyDescriptor(t, r)), 1 === o ? u = {
3931 get: c.get,
3932 set: c.set
3933 } : 2 === o ? u = c.value : 3 === o ? u = c.get : 4 === o && (u = c.set), "function" == typeof h) void 0 !== (f = old_memberDec(h, r, c, l, s, o, i, n, u)) && (old_assertValidReturnValue(o, f), 0 === o ? d = f : 1 === o ? (d = old_getInit(f), p = f.get || u.get, v = f.set || u.set, u = {
3934 get: p,
3935 set: v
3936 }) : u = f);else for (var y = h.length - 1; y >= 0; y--) {
3937 var b;
3938 if (void 0 !== (f = old_memberDec(h[y], r, c, l, s, o, i, n, u))) old_assertValidReturnValue(o, f), 0 === o ? b = f : 1 === o ? (b = old_getInit(f), p = f.get || u.get, v = f.set || u.set, u = {
3939 get: p,
3940 set: v
3941 }) : u = f, void 0 !== b && (void 0 === d ? d = b : "function" == typeof d ? d = [d, b] : d.push(b));
3942 }
3943 if (0 === o || 1 === o) {
3944 if (void 0 === d) d = function (e, t) {
3945 return t;
3946 };else if ("function" != typeof d) {
3947 var g = d;
3948 d = function (e, t) {
3949 for (var a = t, r = 0; r < g.length; r++) a = g[r].call(e, a);
3950 return a;
3951 };
3952 } else {
3953 var m = d;
3954 d = function (e, t) {
3955 return m.call(e, t);
3956 };
3957 }
3958 e.push(d);
3959 }
3960 0 !== o && (1 === o ? (c.get = u.get, c.set = u.set) : 2 === o ? c.value = u : 3 === o ? c.get = u : 4 === o && (c.set = u), n ? 1 === o ? (e.push(function (e, t) {
3961 return u.get.call(e, t);
3962 }), e.push(function (e, t) {
3963 return u.set.call(e, t);
3964 })) : 2 === o ? e.push(u) : e.push(function (e, t) {
3965 return u.call(e, t);
3966 }) : Object.defineProperty(t, r, c));
3967 }
3968 function old_applyMemberDecs(e, t, a, r, o) {
3969 for (var i, n, l = new Map(), s = new Map(), c = 0; c < o.length; c++) {
3970 var d = o[c];
3971 if (Array.isArray(d)) {
3972 var u,
3973 f,
3974 p,
3975 v = d[1],
3976 h = d[2],
3977 y = d.length > 3,
3978 b = v >= 5;
3979 if (b ? (u = t, f = r, 0 !== (v -= 5) && (p = n = n || [])) : (u = t.prototype, f = a, 0 !== v && (p = i = i || [])), 0 !== v && !y) {
3980 var g = b ? s : l,
3981 m = g.get(h) || 0;
3982 if (!0 === m || 3 === m && 4 !== v || 4 === m && 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: " + h);
3983 !m && v > 2 ? g.set(h, v) : g.set(h, !0);
3984 }
3985 old_applyMemberDec(e, u, d, h, v, b, y, f, p);
3986 }
3987 }
3988 old_pushInitializers(e, i), old_pushInitializers(e, n);
3989 }
3990 function old_pushInitializers(e, t) {
3991 t && e.push(function (e) {
3992 for (var a = 0; a < t.length; a++) t[a].call(e);
3993 return e;
3994 });
3995 }
3996 function old_applyClassDecs(e, t, a, r) {
3997 if (r.length > 0) {
3998 for (var o = [], i = t, n = t.name, l = r.length - 1; l >= 0; l--) {
3999 var s = {
4000 v: !1
4001 };
4002 try {
4003 var c = Object.assign({
4004 kind: "class",
4005 name: n,
4006 addInitializer: old_createAddInitializerMethod(o, s)
4007 }, old_createMetadataMethodsForProperty(a, 0, n, s)),
4008 d = r[l](i, c);
4009 } finally {
4010 s.v = !0;
4011 }
4012 void 0 !== d && (old_assertValidReturnValue(10, d), i = d);
4013 }
4014 e.push(i, function () {
4015 for (var e = 0; e < o.length; e++) o[e].call(i);
4016 });
4017 }
4018 }
4019 function _applyDecs(e, t, a) {
4020 var r = [],
4021 o = {},
4022 i = {};
4023 return old_applyMemberDecs(r, e, i, o, t), old_convertMetadataMapToFinal(e.prototype, i), old_applyClassDecs(r, e, o, a), old_convertMetadataMapToFinal(e, o), r;
4024 }
4025 function applyDecs2203Factory() {
4026 function createAddInitializerMethod(e, t) {
4027 return function (r) {
4028 !function (e, t) {
4029 if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
4030 }(t, "addInitializer"), assertCallable(r, "An initializer"), e.push(r);
4031 };
4032 }
4033 function memberDec(e, t, r, a, n, i, s, o) {
4034 var c;
4035 switch (n) {
4036 case 1:
4037 c = "accessor";
4038 break;
4039 case 2:
4040 c = "method";
4041 break;
4042 case 3:
4043 c = "getter";
4044 break;
4045 case 4:
4046 c = "setter";
4047 break;
4048 default:
4049 c = "field";
4050 }
4051 var l,
4052 u,
4053 f = {
4054 kind: c,
4055 name: s ? "#" + t : t,
4056 static: i,
4057 private: s
4058 },
4059 p = {
4060 v: !1
4061 };
4062 0 !== n && (f.addInitializer = createAddInitializerMethod(a, p)), 0 === n ? s ? (l = r.get, u = r.set) : (l = function () {
4063 return this[t];
4064 }, u = function (e) {
4065 this[t] = e;
4066 }) : 2 === n ? l = function () {
4067 return r.value;
4068 } : (1 !== n && 3 !== n || (l = function () {
4069 return r.get.call(this);
4070 }), 1 !== n && 4 !== n || (u = function (e) {
4071 r.set.call(this, e);
4072 })), f.access = l && u ? {
4073 get: l,
4074 set: u
4075 } : l ? {
4076 get: l
4077 } : {
4078 set: u
4079 };
4080 try {
4081 return e(o, f);
4082 } finally {
4083 p.v = !0;
4084 }
4085 }
4086 function assertCallable(e, t) {
4087 if ("function" != typeof e) throw new TypeError(t + " must be a function");
4088 }
4089 function assertValidReturnValue(e, t) {
4090 var r = typeof t;
4091 if (1 === e) {
4092 if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
4093 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");
4094 } else if ("function" !== r) {
4095 var a;
4096 throw a = 0 === e ? "field" : 10 === e ? "class" : "method", new TypeError(a + " decorators must return a function or void 0");
4097 }
4098 }
4099 function applyMemberDec(e, t, r, a, n, i, s, o) {
4100 var c,
4101 l,
4102 u,
4103 f,
4104 p,
4105 d,
4106 h = r[0];
4107 if (s ? c = 0 === n || 1 === n ? {
4108 get: r[3],
4109 set: r[4]
4110 } : 3 === n ? {
4111 get: r[3]
4112 } : 4 === n ? {
4113 set: r[3]
4114 } : {
4115 value: r[3]
4116 } : 0 !== n && (c = Object.getOwnPropertyDescriptor(t, a)), 1 === n ? u = {
4117 get: c.get,
4118 set: c.set
4119 } : 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 = {
4120 get: p,
4121 set: d
4122 }) : u = f);else for (var v = h.length - 1; v >= 0; v--) {
4123 var g;
4124 if (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 = {
4125 get: p,
4126 set: d
4127 }) : u = f, void 0 !== g && (void 0 === l ? l = g : "function" == typeof l ? l = [l, g] : l.push(g));
4128 }
4129 if (0 === n || 1 === n) {
4130 if (void 0 === l) l = function (e, t) {
4131 return t;
4132 };else if ("function" != typeof l) {
4133 var y = l;
4134 l = function (e, t) {
4135 for (var r = t, a = 0; a < y.length; a++) r = y[a].call(e, r);
4136 return r;
4137 };
4138 } else {
4139 var m = l;
4140 l = function (e, t) {
4141 return m.call(e, t);
4142 };
4143 }
4144 e.push(l);
4145 }
4146 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) {
4147 return u.get.call(e, t);
4148 }), e.push(function (e, t) {
4149 return u.set.call(e, t);
4150 })) : 2 === n ? e.push(u) : e.push(function (e, t) {
4151 return u.call(e, t);
4152 }) : Object.defineProperty(t, a, c));
4153 }
4154 function pushInitializers(e, t) {
4155 t && e.push(function (e) {
4156 for (var r = 0; r < t.length; r++) t[r].call(e);
4157 return e;
4158 });
4159 }
4160 return function (e, t, r) {
4161 var a = [];
4162 return function (e, t, r) {
4163 for (var a, n, i = new Map(), s = new Map(), o = 0; o < r.length; o++) {
4164 var c = r[o];
4165 if (Array.isArray(c)) {
4166 var l,
4167 u,
4168 f = c[1],
4169 p = c[2],
4170 d = c.length > 3,
4171 h = f >= 5;
4172 if (h ? (l = t, 0 != (f -= 5) && (u = n = n || [])) : (l = t.prototype, 0 !== f && (u = a = a || [])), 0 !== f && !d) {
4173 var v = h ? s : i,
4174 g = v.get(p) || 0;
4175 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);
4176 !g && f > 2 ? v.set(p, f) : v.set(p, !0);
4177 }
4178 applyMemberDec(e, l, c, p, f, h, d, u);
4179 }
4180 }
4181 pushInitializers(e, a), pushInitializers(e, n);
4182 }(a, e, t), function (e, t, r) {
4183 if (r.length > 0) {
4184 for (var a = [], n = t, i = t.name, s = r.length - 1; s >= 0; s--) {
4185 var o = {
4186 v: !1
4187 };
4188 try {
4189 var c = r[s](n, {
4190 kind: "class",
4191 name: i,
4192 addInitializer: createAddInitializerMethod(a, o)
4193 });
4194 } finally {
4195 o.v = !0;
4196 }
4197 void 0 !== c && (assertValidReturnValue(10, c), n = c);
4198 }
4199 e.push(n, function () {
4200 for (var e = 0; e < a.length; e++) a[e].call(n);
4201 });
4202 }
4203 }(a, e, r), a;
4204 };
4205 }
4206 var applyDecs2203Impl;
4207 function _applyDecs2203(e, t, r) {
4208 return (applyDecs2203Impl = applyDecs2203Impl || applyDecs2203Factory())(e, t, r);
4209 }
4210 function applyDecs2203RFactory() {
4211 function createAddInitializerMethod(e, t) {
4212 return function (r) {
4213 !function (e, t) {
4214 if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
4215 }(t, "addInitializer"), assertCallable(r, "An initializer"), e.push(r);
4216 };
4217 }
4218 function memberDec(e, t, r, n, a, i, s, o) {
4219 var c;
4220 switch (a) {
4221 case 1:
4222 c = "accessor";
4223 break;
4224 case 2:
4225 c = "method";
4226 break;
4227 case 3:
4228 c = "getter";
4229 break;
4230 case 4:
4231 c = "setter";
4232 break;
4233 default:
4234 c = "field";
4235 }
4236 var l,
4237 u,
4238 f = {
4239 kind: c,
4240 name: s ? "#" + t : t,
4241 static: i,
4242 private: s
4243 },
4244 p = {
4245 v: !1
4246 };
4247 0 !== a && (f.addInitializer = createAddInitializerMethod(n, p)), 0 === a ? s ? (l = r.get, u = r.set) : (l = function () {
4248 return this[t];
4249 }, u = function (e) {
4250 this[t] = e;
4251 }) : 2 === a ? l = function () {
4252 return r.value;
4253 } : (1 !== a && 3 !== a || (l = function () {
4254 return r.get.call(this);
4255 }), 1 !== a && 4 !== a || (u = function (e) {
4256 r.set.call(this, e);
4257 })), f.access = l && u ? {
4258 get: l,
4259 set: u
4260 } : l ? {
4261 get: l
4262 } : {
4263 set: u
4264 };
4265 try {
4266 return e(o, f);
4267 } finally {
4268 p.v = !0;
4269 }
4270 }
4271 function assertCallable(e, t) {
4272 if ("function" != typeof e) throw new TypeError(t + " must be a function");
4273 }
4274 function assertValidReturnValue(e, t) {
4275 var r = typeof t;
4276 if (1 === e) {
4277 if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
4278 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");
4279 } else if ("function" !== r) {
4280 var n;
4281 throw n = 0 === e ? "field" : 10 === e ? "class" : "method", new TypeError(n + " decorators must return a function or void 0");
4282 }
4283 }
4284 function applyMemberDec(e, t, r, n, a, i, s, o) {
4285 var c,
4286 l,
4287 u,
4288 f,
4289 p,
4290 d,
4291 h = r[0];
4292 if (s ? c = 0 === a || 1 === a ? {
4293 get: r[3],
4294 set: r[4]
4295 } : 3 === a ? {
4296 get: r[3]
4297 } : 4 === a ? {
4298 set: r[3]
4299 } : {
4300 value: r[3]
4301 } : 0 !== a && (c = Object.getOwnPropertyDescriptor(t, n)), 1 === a ? u = {
4302 get: c.get,
4303 set: c.set
4304 } : 2 === a ? u = c.value : 3 === a ? u = c.get : 4 === a && (u = c.set), "function" == typeof h) void 0 !== (f = memberDec(h, n, c, o, a, i, s, u)) && (assertValidReturnValue(a, f), 0 === a ? l = f : 1 === a ? (l = f.init, p = f.get || u.get, d = f.set || u.set, u = {
4305 get: p,
4306 set: d
4307 }) : u = f);else for (var v = h.length - 1; v >= 0; v--) {
4308 var g;
4309 if (void 0 !== (f = memberDec(h[v], n, c, o, a, i, s, u))) assertValidReturnValue(a, f), 0 === a ? g = f : 1 === a ? (g = f.init, p = f.get || u.get, d = f.set || u.set, u = {
4310 get: p,
4311 set: d
4312 }) : u = f, void 0 !== g && (void 0 === l ? l = g : "function" == typeof l ? l = [l, g] : l.push(g));
4313 }
4314 if (0 === a || 1 === a) {
4315 if (void 0 === l) l = function (e, t) {
4316 return t;
4317 };else if ("function" != typeof l) {
4318 var y = l;
4319 l = function (e, t) {
4320 for (var r = t, n = 0; n < y.length; n++) r = y[n].call(e, r);
4321 return r;
4322 };
4323 } else {
4324 var m = l;
4325 l = function (e, t) {
4326 return m.call(e, t);
4327 };
4328 }
4329 e.push(l);
4330 }
4331 0 !== a && (1 === a ? (c.get = u.get, c.set = u.set) : 2 === a ? c.value = u : 3 === a ? c.get = u : 4 === a && (c.set = u), s ? 1 === a ? (e.push(function (e, t) {
4332 return u.get.call(e, t);
4333 }), e.push(function (e, t) {
4334 return u.set.call(e, t);
4335 })) : 2 === a ? e.push(u) : e.push(function (e, t) {
4336 return u.call(e, t);
4337 }) : Object.defineProperty(t, n, c));
4338 }
4339 function applyMemberDecs(e, t) {
4340 for (var r, n, a = [], i = new Map(), s = new Map(), o = 0; o < t.length; o++) {
4341 var c = t[o];
4342 if (Array.isArray(c)) {
4343 var l,
4344 u,
4345 f = c[1],
4346 p = c[2],
4347 d = c.length > 3,
4348 h = f >= 5;
4349 if (h ? (l = e, 0 !== (f -= 5) && (u = n = n || [])) : (l = e.prototype, 0 !== f && (u = r = r || [])), 0 !== f && !d) {
4350 var v = h ? s : i,
4351 g = v.get(p) || 0;
4352 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);
4353 !g && f > 2 ? v.set(p, f) : v.set(p, !0);
4354 }
4355 applyMemberDec(a, l, c, p, f, h, d, u);
4356 }
4357 }
4358 return pushInitializers(a, r), pushInitializers(a, n), a;
4359 }
4360 function pushInitializers(e, t) {
4361 t && e.push(function (e) {
4362 for (var r = 0; r < t.length; r++) t[r].call(e);
4363 return e;
4364 });
4365 }
4366 return function (e, t, r) {
4367 return {
4368 e: applyMemberDecs(e, t),
4369 get c() {
4370 return function (e, t) {
4371 if (t.length > 0) {
4372 for (var r = [], n = e, a = e.name, i = t.length - 1; i >= 0; i--) {
4373 var s = {
4374 v: !1
4375 };
4376 try {
4377 var o = t[i](n, {
4378 kind: "class",
4379 name: a,
4380 addInitializer: createAddInitializerMethod(r, s)
4381 });
4382 } finally {
4383 s.v = !0;
4384 }
4385 void 0 !== o && (assertValidReturnValue(10, o), n = o);
4386 }
4387 return [n, function () {
4388 for (var e = 0; e < r.length; e++) r[e].call(n);
4389 }];
4390 }
4391 }(e, r);
4392 }
4393 };
4394 };
4395 }
4396 function _applyDecs2203R(e, t, r) {
4397 return (_applyDecs2203R = applyDecs2203RFactory())(e, t, r);
4398 }
4399 function applyDecs2301Factory() {
4400 function createAddInitializerMethod(e, t) {
4401 return function (r) {
4402 !function (e, t) {
4403 if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
4404 }(t, "addInitializer"), assertCallable(r, "An initializer"), e.push(r);
4405 };
4406 }
4407 function assertInstanceIfPrivate(e, t) {
4408 if (!e(t)) throw new TypeError("Attempted to access private element on non-instance");
4409 }
4410 function memberDec(e, t, r, n, a, i, s, o, c) {
4411 var u;
4412 switch (a) {
4413 case 1:
4414 u = "accessor";
4415 break;
4416 case 2:
4417 u = "method";
4418 break;
4419 case 3:
4420 u = "getter";
4421 break;
4422 case 4:
4423 u = "setter";
4424 break;
4425 default:
4426 u = "field";
4427 }
4428 var l,
4429 f,
4430 p = {
4431 kind: u,
4432 name: s ? "#" + t : t,
4433 static: i,
4434 private: s
4435 },
4436 d = {
4437 v: !1
4438 };
4439 if (0 !== a && (p.addInitializer = createAddInitializerMethod(n, d)), s || 0 !== a && 2 !== a) {
4440 if (2 === a) l = function (e) {
4441 return assertInstanceIfPrivate(c, e), r.value;
4442 };else {
4443 var h = 0 === a || 1 === a;
4444 (h || 3 === a) && (l = s ? function (e) {
4445 return assertInstanceIfPrivate(c, e), r.get.call(e);
4446 } : function (e) {
4447 return r.get.call(e);
4448 }), (h || 4 === a) && (f = s ? function (e, t) {
4449 assertInstanceIfPrivate(c, e), r.set.call(e, t);
4450 } : function (e, t) {
4451 r.set.call(e, t);
4452 });
4453 }
4454 } else l = function (e) {
4455 return e[t];
4456 }, 0 === a && (f = function (e, r) {
4457 e[t] = r;
4458 });
4459 var v = s ? c.bind() : function (e) {
4460 return t in e;
4461 };
4462 p.access = l && f ? {
4463 get: l,
4464 set: f,
4465 has: v
4466 } : l ? {
4467 get: l,
4468 has: v
4469 } : {
4470 set: f,
4471 has: v
4472 };
4473 try {
4474 return e(o, p);
4475 } finally {
4476 d.v = !0;
4477 }
4478 }
4479 function assertCallable(e, t) {
4480 if ("function" != typeof e) throw new TypeError(t + " must be a function");
4481 }
4482 function assertValidReturnValue(e, t) {
4483 var r = typeof t;
4484 if (1 === e) {
4485 if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
4486 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");
4487 } else if ("function" !== r) {
4488 var n;
4489 throw n = 0 === e ? "field" : 10 === e ? "class" : "method", new TypeError(n + " decorators must return a function or void 0");
4490 }
4491 }
4492 function curryThis2(e) {
4493 return function (t) {
4494 e(this, t);
4495 };
4496 }
4497 function applyMemberDec(e, t, r, n, a, i, s, o, c) {
4498 var u,
4499 l,
4500 f,
4501 p,
4502 d,
4503 h,
4504 v,
4505 g = r[0];
4506 if (s ? u = 0 === a || 1 === a ? {
4507 get: (p = r[3], function () {
4508 return p(this);
4509 }),
4510 set: curryThis2(r[4])
4511 } : 3 === a ? {
4512 get: r[3]
4513 } : 4 === a ? {
4514 set: r[3]
4515 } : {
4516 value: r[3]
4517 } : 0 !== a && (u = Object.getOwnPropertyDescriptor(t, n)), 1 === a ? f = {
4518 get: u.get,
4519 set: u.set
4520 } : 2 === a ? f = u.value : 3 === a ? f = u.get : 4 === a && (f = u.set), "function" == typeof g) void 0 !== (d = memberDec(g, n, u, o, a, i, s, f, c)) && (assertValidReturnValue(a, d), 0 === a ? l = d : 1 === a ? (l = d.init, h = d.get || f.get, v = d.set || f.set, f = {
4521 get: h,
4522 set: v
4523 }) : f = d);else for (var y = g.length - 1; y >= 0; y--) {
4524 var m;
4525 if (void 0 !== (d = memberDec(g[y], n, u, o, a, i, s, f, c))) assertValidReturnValue(a, d), 0 === a ? m = d : 1 === a ? (m = d.init, h = d.get || f.get, v = d.set || f.set, f = {
4526 get: h,
4527 set: v
4528 }) : f = d, void 0 !== m && (void 0 === l ? l = m : "function" == typeof l ? l = [l, m] : l.push(m));
4529 }
4530 if (0 === a || 1 === a) {
4531 if (void 0 === l) l = function (e, t) {
4532 return t;
4533 };else if ("function" != typeof l) {
4534 var b = l;
4535 l = function (e, t) {
4536 for (var r = t, n = 0; n < b.length; n++) r = b[n].call(e, r);
4537 return r;
4538 };
4539 } else {
4540 var I = l;
4541 l = function (e, t) {
4542 return I.call(e, t);
4543 };
4544 }
4545 e.push(l);
4546 }
4547 0 !== a && (1 === a ? (u.get = f.get, u.set = f.set) : 2 === a ? u.value = f : 3 === a ? u.get = f : 4 === a && (u.set = f), s ? 1 === a ? (e.push(function (e, t) {
4548 return f.get.call(e, t);
4549 }), e.push(function (e, t) {
4550 return f.set.call(e, t);
4551 })) : 2 === a ? e.push(f) : e.push(function (e, t) {
4552 return f.call(e, t);
4553 }) : Object.defineProperty(t, n, u));
4554 }
4555 function applyMemberDecs(e, t, r) {
4556 for (var n, a, i, s = [], o = new Map(), c = new Map(), u = 0; u < t.length; u++) {
4557 var l = t[u];
4558 if (Array.isArray(l)) {
4559 var f,
4560 p,
4561 d = l[1],
4562 h = l[2],
4563 v = l.length > 3,
4564 g = d >= 5,
4565 y = r;
4566 if (g ? (f = e, 0 !== (d -= 5) && (p = a = a || []), v && !i && (i = function (t) {
4567 return _checkInRHS(t) === e;
4568 }), y = i) : (f = e.prototype, 0 !== d && (p = n = n || [])), 0 !== d && !v) {
4569 var m = g ? c : o,
4570 b = m.get(h) || 0;
4571 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);
4572 !b && d > 2 ? m.set(h, d) : m.set(h, !0);
4573 }
4574 applyMemberDec(s, f, l, h, d, g, v, p, y);
4575 }
4576 }
4577 return pushInitializers(s, n), pushInitializers(s, a), s;
4578 }
4579 function pushInitializers(e, t) {
4580 t && e.push(function (e) {
4581 for (var r = 0; r < t.length; r++) t[r].call(e);
4582 return e;
4583 });
4584 }
4585 return function (e, t, r, n) {
4586 return {
4587 e: applyMemberDecs(e, t, n),
4588 get c() {
4589 return function (e, t) {
4590 if (t.length > 0) {
4591 for (var r = [], n = e, a = e.name, i = t.length - 1; i >= 0; i--) {
4592 var s = {
4593 v: !1
4594 };
4595 try {
4596 var o = t[i](n, {
4597 kind: "class",
4598 name: a,
4599 addInitializer: createAddInitializerMethod(r, s)
4600 });
4601 } finally {
4602 s.v = !0;
4603 }
4604 void 0 !== o && (assertValidReturnValue(10, o), n = o);
4605 }
4606 return [n, function () {
4607 for (var e = 0; e < r.length; e++) r[e].call(n);
4608 }];
4609 }
4610 }(e, r);
4611 }
4612 };
4613 };
4614 }
4615 function _applyDecs2301(e, t, r, n) {
4616 return (_applyDecs2301 = applyDecs2301Factory())(e, t, r, n);
4617 }
4618 function createAddInitializerMethod(e, t) {
4619 return function (r) {
4620 assertNotFinished(t, "addInitializer"), assertCallable(r, "An initializer"), e.push(r);
4621 };
4622 }
4623 function assertInstanceIfPrivate(e, t) {
4624 if (!e(t)) throw new TypeError("Attempted to access private element on non-instance");
4625 }
4626 function memberDec(e, t, r, a, n, i, s, o, c, l, u) {
4627 var f;
4628 switch (i) {
4629 case 1:
4630 f = "accessor";
4631 break;
4632 case 2:
4633 f = "method";
4634 break;
4635 case 3:
4636 f = "getter";
4637 break;
4638 case 4:
4639 f = "setter";
4640 break;
4641 default:
4642 f = "field";
4643 }
4644 var d,
4645 p,
4646 h = {
4647 kind: f,
4648 name: o ? "#" + r : r,
4649 static: s,
4650 private: o,
4651 metadata: u
4652 },
4653 v = {
4654 v: !1
4655 };
4656 if (0 !== i && (h.addInitializer = createAddInitializerMethod(n, v)), o || 0 !== i && 2 !== i) {
4657 if (2 === i) d = function (e) {
4658 return assertInstanceIfPrivate(l, e), a.value;
4659 };else {
4660 var y = 0 === i || 1 === i;
4661 (y || 3 === i) && (d = o ? function (e) {
4662 return assertInstanceIfPrivate(l, e), a.get.call(e);
4663 } : function (e) {
4664 return a.get.call(e);
4665 }), (y || 4 === i) && (p = o ? function (e, t) {
4666 assertInstanceIfPrivate(l, e), a.set.call(e, t);
4667 } : function (e, t) {
4668 a.set.call(e, t);
4669 });
4670 }
4671 } else d = function (e) {
4672 return e[r];
4673 }, 0 === i && (p = function (e, t) {
4674 e[r] = t;
4675 });
4676 var m = o ? l.bind() : function (e) {
4677 return r in e;
4678 };
4679 h.access = d && p ? {
4680 get: d,
4681 set: p,
4682 has: m
4683 } : d ? {
4684 get: d,
4685 has: m
4686 } : {
4687 set: p,
4688 has: m
4689 };
4690 try {
4691 return e.call(t, c, h);
4692 } finally {
4693 v.v = !0;
4694 }
4695 }
4696 function assertNotFinished(e, t) {
4697 if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
4698 }
4699 function assertCallable(e, t) {
4700 if ("function" != typeof e) throw new TypeError(t + " must be a function");
4701 }
4702 function assertValidReturnValue(e, t) {
4703 var r = typeof t;
4704 if (1 === e) {
4705 if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
4706 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");
4707 } else if ("function" !== r) {
4708 var a;
4709 throw a = 0 === e ? "field" : 5 === e ? "class" : "method", new TypeError(a + " decorators must return a function or void 0");
4710 }
4711 }
4712 function curryThis1(e) {
4713 return function () {
4714 return e(this);
4715 };
4716 }
4717 function curryThis2(e) {
4718 return function (t) {
4719 e(this, t);
4720 };
4721 }
4722 function applyMemberDec(e, t, r, a, n, i, s, o, c, l, u) {
4723 var f,
4724 d,
4725 p,
4726 h,
4727 v,
4728 y,
4729 m = r[0];
4730 a || Array.isArray(m) || (m = [m]), o ? f = 0 === i || 1 === i ? {
4731 get: curryThis1(r[3]),
4732 set: curryThis2(r[4])
4733 } : 3 === i ? {
4734 get: r[3]
4735 } : 4 === i ? {
4736 set: r[3]
4737 } : {
4738 value: r[3]
4739 } : 0 !== i && (f = Object.getOwnPropertyDescriptor(t, n)), 1 === i ? p = {
4740 get: f.get,
4741 set: f.set
4742 } : 2 === i ? p = f.value : 3 === i ? p = f.get : 4 === i && (p = f.set);
4743 for (var g = a ? 2 : 1, b = m.length - 1; b >= 0; b -= g) {
4744 var I;
4745 if (void 0 !== (h = memberDec(m[b], a ? m[b - 1] : void 0, n, f, c, i, s, o, p, l, u))) assertValidReturnValue(i, h), 0 === i ? I = h : 1 === i ? (I = h.init, v = h.get || p.get, y = h.set || p.set, p = {
4746 get: v,
4747 set: y
4748 }) : p = h, void 0 !== I && (void 0 === d ? d = I : "function" == typeof d ? d = [d, I] : d.push(I));
4749 }
4750 if (0 === i || 1 === i) {
4751 if (void 0 === d) d = function (e, t) {
4752 return t;
4753 };else if ("function" != typeof d) {
4754 var w = d;
4755 d = function (e, t) {
4756 for (var r = t, a = w.length - 1; a >= 0; a--) r = w[a].call(e, r);
4757 return r;
4758 };
4759 } else {
4760 var M = d;
4761 d = function (e, t) {
4762 return M.call(e, t);
4763 };
4764 }
4765 e.push(d);
4766 }
4767 0 !== i && (1 === i ? (f.get = p.get, f.set = p.set) : 2 === i ? f.value = p : 3 === i ? f.get = p : 4 === i && (f.set = p), o ? 1 === i ? (e.push(function (e, t) {
4768 return p.get.call(e, t);
4769 }), e.push(function (e, t) {
4770 return p.set.call(e, t);
4771 })) : 2 === i ? e.push(p) : e.push(function (e, t) {
4772 return p.call(e, t);
4773 }) : Object.defineProperty(t, n, f));
4774 }
4775 function applyMemberDecs(e, t, r, a) {
4776 for (var n, i, s, o = [], c = new Map(), l = new Map(), u = 0; u < t.length; u++) {
4777 var f = t[u];
4778 if (Array.isArray(f)) {
4779 var d,
4780 p,
4781 h = f[1],
4782 v = f[2],
4783 y = f.length > 3,
4784 m = 16 & h,
4785 g = !!(8 & h),
4786 b = r;
4787 if (h &= 7, g ? (d = e, 0 !== h && (p = i = i || []), y && !s && (s = function (t) {
4788 return _checkInRHS(t) === e;
4789 }), b = s) : (d = e.prototype, 0 !== h && (p = n = n || [])), 0 !== h && !y) {
4790 var I = g ? l : c,
4791 w = I.get(v) || 0;
4792 if (!0 === w || 3 === w && 4 !== h || 4 === w && 3 !== h) 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: " + v);
4793 I.set(v, !(!w && h > 2) || h);
4794 }
4795 applyMemberDec(o, d, f, m, v, h, g, y, p, b, a);
4796 }
4797 }
4798 return pushInitializers(o, n), pushInitializers(o, i), o;
4799 }
4800 function pushInitializers(e, t) {
4801 t && e.push(function (e) {
4802 for (var r = 0; r < t.length; r++) t[r].call(e);
4803 return e;
4804 });
4805 }
4806 function applyClassDecs(e, t, r, a) {
4807 if (t.length) {
4808 for (var n = [], i = e, s = e.name, o = r ? 2 : 1, c = t.length - 1; c >= 0; c -= o) {
4809 var l = {
4810 v: !1
4811 };
4812 try {
4813 var u = t[c].call(r ? t[c - 1] : void 0, i, {
4814 kind: "class",
4815 name: s,
4816 addInitializer: createAddInitializerMethod(n, l),
4817 metadata: a
4818 });
4819 } finally {
4820 l.v = !0;
4821 }
4822 void 0 !== u && (assertValidReturnValue(5, u), i = u);
4823 }
4824 return [defineMetadata(i, a), function () {
4825 for (var e = 0; e < n.length; e++) n[e].call(i);
4826 }];
4827 }
4828 }
4829 function defineMetadata(e, t) {
4830 return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), {
4831 configurable: !0,
4832 enumerable: !0,
4833 value: t
4834 });
4835 }
4836 function _applyDecs2305(e, t, r, a, n, i) {
4837 if (arguments.length >= 6) var s = i[Symbol.metadata || Symbol.for("Symbol.metadata")];
4838 var o = Object.create(void 0 === s ? null : s),
4839 c = applyMemberDecs(e, t, n, o);
4840 return r.length || defineMetadata(e, o), {
4841 e: c,
4842 get c() {
4843 return applyClassDecs(e, r, a, o);
4844 }
4845 };
4846 }
4847 function _asyncGeneratorDelegate(t) {
4848 var e = {},
4849 n = !1;
4850 function pump(e, r) {
4851 return n = !0, r = new Promise(function (n) {
4852 n(t[e](r));
4853 }), {
4854 done: !1,
4855 value: new _OverloadYield(r, 1)
4856 };
4857 }
4858 return e["undefined" != typeof Symbol && Symbol.iterator || "@@iterator"] = function () {
4859 return this;
4860 }, e.next = function (t) {
4861 return n ? (n = !1, t) : pump("next", t);
4862 }, "function" == typeof t.throw && (e.throw = function (t) {
4863 if (n) throw n = !1, t;
4864 return pump("throw", t);
4865 }), "function" == typeof t.return && (e.return = function (t) {
4866 return n ? (n = !1, t) : pump("return", t);
4867 }), e;
4868 }
4869 function _asyncIterator(r) {
4870 var n,
4871 t,
4872 o,
4873 e = 2;
4874 for ("undefined" != typeof Symbol && (t = Symbol.asyncIterator, o = Symbol.iterator); e--;) {
4875 if (t && null != (n = r[t])) return n.call(r);
4876 if (o && null != (n = r[o])) return new AsyncFromSyncIterator(n.call(r));
4877 t = "@@asyncIterator", o = "@@iterator";
4878 }
4879 throw new TypeError("Object is not async iterable");
4880 }
4881 function AsyncFromSyncIterator(r) {
4882 function AsyncFromSyncIteratorContinuation(r) {
4883 if (Object(r) !== r) return Promise.reject(new TypeError(r + " is not an object."));
4884 var n = r.done;
4885 return Promise.resolve(r.value).then(function (r) {
4886 return {
4887 value: r,
4888 done: n
4889 };
4890 });
4891 }
4892 return AsyncFromSyncIterator = function (r) {
4893 this.s = r, this.n = r.next;
4894 }, AsyncFromSyncIterator.prototype = {
4895 s: null,
4896 n: null,
4897 next: function () {
4898 return AsyncFromSyncIteratorContinuation(this.n.apply(this.s, arguments));
4899 },
4900 return: function (r) {
4901 var n = this.s.return;
4902 return void 0 === n ? Promise.resolve({
4903 value: r,
4904 done: !0
4905 }) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments));
4906 },
4907 throw: function (r) {
4908 var n = this.s.return;
4909 return void 0 === n ? Promise.reject(r) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments));
4910 }
4911 }, new AsyncFromSyncIterator(r);
4912 }
4913 function _awaitAsyncGenerator(e) {
4914 return new _OverloadYield(e, 0);
4915 }
4916 function _checkInRHS(e) {
4917 if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null"));
4918 return e;
4919 }
4920 function _defineAccessor(e, r, n, t) {
4921 var c = {
4922 configurable: !0,
4923 enumerable: !0
4924 };
4925 return c[e] = t, Object.defineProperty(r, n, c);
4926 }
4927 function dispose_SuppressedError(r, e) {
4928 return "undefined" != typeof SuppressedError ? dispose_SuppressedError = SuppressedError : (dispose_SuppressedError = function (r, e) {
4929 this.suppressed = r, this.error = e, this.stack = new Error().stack;
4930 }, dispose_SuppressedError.prototype = Object.create(Error.prototype, {
4931 constructor: {
4932 value: dispose_SuppressedError,
4933 writable: !0,
4934 configurable: !0
4935 }
4936 })), new dispose_SuppressedError(r, e);
4937 }
4938 function _dispose(r, e, s) {
4939 function next() {
4940 for (; r.length > 0;) try {
4941 var o = r.pop(),
4942 p = o.d.call(o.v);
4943 if (o.a) return Promise.resolve(p).then(next, err);
4944 } catch (r) {
4945 return err(r);
4946 }
4947 if (s) throw e;
4948 }
4949 function err(r) {
4950 return e = s ? new dispose_SuppressedError(r, e) : r, s = !0, next();
4951 }
4952 return next();
4953 }
4954 function _importDeferProxy(e) {
4955 var t = null,
4956 constValue = function (e) {
4957 return function () {
4958 return e;
4959 };
4960 },
4961 proxy = function (r) {
4962 return function (n, o, f) {
4963 return null === t && (t = e()), r(t, o, f);
4964 };
4965 };
4966 return new Proxy({}, {
4967 defineProperty: constValue(!1),
4968 deleteProperty: constValue(!1),
4969 get: proxy(Reflect.get),
4970 getOwnPropertyDescriptor: proxy(Reflect.getOwnPropertyDescriptor),
4971 getPrototypeOf: constValue(null),
4972 isExtensible: constValue(!1),
4973 has: proxy(Reflect.has),
4974 ownKeys: proxy(Reflect.ownKeys),
4975 preventExtensions: constValue(!0),
4976 set: constValue(!1),
4977 setPrototypeOf: constValue(!1)
4978 });
4979 }
4980 function _iterableToArrayLimit(r, l) {
4981 var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
4982 if (null != t) {
4983 var e,
4984 n,
4985 i,
4986 u,
4987 a = [],
4988 f = !0,
4989 o = !1;
4990 try {
4991 if (i = (t = t.call(r)).next, 0 === l) {
4992 if (Object(t) !== t) return;
4993 f = !1;
4994 } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
4995 } catch (r) {
4996 o = !0, n = r;
4997 } finally {
4998 try {
4999 if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
5000 } finally {
5001 if (o) throw n;
5002 }
5003 }
5004 return a;
5005 }
5006 }
5007 function _iterableToArrayLimitLoose(e, r) {
5008 var t = e && ("undefined" != typeof Symbol && e[Symbol.iterator] || e["@@iterator"]);
5009 if (null != t) {
5010 var o,
5011 l = [];
5012 for (t = t.call(e); e.length < r && !(o = t.next()).done;) l.push(o.value);
5013 return l;
5014 }
5015 }
5016 var REACT_ELEMENT_TYPE;
5017 function _jsx(e, r, E, l) {
5018 REACT_ELEMENT_TYPE || (REACT_ELEMENT_TYPE = "function" == typeof Symbol && Symbol.for && Symbol.for("react.element") || 60103);
5019 var o = e && e.defaultProps,
5020 n = arguments.length - 3;
5021 if (r || 0 === n || (r = {
5022 children: void 0
5023 }), 1 === n) r.children = l;else if (n > 1) {
5024 for (var t = new Array(n), f = 0; f < n; f++) t[f] = arguments[f + 3];
5025 r.children = t;
5026 }
5027 if (r && o) for (var i in o) void 0 === r[i] && (r[i] = o[i]);else r || (r = o || {});
5028 return {
5029 $$typeof: REACT_ELEMENT_TYPE,
5030 type: e,
5031 key: void 0 === E ? null : "" + E,
5032 ref: null,
5033 props: r,
5034 _owner: null
5035 };
5036 }
5037 function ownKeys(e, r) {
5038 var t = Object.keys(e);
5039 if (Object.getOwnPropertySymbols) {
5040 var o = Object.getOwnPropertySymbols(e);
5041 r && (o = o.filter(function (r) {
5042 return Object.getOwnPropertyDescriptor(e, r).enumerable;
5043 })), t.push.apply(t, o);
5044 }
5045 return t;
5046 }
5047 function _objectSpread2(e) {
5048 for (var r = 1; r < arguments.length; r++) {
5049 var t = null != arguments[r] ? arguments[r] : {};
5050 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
5051 _defineProperty(e, r, t[r]);
5052 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
5053 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
5054 });
5055 }
5056 return e;
5057 }
5058 function _regeneratorRuntime() {
5059 "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
5060 _regeneratorRuntime = function () {
5061 return e;
5062 };
5063 var t,
5064 e = {},
5065 r = Object.prototype,
5066 n = r.hasOwnProperty,
5067 o = Object.defineProperty || function (t, e, r) {
5068 t[e] = r.value;
5069 },
5070 i = "function" == typeof Symbol ? Symbol : {},
5071 a = i.iterator || "@@iterator",
5072 c = i.asyncIterator || "@@asyncIterator",
5073 u = i.toStringTag || "@@toStringTag";
5074 function define(t, e, r) {
5075 return Object.defineProperty(t, e, {
5076 value: r,
5077 enumerable: !0,
5078 configurable: !0,
5079 writable: !0
5080 }), t[e];
5081 }
5082 try {
5083 define({}, "");
5084 } catch (t) {
5085 define = function (t, e, r) {
5086 return t[e] = r;
5087 };
5088 }
5089 function wrap(t, e, r, n) {
5090 var i = e && e.prototype instanceof Generator ? e : Generator,
5091 a = Object.create(i.prototype),
5092 c = new Context(n || []);
5093 return o(a, "_invoke", {
5094 value: makeInvokeMethod(t, r, c)
5095 }), a;
5096 }
5097 function tryCatch(t, e, r) {
5098 try {
5099 return {
5100 type: "normal",
5101 arg: t.call(e, r)
5102 };
5103 } catch (t) {
5104 return {
5105 type: "throw",
5106 arg: t
5107 };
5108 }
5109 }
5110 e.wrap = wrap;
5111 var h = "suspendedStart",
5112 l = "suspendedYield",
5113 f = "executing",
5114 s = "completed",
5115 y = {};
5116 function Generator() {}
5117 function GeneratorFunction() {}
5118 function GeneratorFunctionPrototype() {}
5119 var p = {};
5120 define(p, a, function () {
5121 return this;
5122 });
5123 var d = Object.getPrototypeOf,
5124 v = d && d(d(values([])));
5125 v && v !== r && n.call(v, a) && (p = v);
5126 var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p);
5127 function defineIteratorMethods(t) {
5128 ["next", "throw", "return"].forEach(function (e) {
5129 define(t, e, function (t) {
5130 return this._invoke(e, t);
5131 });
5132 });
5133 }
5134 function AsyncIterator(t, e) {
5135 function invoke(r, o, i, a) {
5136 var c = tryCatch(t[r], t, o);
5137 if ("throw" !== c.type) {
5138 var u = c.arg,
5139 h = u.value;
5140 return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) {
5141 invoke("next", t, i, a);
5142 }, function (t) {
5143 invoke("throw", t, i, a);
5144 }) : e.resolve(h).then(function (t) {
5145 u.value = t, i(u);
5146 }, function (t) {
5147 return invoke("throw", t, i, a);
5148 });
5149 }
5150 a(c.arg);
5151 }
5152 var r;
5153 o(this, "_invoke", {
5154 value: function (t, n) {
5155 function callInvokeWithMethodAndArg() {
5156 return new e(function (e, r) {
5157 invoke(t, n, e, r);
5158 });
5159 }
5160 return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
5161 }
5162 });
5163 }
5164 function makeInvokeMethod(e, r, n) {
5165 var o = h;
5166 return function (i, a) {
5167 if (o === f) throw new Error("Generator is already running");
5168 if (o === s) {
5169 if ("throw" === i) throw a;
5170 return {
5171 value: t,
5172 done: !0
5173 };
5174 }
5175 for (n.method = i, n.arg = a;;) {
5176 var c = n.delegate;
5177 if (c) {
5178 var u = maybeInvokeDelegate(c, n);
5179 if (u) {
5180 if (u === y) continue;
5181 return u;
5182 }
5183 }
5184 if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) {
5185 if (o === h) throw o = s, n.arg;
5186 n.dispatchException(n.arg);
5187 } else "return" === n.method && n.abrupt("return", n.arg);
5188 o = f;
5189 var p = tryCatch(e, r, n);
5190 if ("normal" === p.type) {
5191 if (o = n.done ? s : l, p.arg === y) continue;
5192 return {
5193 value: p.arg,
5194 done: n.done
5195 };
5196 }
5197 "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg);
5198 }
5199 };
5200 }
5201 function maybeInvokeDelegate(e, r) {
5202 var n = r.method,
5203 o = e.iterator[n];
5204 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;
5205 var i = tryCatch(o, e.iterator, r.arg);
5206 if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y;
5207 var a = i.arg;
5208 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);
5209 }
5210 function pushTryEntry(t) {
5211 var e = {
5212 tryLoc: t[0]
5213 };
5214 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e);
5215 }
5216 function resetTryEntry(t) {
5217 var e = t.completion || {};
5218 e.type = "normal", delete e.arg, t.completion = e;
5219 }
5220 function Context(t) {
5221 this.tryEntries = [{
5222 tryLoc: "root"
5223 }], t.forEach(pushTryEntry, this), this.reset(!0);
5224 }
5225 function values(e) {
5226 if (e || "" === e) {
5227 var r = e[a];
5228 if (r) return r.call(e);
5229 if ("function" == typeof e.next) return e;
5230 if (!isNaN(e.length)) {
5231 var o = -1,
5232 i = function next() {
5233 for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next;
5234 return next.value = t, next.done = !0, next;
5235 };
5236 return i.next = i;
5237 }
5238 }
5239 throw new TypeError(typeof e + " is not iterable");
5240 }
5241 return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", {
5242 value: GeneratorFunctionPrototype,
5243 configurable: !0
5244 }), o(GeneratorFunctionPrototype, "constructor", {
5245 value: GeneratorFunction,
5246 configurable: !0
5247 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) {
5248 var e = "function" == typeof t && t.constructor;
5249 return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name));
5250 }, e.mark = function (t) {
5251 return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t;
5252 }, e.awrap = function (t) {
5253 return {
5254 __await: t
5255 };
5256 }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () {
5257 return this;
5258 }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) {
5259 void 0 === i && (i = Promise);
5260 var a = new AsyncIterator(wrap(t, r, n, o), i);
5261 return e.isGeneratorFunction(r) ? a : a.next().then(function (t) {
5262 return t.done ? t.value : a.next();
5263 });
5264 }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () {
5265 return this;
5266 }), define(g, "toString", function () {
5267 return "[object Generator]";
5268 }), e.keys = function (t) {
5269 var e = Object(t),
5270 r = [];
5271 for (var n in e) r.push(n);
5272 return r.reverse(), function next() {
5273 for (; r.length;) {
5274 var t = r.pop();
5275 if (t in e) return next.value = t, next.done = !1, next;
5276 }
5277 return next.done = !0, next;
5278 };
5279 }, e.values = values, Context.prototype = {
5280 constructor: Context,
5281 reset: function (e) {
5282 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);
5283 },
5284 stop: function () {
5285 this.done = !0;
5286 var t = this.tryEntries[0].completion;
5287 if ("throw" === t.type) throw t.arg;
5288 return this.rval;
5289 },
5290 dispatchException: function (e) {
5291 if (this.done) throw e;
5292 var r = this;
5293 function handle(n, o) {
5294 return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o;
5295 }
5296 for (var o = this.tryEntries.length - 1; o >= 0; --o) {
5297 var i = this.tryEntries[o],
5298 a = i.completion;
5299 if ("root" === i.tryLoc) return handle("end");
5300 if (i.tryLoc <= this.prev) {
5301 var c = n.call(i, "catchLoc"),
5302 u = n.call(i, "finallyLoc");
5303 if (c && u) {
5304 if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
5305 if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
5306 } else if (c) {
5307 if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
5308 } else {
5309 if (!u) throw new Error("try statement without catch or finally");
5310 if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
5311 }
5312 }
5313 }
5314 },
5315 abrupt: function (t, e) {
5316 for (var r = this.tryEntries.length - 1; r >= 0; --r) {
5317 var o = this.tryEntries[r];
5318 if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
5319 var i = o;
5320 break;
5321 }
5322 }
5323 i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
5324 var a = i ? i.completion : {};
5325 return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a);
5326 },
5327 complete: function (t, e) {
5328 if ("throw" === t.type) throw t.arg;
5329 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;
5330 },
5331 finish: function (t) {
5332 for (var e = this.tryEntries.length - 1; e >= 0; --e) {
5333 var r = this.tryEntries[e];
5334 if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y;
5335 }
5336 },
5337 catch: function (t) {
5338 for (var e = this.tryEntries.length - 1; e >= 0; --e) {
5339 var r = this.tryEntries[e];
5340 if (r.tryLoc === t) {
5341 var n = r.completion;
5342 if ("throw" === n.type) {
5343 var o = n.arg;
5344 resetTryEntry(r);
5345 }
5346 return o;
5347 }
5348 }
5349 throw new Error("illegal catch attempt");
5350 },
5351 delegateYield: function (e, r, n) {
5352 return this.delegate = {
5353 iterator: values(e),
5354 resultName: r,
5355 nextLoc: n
5356 }, "next" === this.method && (this.arg = t), y;
5357 }
5358 }, e;
5359 }
5360 function _typeof(o) {
5361 "@babel/helpers - typeof";
5362
5363 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
5364 return typeof o;
5365 } : function (o) {
5366 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
5367 }, _typeof(o);
5368 }
5369 function _using(o, e, n) {
5370 if (null == e) return e;
5371 if ("object" != typeof e) throw new TypeError("using declarations can only be used with objects, null, or undefined.");
5372 if (n) var r = e[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
5373 if (null == r && (r = e[Symbol.dispose || Symbol.for("Symbol.dispose")]), "function" != typeof r) throw new TypeError("Property [Symbol.dispose] is not a function.");
5374 return o.push({
5375 v: e,
5376 d: r,
5377 a: n
5378 }), e;
5379 }
5380 function _wrapRegExp() {
5381 _wrapRegExp = function (e, r) {
5382 return new BabelRegExp(e, void 0, r);
5383 };
5384 var e = RegExp.prototype,
5385 r = new WeakMap();
5386 function BabelRegExp(e, t, p) {
5387 var o = new RegExp(e, t);
5388 return r.set(o, p || r.get(e)), _setPrototypeOf(o, BabelRegExp.prototype);
5389 }
5390 function buildGroups(e, t) {
5391 var p = r.get(t);
5392 return Object.keys(p).reduce(function (r, t) {
5393 var o = p[t];
5394 if ("number" == typeof o) r[t] = e[o];else {
5395 for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++;
5396 r[t] = e[o[i]];
5397 }
5398 return r;
5399 }, Object.create(null));
5400 }
5401 return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) {
5402 var t = e.exec.call(this, r);
5403 if (t) {
5404 t.groups = buildGroups(t, this);
5405 var p = t.indices;
5406 p && (p.groups = buildGroups(p, this));
5407 }
5408 return t;
5409 }, BabelRegExp.prototype[Symbol.replace] = function (t, p) {
5410 if ("string" == typeof p) {
5411 var o = r.get(this);
5412 return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)>/g, function (e, r) {
5413 var t = o[r];
5414 return "$" + (Array.isArray(t) ? t.join("$") : t);
5415 }));
5416 }
5417 if ("function" == typeof p) {
5418 var i = this;
5419 return e[Symbol.replace].call(this, t, function () {
5420 var e = arguments;
5421 return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e);
5422 });
5423 }
5424 return e[Symbol.replace].call(this, t, p);
5425 }, _wrapRegExp.apply(this, arguments);
5426 }
5427 function _AwaitValue(value) {
5428 this.wrapped = value;
5429 }
5430 function _wrapAsyncGenerator(fn) {
5431 return function () {
5432 return new _AsyncGenerator(fn.apply(this, arguments));
5433 };
5434 }
5435 function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
5436 try {
5437 var info = gen[key](arg);
5438 var value = info.value;
5439 } catch (error) {
5440 reject(error);
5441 return;
5442 }
5443 if (info.done) {
5444 resolve(value);
5445 } else {
5446 Promise.resolve(value).then(_next, _throw);
5447 }
5448 }
5449 function _asyncToGenerator(fn) {
5450 return function () {
5451 var self = this,
5452 args = arguments;
5453 return new Promise(function (resolve, reject) {
5454 var gen = fn.apply(self, args);
5455 function _next(value) {
5456 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
5457 }
5458 function _throw(err) {
5459 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
5460 }
5461 _next(undefined);
5462 });
5463 };
5464 }
5465 function _classCallCheck(instance, Constructor) {
5466 if (!(instance instanceof Constructor)) {
5467 throw new TypeError("Cannot call a class as a function");
5468 }
5469 }
5470 function _defineProperties(target, props) {
5471 for (var i = 0; i < props.length; i++) {
5472 var descriptor = props[i];
5473 descriptor.enumerable = descriptor.enumerable || false;
5474 descriptor.configurable = true;
5475 if ("value" in descriptor) descriptor.writable = true;
5476 Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
5477 }
5478 }
5479 function _createClass(Constructor, protoProps, staticProps) {
5480 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
5481 if (staticProps) _defineProperties(Constructor, staticProps);
5482 Object.defineProperty(Constructor, "prototype", {
5483 writable: false
5484 });
5485 return Constructor;
5486 }
5487 function _defineEnumerableProperties(obj, descs) {
5488 for (var key in descs) {
5489 var desc = descs[key];
5490 desc.configurable = desc.enumerable = true;
5491 if ("value" in desc) desc.writable = true;
5492 Object.defineProperty(obj, key, desc);
5493 }
5494 if (Object.getOwnPropertySymbols) {
5495 var objectSymbols = Object.getOwnPropertySymbols(descs);
5496 for (var i = 0; i < objectSymbols.length; i++) {
5497 var sym = objectSymbols[i];
5498 var desc = descs[sym];
5499 desc.configurable = desc.enumerable = true;
5500 if ("value" in desc) desc.writable = true;
5501 Object.defineProperty(obj, sym, desc);
5502 }
5503 }
5504 return obj;
5505 }
5506 function _defaults(obj, defaults) {
5507 var keys = Object.getOwnPropertyNames(defaults);
5508 for (var i = 0; i < keys.length; i++) {
5509 var key = keys[i];
5510 var value = Object.getOwnPropertyDescriptor(defaults, key);
5511 if (value && value.configurable && obj[key] === undefined) {
5512 Object.defineProperty(obj, key, value);
5513 }
5514 }
5515 return obj;
5516 }
5517 function _defineProperty(obj, key, value) {
5518 key = _toPropertyKey(key);
5519 if (key in obj) {
5520 Object.defineProperty(obj, key, {
5521 value: value,
5522 enumerable: true,
5523 configurable: true,
5524 writable: true
5525 });
5526 } else {
5527 obj[key] = value;
5528 }
5529 return obj;
5530 }
5531 function _extends() {
5532 _extends = Object.assign ? Object.assign.bind() : function (target) {
5533 for (var i = 1; i < arguments.length; i++) {
5534 var source = arguments[i];
5535 for (var key in source) {
5536 if (Object.prototype.hasOwnProperty.call(source, key)) {
5537 target[key] = source[key];
5538 }
5539 }
5540 }
5541 return target;
5542 };
5543 return _extends.apply(this, arguments);
5544 }
5545 function _objectSpread(target) {
5546 for (var i = 1; i < arguments.length; i++) {
5547 var source = arguments[i] != null ? Object(arguments[i]) : {};
5548 var ownKeys = Object.keys(source);
5549 if (typeof Object.getOwnPropertySymbols === 'function') {
5550 ownKeys.push.apply(ownKeys, Object.getOwnPropertySymbols(source).filter(function (sym) {
5551 return Object.getOwnPropertyDescriptor(source, sym).enumerable;
5552 }));
5553 }
5554 ownKeys.forEach(function (key) {
5555 _defineProperty(target, key, source[key]);
5556 });
5557 }
5558 return target;
5559 }
5560 function _inherits(subClass, superClass) {
5561 if (typeof superClass !== "function" && superClass !== null) {
5562 throw new TypeError("Super expression must either be null or a function");
5563 }
5564 subClass.prototype = Object.create(superClass && superClass.prototype, {
5565 constructor: {
5566 value: subClass,
5567 writable: true,
5568 configurable: true
5569 }
5570 });
5571 Object.defineProperty(subClass, "prototype", {
5572 writable: false
5573 });
5574 if (superClass) _setPrototypeOf(subClass, superClass);
5575 }
5576 function _inheritsLoose(subClass, superClass) {
5577 subClass.prototype = Object.create(superClass.prototype);
5578 subClass.prototype.constructor = subClass;
5579 _setPrototypeOf(subClass, superClass);
5580 }
5581 function _getPrototypeOf(o) {
5582 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
5583 return o.__proto__ || Object.getPrototypeOf(o);
5584 };
5585 return _getPrototypeOf(o);
5586 }
5587 function _setPrototypeOf(o, p) {
5588 _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
5589 o.__proto__ = p;
5590 return o;
5591 };
5592 return _setPrototypeOf(o, p);
5593 }
5594 function _isNativeReflectConstruct() {
5595 if (typeof Reflect === "undefined" || !Reflect.construct) return false;
5596 if (Reflect.construct.sham) return false;
5597 if (typeof Proxy === "function") return true;
5598 try {
5599 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
5600 return true;
5601 } catch (e) {
5602 return false;
5603 }
5604 }
5605 function _construct(Parent, args, Class) {
5606 if (_isNativeReflectConstruct()) {
5607 _construct = Reflect.construct.bind();
5608 } else {
5609 _construct = function _construct(Parent, args, Class) {
5610 var a = [null];
5611 a.push.apply(a, args);
5612 var Constructor = Function.bind.apply(Parent, a);
5613 var instance = new Constructor();
5614 if (Class) _setPrototypeOf(instance, Class.prototype);
5615 return instance;
5616 };
5617 }
5618 return _construct.apply(null, arguments);
5619 }
5620 function _isNativeFunction(fn) {
5621 return Function.toString.call(fn).indexOf("[native code]") !== -1;
5622 }
5623 function _wrapNativeSuper(Class) {
5624 var _cache = typeof Map === "function" ? new Map() : undefined;
5625 _wrapNativeSuper = function _wrapNativeSuper(Class) {
5626 if (Class === null || !_isNativeFunction(Class)) return Class;
5627 if (typeof Class !== "function") {
5628 throw new TypeError("Super expression must either be null or a function");
5629 }
5630 if (typeof _cache !== "undefined") {
5631 if (_cache.has(Class)) return _cache.get(Class);
5632 _cache.set(Class, Wrapper);
5633 }
5634 function Wrapper() {
5635 return _construct(Class, arguments, _getPrototypeOf(this).constructor);
5636 }
5637 Wrapper.prototype = Object.create(Class.prototype, {
5638 constructor: {
5639 value: Wrapper,
5640 enumerable: false,
5641 writable: true,
5642 configurable: true
5643 }
5644 });
5645 return _setPrototypeOf(Wrapper, Class);
5646 };
5647 return _wrapNativeSuper(Class);
5648 }
5649 function _instanceof(left, right) {
5650 if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
5651 return !!right[Symbol.hasInstance](left);
5652 } else {
5653 return left instanceof right;
5654 }
5655 }
5656 function _interopRequireDefault(obj) {
5657 return obj && obj.__esModule ? obj : {
5658 default: obj
5659 };
5660 }
5661 function _getRequireWildcardCache(nodeInterop) {
5662 if (typeof WeakMap !== "function") return null;
5663 var cacheBabelInterop = new WeakMap();
5664 var cacheNodeInterop = new WeakMap();
5665 return (_getRequireWildcardCache = function (nodeInterop) {
5666 return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
5667 })(nodeInterop);
5668 }
5669 function _interopRequireWildcard(obj, nodeInterop) {
5670 if (!nodeInterop && obj && obj.__esModule) {
5671 return obj;
5672 }
5673 if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
5674 return {
5675 default: obj
5676 };
5677 }
5678 var cache = _getRequireWildcardCache(nodeInterop);
5679 if (cache && cache.has(obj)) {
5680 return cache.get(obj);
5681 }
5682 var newObj = {};
5683 var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
5684 for (var key in obj) {
5685 if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
5686 var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
5687 if (desc && (desc.get || desc.set)) {
5688 Object.defineProperty(newObj, key, desc);
5689 } else {
5690 newObj[key] = obj[key];
5691 }
5692 }
5693 }
5694 newObj.default = obj;
5695 if (cache) {
5696 cache.set(obj, newObj);
5697 }
5698 return newObj;
5699 }
5700 function _newArrowCheck(innerThis, boundThis) {
5701 if (innerThis !== boundThis) {
5702 throw new TypeError("Cannot instantiate an arrow function");
5703 }
5704 }
5705 function _objectDestructuringEmpty(obj) {
5706 if (obj == null) throw new TypeError("Cannot destructure " + obj);
5707 }
5708 function _objectWithoutPropertiesLoose(source, excluded) {
5709 if (source == null) return {};
5710 var target = {};
5711 var sourceKeys = Object.keys(source);
5712 var key, i;
5713 for (i = 0; i < sourceKeys.length; i++) {
5714 key = sourceKeys[i];
5715 if (excluded.indexOf(key) >= 0) continue;
5716 target[key] = source[key];
5717 }
5718 return target;
5719 }
5720 function _objectWithoutProperties(source, excluded) {
5721 if (source == null) return {};
5722 var target = _objectWithoutPropertiesLoose(source, excluded);
5723 var key, i;
5724 if (Object.getOwnPropertySymbols) {
5725 var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
5726 for (i = 0; i < sourceSymbolKeys.length; i++) {
5727 key = sourceSymbolKeys[i];
5728 if (excluded.indexOf(key) >= 0) continue;
5729 if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
5730 target[key] = source[key];
5731 }
5732 }
5733 return target;
5734 }
5735 function _assertThisInitialized(self) {
5736 if (self === void 0) {
5737 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
5738 }
5739 return self;
5740 }
5741 function _possibleConstructorReturn(self, call) {
5742 if (call && (typeof call === "object" || typeof call === "function")) {
5743 return call;
5744 } else if (call !== void 0) {
5745 throw new TypeError("Derived constructors may only return object or undefined");
5746 }
5747 return _assertThisInitialized(self);
5748 }
5749 function _createSuper(Derived) {
5750 var hasNativeReflectConstruct = _isNativeReflectConstruct();
5751 return function _createSuperInternal() {
5752 var Super = _getPrototypeOf(Derived),
5753 result;
5754 if (hasNativeReflectConstruct) {
5755 var NewTarget = _getPrototypeOf(this).constructor;
5756 result = Reflect.construct(Super, arguments, NewTarget);
5757 } else {
5758 result = Super.apply(this, arguments);
5759 }
5760 return _possibleConstructorReturn(this, result);
5761 };
5762 }
5763 function _superPropBase(object, property) {
5764 while (!Object.prototype.hasOwnProperty.call(object, property)) {
5765 object = _getPrototypeOf(object);
5766 if (object === null) break;
5767 }
5768 return object;
5769 }
5770 function _get() {
5771 if (typeof Reflect !== "undefined" && Reflect.get) {
5772 _get = Reflect.get.bind();
5773 } else {
5774 _get = function _get(target, property, receiver) {
5775 var base = _superPropBase(target, property);
5776 if (!base) return;
5777 var desc = Object.getOwnPropertyDescriptor(base, property);
5778 if (desc.get) {
5779 return desc.get.call(arguments.length < 3 ? target : receiver);
5780 }
5781 return desc.value;
5782 };
5783 }
5784 return _get.apply(this, arguments);
5785 }
5786 function set(target, property, value, receiver) {
5787 if (typeof Reflect !== "undefined" && Reflect.set) {
5788 set = Reflect.set;
5789 } else {
5790 set = function set(target, property, value, receiver) {
5791 var base = _superPropBase(target, property);
5792 var desc;
5793 if (base) {
5794 desc = Object.getOwnPropertyDescriptor(base, property);
5795 if (desc.set) {
5796 desc.set.call(receiver, value);
5797 return true;
5798 } else if (!desc.writable) {
5799 return false;
5800 }
5801 }
5802 desc = Object.getOwnPropertyDescriptor(receiver, property);
5803 if (desc) {
5804 if (!desc.writable) {
5805 return false;
5806 }
5807 desc.value = value;
5808 Object.defineProperty(receiver, property, desc);
5809 } else {
5810 _defineProperty(receiver, property, value);
5811 }
5812 return true;
5813 };
5814 }
5815 return set(target, property, value, receiver);
5816 }
5817 function _set(target, property, value, receiver, isStrict) {
5818 var s = set(target, property, value, receiver || target);
5819 if (!s && isStrict) {
5820 throw new TypeError('failed to set property');
5821 }
5822 return value;
5823 }
5824 function _taggedTemplateLiteral(strings, raw) {
5825 if (!raw) {
5826 raw = strings.slice(0);
5827 }
5828 return Object.freeze(Object.defineProperties(strings, {
5829 raw: {
5830 value: Object.freeze(raw)
5831 }
5832 }));
5833 }
5834 function _taggedTemplateLiteralLoose(strings, raw) {
5835 if (!raw) {
5836 raw = strings.slice(0);
5837 }
5838 strings.raw = raw;
5839 return strings;
5840 }
5841 function _readOnlyError(name) {
5842 throw new TypeError("\"" + name + "\" is read-only");
5843 }
5844 function _writeOnlyError(name) {
5845 throw new TypeError("\"" + name + "\" is write-only");
5846 }
5847 function _classNameTDZError(name) {
5848 throw new ReferenceError("Class \"" + name + "\" cannot be referenced in computed property keys.");
5849 }
5850 function _temporalUndefined() {}
5851 function _tdz(name) {
5852 throw new ReferenceError(name + " is not defined - temporal dead zone");
5853 }
5854 function _temporalRef(val, name) {
5855 return val === _temporalUndefined ? _tdz(name) : val;
5856 }
5857 function _slicedToArray(arr, i) {
5858 return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
5859 }
5860 function _slicedToArrayLoose(arr, i) {
5861 return _arrayWithHoles(arr) || _iterableToArrayLimitLoose(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
5862 }
5863 function _toArray(arr) {
5864 return _arrayWithHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableRest();
5865 }
5866 function _toConsumableArray(arr) {
5867 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
5868 }
5869 function _arrayWithoutHoles(arr) {
5870 if (Array.isArray(arr)) return _arrayLikeToArray(arr);
5871 }
5872 function _arrayWithHoles(arr) {
5873 if (Array.isArray(arr)) return arr;
5874 }
5875 function _maybeArrayLike(next, arr, i) {
5876 if (arr && !Array.isArray(arr) && typeof arr.length === "number") {
5877 var len = arr.length;
5878 return _arrayLikeToArray(arr, i !== void 0 && i < len ? i : len);
5879 }
5880 return next(arr, i);
5881 }
5882 function _iterableToArray(iter) {
5883 if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
5884 }
5885 function _unsupportedIterableToArray(o, minLen) {
5886 if (!o) return;
5887 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
5888 var n = Object.prototype.toString.call(o).slice(8, -1);
5889 if (n === "Object" && o.constructor) n = o.constructor.name;
5890 if (n === "Map" || n === "Set") return Array.from(o);
5891 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
5892 }
5893 function _arrayLikeToArray(arr, len) {
5894 if (len == null || len > arr.length) len = arr.length;
5895 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
5896 return arr2;
5897 }
5898 function _nonIterableSpread() {
5899 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
5900 }
5901 function _nonIterableRest() {
5902 throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
5903 }
5904 function _createForOfIteratorHelper(o, allowArrayLike) {
5905 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
5906 if (!it) {
5907 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
5908 if (it) o = it;
5909 var i = 0;
5910 var F = function () {};
5911 return {
5912 s: F,
5913 n: function () {
5914 if (i >= o.length) return {
5915 done: true
5916 };
5917 return {
5918 done: false,
5919 value: o[i++]
5920 };
5921 },
5922 e: function (e) {
5923 throw e;
5924 },
5925 f: F
5926 };
5927 }
5928 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
5929 }
5930 var normalCompletion = true,
5931 didErr = false,
5932 err;
5933 return {
5934 s: function () {
5935 it = it.call(o);
5936 },
5937 n: function () {
5938 var step = it.next();
5939 normalCompletion = step.done;
5940 return step;
5941 },
5942 e: function (e) {
5943 didErr = true;
5944 err = e;
5945 },
5946 f: function () {
5947 try {
5948 if (!normalCompletion && it.return != null) it.return();
5949 } finally {
5950 if (didErr) throw err;
5951 }
5952 }
5953 };
5954 }
5955 function _createForOfIteratorHelperLoose(o, allowArrayLike) {
5956 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
5957 if (it) return (it = it.call(o)).next.bind(it);
5958 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
5959 if (it) o = it;
5960 var i = 0;
5961 return function () {
5962 if (i >= o.length) return {
5963 done: true
5964 };
5965 return {
5966 done: false,
5967 value: o[i++]
5968 };
5969 };
5970 }
5971 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
5972 }
5973 function _skipFirstGeneratorNext(fn) {
5974 return function () {
5975 var it = fn.apply(this, arguments);
5976 it.next();
5977 return it;
5978 };
5979 }
5980 function _toPrimitive(input, hint) {
5981 if (typeof input !== "object" || input === null) return input;
5982 var prim = input[Symbol.toPrimitive];
5983 if (prim !== undefined) {
5984 var res = prim.call(input, hint || "default");
5985 if (typeof res !== "object") return res;
5986 throw new TypeError("@@toPrimitive must return a primitive value.");
5987 }
5988 return (hint === "string" ? String : Number)(input);
5989 }
5990 function _toPropertyKey(arg) {
5991 var key = _toPrimitive(arg, "string");
5992 return typeof key === "symbol" ? key : String(key);
5993 }
5994 function _initializerWarningHelper(descriptor, context) {
5995 throw new Error('Decorating class property failed. Please ensure that ' + 'transform-class-properties is enabled and runs after the decorators transform.');
5996 }
5997 function _initializerDefineProperty(target, property, descriptor, context) {
5998 if (!descriptor) return;
5999 Object.defineProperty(target, property, {
6000 enumerable: descriptor.enumerable,
6001 configurable: descriptor.configurable,
6002 writable: descriptor.writable,
6003 value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
6004 });
6005 }
6006 function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
6007 var desc = {};
6008 Object.keys(descriptor).forEach(function (key) {
6009 desc[key] = descriptor[key];
6010 });
6011 desc.enumerable = !!desc.enumerable;
6012 desc.configurable = !!desc.configurable;
6013 if ('value' in desc || desc.initializer) {
6014 desc.writable = true;
6015 }
6016 desc = decorators.slice().reverse().reduce(function (desc, decorator) {
6017 return decorator(target, property, desc) || desc;
6018 }, desc);
6019 if (context && desc.initializer !== void 0) {
6020 desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
6021 desc.initializer = undefined;
6022 }
6023 if (desc.initializer === void 0) {
6024 Object.defineProperty(target, property, desc);
6025 desc = null;
6026 }
6027 return desc;
6028 }
6029 var id$1 = 0;
6030 function _classPrivateFieldLooseKey(name) {
6031 return "__private_" + id$1++ + "_" + name;
6032 }
6033 function _classPrivateFieldLooseBase(receiver, privateKey) {
6034 if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
6035 throw new TypeError("attempted to use private field on non-instance");
6036 }
6037 return receiver;
6038 }
6039 function _classPrivateFieldGet(receiver, privateMap) {
6040 var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get");
6041 return _classApplyDescriptorGet(receiver, descriptor);
6042 }
6043 function _classPrivateFieldSet(receiver, privateMap, value) {
6044 var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set");
6045 _classApplyDescriptorSet(receiver, descriptor, value);
6046 return value;
6047 }
6048 function _classPrivateFieldDestructureSet(receiver, privateMap) {
6049 var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set");
6050 return _classApplyDescriptorDestructureSet(receiver, descriptor);
6051 }
6052 function _classExtractFieldDescriptor(receiver, privateMap, action) {
6053 if (!privateMap.has(receiver)) {
6054 throw new TypeError("attempted to " + action + " private field on non-instance");
6055 }
6056 return privateMap.get(receiver);
6057 }
6058 function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) {
6059 _classCheckPrivateStaticAccess(receiver, classConstructor);
6060 _classCheckPrivateStaticFieldDescriptor(descriptor, "get");
6061 return _classApplyDescriptorGet(receiver, descriptor);
6062 }
6063 function _classStaticPrivateFieldSpecSet(receiver, classConstructor, descriptor, value) {
6064 _classCheckPrivateStaticAccess(receiver, classConstructor);
6065 _classCheckPrivateStaticFieldDescriptor(descriptor, "set");
6066 _classApplyDescriptorSet(receiver, descriptor, value);
6067 return value;
6068 }
6069 function _classStaticPrivateMethodGet(receiver, classConstructor, method) {
6070 _classCheckPrivateStaticAccess(receiver, classConstructor);
6071 return method;
6072 }
6073 function _classStaticPrivateMethodSet() {
6074 throw new TypeError("attempted to set read only static private field");
6075 }
6076 function _classApplyDescriptorGet(receiver, descriptor) {
6077 if (descriptor.get) {
6078 return descriptor.get.call(receiver);
6079 }
6080 return descriptor.value;
6081 }
6082 function _classApplyDescriptorSet(receiver, descriptor, value) {
6083 if (descriptor.set) {
6084 descriptor.set.call(receiver, value);
6085 } else {
6086 if (!descriptor.writable) {
6087 throw new TypeError("attempted to set read only private field");
6088 }
6089 descriptor.value = value;
6090 }
6091 }
6092 function _classApplyDescriptorDestructureSet(receiver, descriptor) {
6093 if (descriptor.set) {
6094 if (!("__destrObj" in descriptor)) {
6095 descriptor.__destrObj = {
6096 set value(v) {
6097 descriptor.set.call(receiver, v);
6098 }
6099 };
6100 }
6101 return descriptor.__destrObj;
6102 } else {
6103 if (!descriptor.writable) {
6104 throw new TypeError("attempted to set read only private field");
6105 }
6106 return descriptor;
6107 }
6108 }
6109 function _classStaticPrivateFieldDestructureSet(receiver, classConstructor, descriptor) {
6110 _classCheckPrivateStaticAccess(receiver, classConstructor);
6111 _classCheckPrivateStaticFieldDescriptor(descriptor, "set");
6112 return _classApplyDescriptorDestructureSet(receiver, descriptor);
6113 }
6114 function _classCheckPrivateStaticAccess(receiver, classConstructor) {
6115 if (receiver !== classConstructor) {
6116 throw new TypeError("Private static access of wrong provenance");
6117 }
6118 }
6119 function _classCheckPrivateStaticFieldDescriptor(descriptor, action) {
6120 if (descriptor === undefined) {
6121 throw new TypeError("attempted to " + action + " private static field before its declaration");
6122 }
6123 }
6124 function _decorate(decorators, factory, superClass, mixins) {
6125 var api = _getDecoratorsApi();
6126 if (mixins) {
6127 for (var i = 0; i < mixins.length; i++) {
6128 api = mixins[i](api);
6129 }
6130 }
6131 var r = factory(function initialize(O) {
6132 api.initializeInstanceElements(O, decorated.elements);
6133 }, superClass);
6134 var decorated = api.decorateClass(_coalesceClassElements(r.d.map(_createElementDescriptor)), decorators);
6135 api.initializeClassElements(r.F, decorated.elements);
6136 return api.runClassFinishers(r.F, decorated.finishers);
6137 }
6138 function _getDecoratorsApi() {
6139 _getDecoratorsApi = function () {
6140 return api;
6141 };
6142 var api = {
6143 elementsDefinitionOrder: [["method"], ["field"]],
6144 initializeInstanceElements: function (O, elements) {
6145 ["method", "field"].forEach(function (kind) {
6146 elements.forEach(function (element) {
6147 if (element.kind === kind && element.placement === "own") {
6148 this.defineClassElement(O, element);
6149 }
6150 }, this);
6151 }, this);
6152 },
6153 initializeClassElements: function (F, elements) {
6154 var proto = F.prototype;
6155 ["method", "field"].forEach(function (kind) {
6156 elements.forEach(function (element) {
6157 var placement = element.placement;
6158 if (element.kind === kind && (placement === "static" || placement === "prototype")) {
6159 var receiver = placement === "static" ? F : proto;
6160 this.defineClassElement(receiver, element);
6161 }
6162 }, this);
6163 }, this);
6164 },
6165 defineClassElement: function (receiver, element) {
6166 var descriptor = element.descriptor;
6167 if (element.kind === "field") {
6168 var initializer = element.initializer;
6169 descriptor = {
6170 enumerable: descriptor.enumerable,
6171 writable: descriptor.writable,
6172 configurable: descriptor.configurable,
6173 value: initializer === void 0 ? void 0 : initializer.call(receiver)
6174 };
6175 }
6176 Object.defineProperty(receiver, element.key, descriptor);
6177 },
6178 decorateClass: function (elements, decorators) {
6179 var newElements = [];
6180 var finishers = [];
6181 var placements = {
6182 static: [],
6183 prototype: [],
6184 own: []
6185 };
6186 elements.forEach(function (element) {
6187 this.addElementPlacement(element, placements);
6188 }, this);
6189 elements.forEach(function (element) {
6190 if (!_hasDecorators(element)) return newElements.push(element);
6191 var elementFinishersExtras = this.decorateElement(element, placements);
6192 newElements.push(elementFinishersExtras.element);
6193 newElements.push.apply(newElements, elementFinishersExtras.extras);
6194 finishers.push.apply(finishers, elementFinishersExtras.finishers);
6195 }, this);
6196 if (!decorators) {
6197 return {
6198 elements: newElements,
6199 finishers: finishers
6200 };
6201 }
6202 var result = this.decorateConstructor(newElements, decorators);
6203 finishers.push.apply(finishers, result.finishers);
6204 result.finishers = finishers;
6205 return result;
6206 },
6207 addElementPlacement: function (element, placements, silent) {
6208 var keys = placements[element.placement];
6209 if (!silent && keys.indexOf(element.key) !== -1) {
6210 throw new TypeError("Duplicated element (" + element.key + ")");
6211 }
6212 keys.push(element.key);
6213 },
6214 decorateElement: function (element, placements) {
6215 var extras = [];
6216 var finishers = [];
6217 for (var decorators = element.decorators, i = decorators.length - 1; i >= 0; i--) {
6218 var keys = placements[element.placement];
6219 keys.splice(keys.indexOf(element.key), 1);
6220 var elementObject = this.fromElementDescriptor(element);
6221 var elementFinisherExtras = this.toElementFinisherExtras((0, decorators[i])(elementObject) || elementObject);
6222 element = elementFinisherExtras.element;
6223 this.addElementPlacement(element, placements);
6224 if (elementFinisherExtras.finisher) {
6225 finishers.push(elementFinisherExtras.finisher);
6226 }
6227 var newExtras = elementFinisherExtras.extras;
6228 if (newExtras) {
6229 for (var j = 0; j < newExtras.length; j++) {
6230 this.addElementPlacement(newExtras[j], placements);
6231 }
6232 extras.push.apply(extras, newExtras);
6233 }
6234 }
6235 return {
6236 element: element,
6237 finishers: finishers,
6238 extras: extras
6239 };
6240 },
6241 decorateConstructor: function (elements, decorators) {
6242 var finishers = [];
6243 for (var i = decorators.length - 1; i >= 0; i--) {
6244 var obj = this.fromClassDescriptor(elements);
6245 var elementsAndFinisher = this.toClassDescriptor((0, decorators[i])(obj) || obj);
6246 if (elementsAndFinisher.finisher !== undefined) {
6247 finishers.push(elementsAndFinisher.finisher);
6248 }
6249 if (elementsAndFinisher.elements !== undefined) {
6250 elements = elementsAndFinisher.elements;
6251 for (var j = 0; j < elements.length - 1; j++) {
6252 for (var k = j + 1; k < elements.length; k++) {
6253 if (elements[j].key === elements[k].key && elements[j].placement === elements[k].placement) {
6254 throw new TypeError("Duplicated element (" + elements[j].key + ")");
6255 }
6256 }
6257 }
6258 }
6259 }
6260 return {
6261 elements: elements,
6262 finishers: finishers
6263 };
6264 },
6265 fromElementDescriptor: function (element) {
6266 var obj = {
6267 kind: element.kind,
6268 key: element.key,
6269 placement: element.placement,
6270 descriptor: element.descriptor
6271 };
6272 var desc = {
6273 value: "Descriptor",
6274 configurable: true
6275 };
6276 Object.defineProperty(obj, Symbol.toStringTag, desc);
6277 if (element.kind === "field") obj.initializer = element.initializer;
6278 return obj;
6279 },
6280 toElementDescriptors: function (elementObjects) {
6281 if (elementObjects === undefined) return;
6282 return _toArray(elementObjects).map(function (elementObject) {
6283 var element = this.toElementDescriptor(elementObject);
6284 this.disallowProperty(elementObject, "finisher", "An element descriptor");
6285 this.disallowProperty(elementObject, "extras", "An element descriptor");
6286 return element;
6287 }, this);
6288 },
6289 toElementDescriptor: function (elementObject) {
6290 var kind = String(elementObject.kind);
6291 if (kind !== "method" && kind !== "field") {
6292 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 + '"');
6293 }
6294 var key = _toPropertyKey(elementObject.key);
6295 var placement = String(elementObject.placement);
6296 if (placement !== "static" && placement !== "prototype" && placement !== "own") {
6297 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 + '"');
6298 }
6299 var descriptor = elementObject.descriptor;
6300 this.disallowProperty(elementObject, "elements", "An element descriptor");
6301 var element = {
6302 kind: kind,
6303 key: key,
6304 placement: placement,
6305 descriptor: Object.assign({}, descriptor)
6306 };
6307 if (kind !== "field") {
6308 this.disallowProperty(elementObject, "initializer", "A method descriptor");
6309 } else {
6310 this.disallowProperty(descriptor, "get", "The property descriptor of a field descriptor");
6311 this.disallowProperty(descriptor, "set", "The property descriptor of a field descriptor");
6312 this.disallowProperty(descriptor, "value", "The property descriptor of a field descriptor");
6313 element.initializer = elementObject.initializer;
6314 }
6315 return element;
6316 },
6317 toElementFinisherExtras: function (elementObject) {
6318 var element = this.toElementDescriptor(elementObject);
6319 var finisher = _optionalCallableProperty(elementObject, "finisher");
6320 var extras = this.toElementDescriptors(elementObject.extras);
6321 return {
6322 element: element,
6323 finisher: finisher,
6324 extras: extras
6325 };
6326 },
6327 fromClassDescriptor: function (elements) {
6328 var obj = {
6329 kind: "class",
6330 elements: elements.map(this.fromElementDescriptor, this)
6331 };
6332 var desc = {
6333 value: "Descriptor",
6334 configurable: true
6335 };
6336 Object.defineProperty(obj, Symbol.toStringTag, desc);
6337 return obj;
6338 },
6339 toClassDescriptor: function (obj) {
6340 var kind = String(obj.kind);
6341 if (kind !== "class") {
6342 throw new TypeError('A class descriptor\'s .kind property must be "class", but a decorator' + ' created a class descriptor with .kind "' + kind + '"');
6343 }
6344 this.disallowProperty(obj, "key", "A class descriptor");
6345 this.disallowProperty(obj, "placement", "A class descriptor");
6346 this.disallowProperty(obj, "descriptor", "A class descriptor");
6347 this.disallowProperty(obj, "initializer", "A class descriptor");
6348 this.disallowProperty(obj, "extras", "A class descriptor");
6349 var finisher = _optionalCallableProperty(obj, "finisher");
6350 var elements = this.toElementDescriptors(obj.elements);
6351 return {
6352 elements: elements,
6353 finisher: finisher
6354 };
6355 },
6356 runClassFinishers: function (constructor, finishers) {
6357 for (var i = 0; i < finishers.length; i++) {
6358 var newConstructor = (0, finishers[i])(constructor);
6359 if (newConstructor !== undefined) {
6360 if (typeof newConstructor !== "function") {
6361 throw new TypeError("Finishers must return a constructor.");
6362 }
6363 constructor = newConstructor;
6364 }
6365 }
6366 return constructor;
6367 },
6368 disallowProperty: function (obj, name, objectType) {
6369 if (obj[name] !== undefined) {
6370 throw new TypeError(objectType + " can't have a ." + name + " property.");
6371 }
6372 }
6373 };
6374 return api;
6375 }
6376 function _createElementDescriptor(def) {
6377 var key = _toPropertyKey(def.key);
6378 var descriptor;
6379 if (def.kind === "method") {
6380 descriptor = {
6381 value: def.value,
6382 writable: true,
6383 configurable: true,
6384 enumerable: false
6385 };
6386 } else if (def.kind === "get") {
6387 descriptor = {
6388 get: def.value,
6389 configurable: true,
6390 enumerable: false
6391 };
6392 } else if (def.kind === "set") {
6393 descriptor = {
6394 set: def.value,
6395 configurable: true,
6396 enumerable: false
6397 };
6398 } else if (def.kind === "field") {
6399 descriptor = {
6400 configurable: true,
6401 writable: true,
6402 enumerable: true
6403 };
6404 }
6405 var element = {
6406 kind: def.kind === "field" ? "field" : "method",
6407 key: key,
6408 placement: def.static ? "static" : def.kind === "field" ? "own" : "prototype",
6409 descriptor: descriptor
6410 };
6411 if (def.decorators) element.decorators = def.decorators;
6412 if (def.kind === "field") element.initializer = def.value;
6413 return element;
6414 }
6415 function _coalesceGetterSetter(element, other) {
6416 if (element.descriptor.get !== undefined) {
6417 other.descriptor.get = element.descriptor.get;
6418 } else {
6419 other.descriptor.set = element.descriptor.set;
6420 }
6421 }
6422 function _coalesceClassElements(elements) {
6423 var newElements = [];
6424 var isSameElement = function (other) {
6425 return other.kind === "method" && other.key === element.key && other.placement === element.placement;
6426 };
6427 for (var i = 0; i < elements.length; i++) {
6428 var element = elements[i];
6429 var other;
6430 if (element.kind === "method" && (other = newElements.find(isSameElement))) {
6431 if (_isDataDescriptor(element.descriptor) || _isDataDescriptor(other.descriptor)) {
6432 if (_hasDecorators(element) || _hasDecorators(other)) {
6433 throw new ReferenceError("Duplicated methods (" + element.key + ") can't be decorated.");
6434 }
6435 other.descriptor = element.descriptor;
6436 } else {
6437 if (_hasDecorators(element)) {
6438 if (_hasDecorators(other)) {
6439 throw new ReferenceError("Decorators can't be placed on different accessors with for " + "the same property (" + element.key + ").");
6440 }
6441 other.decorators = element.decorators;
6442 }
6443 _coalesceGetterSetter(element, other);
6444 }
6445 } else {
6446 newElements.push(element);
6447 }
6448 }
6449 return newElements;
6450 }
6451 function _hasDecorators(element) {
6452 return element.decorators && element.decorators.length;
6453 }
6454 function _isDataDescriptor(desc) {
6455 return desc !== undefined && !(desc.value === undefined && desc.writable === undefined);
6456 }
6457 function _optionalCallableProperty(obj, name) {
6458 var value = obj[name];
6459 if (value !== undefined && typeof value !== "function") {
6460 throw new TypeError("Expected '" + name + "' to be a function");
6461 }
6462 return value;
6463 }
6464 function _classPrivateMethodGet(receiver, privateSet, fn) {
6465 if (!privateSet.has(receiver)) {
6466 throw new TypeError("attempted to get private field on non-instance");
6467 }
6468 return fn;
6469 }
6470 function _checkPrivateRedeclaration(obj, privateCollection) {
6471 if (privateCollection.has(obj)) {
6472 throw new TypeError("Cannot initialize the same private elements twice on an object");
6473 }
6474 }
6475 function _classPrivateFieldInitSpec(obj, privateMap, value) {
6476 _checkPrivateRedeclaration(obj, privateMap);
6477 privateMap.set(obj, value);
6478 }
6479 function _classPrivateMethodInitSpec(obj, privateSet) {
6480 _checkPrivateRedeclaration(obj, privateSet);
6481 privateSet.add(obj);
6482 }
6483 function _classPrivateMethodSet() {
6484 throw new TypeError("attempted to reassign private method");
6485 }
6486 function _identity(x) {
6487 return x;
6488 }
6489 function _nullishReceiverError(r) {
6490 throw new TypeError("Cannot set property of null or undefined.");
6491 }
6492
6493 class Piece extends TrixObject {
6494 static registerType(type, constructor) {
6495 constructor.type = type;
6496 this.types[type] = constructor;
6497 }
6498 static fromJSON(pieceJSON) {
6499 const constructor = this.types[pieceJSON.type];
6500 if (constructor) {
6501 return constructor.fromJSON(pieceJSON);
6502 }
6503 }
6504 constructor(value) {
6505 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6506 super(...arguments);
6507 this.attributes = Hash.box(attributes);
6508 }
6509 copyWithAttributes(attributes) {
6510 return new this.constructor(this.getValue(), attributes);
6511 }
6512 copyWithAdditionalAttributes(attributes) {
6513 return this.copyWithAttributes(this.attributes.merge(attributes));
6514 }
6515 copyWithoutAttribute(attribute) {
6516 return this.copyWithAttributes(this.attributes.remove(attribute));
6517 }
6518 copy() {
6519 return this.copyWithAttributes(this.attributes);
6520 }
6521 getAttribute(attribute) {
6522 return this.attributes.get(attribute);
6523 }
6524 getAttributesHash() {
6525 return this.attributes;
6526 }
6527 getAttributes() {
6528 return this.attributes.toObject();
6529 }
6530 hasAttribute(attribute) {
6531 return this.attributes.has(attribute);
6532 }
6533 hasSameStringValueAsPiece(piece) {
6534 return piece && this.toString() === piece.toString();
6535 }
6536 hasSameAttributesAsPiece(piece) {
6537 return piece && (this.attributes === piece.attributes || this.attributes.isEqualTo(piece.attributes));
6538 }
6539 isBlockBreak() {
6540 return false;
6541 }
6542 isEqualTo(piece) {
6543 return super.isEqualTo(...arguments) || this.hasSameConstructorAs(piece) && this.hasSameStringValueAsPiece(piece) && this.hasSameAttributesAsPiece(piece);
6544 }
6545 isEmpty() {
6546 return this.length === 0;
6547 }
6548 isSerializable() {
6549 return true;
6550 }
6551 toJSON() {
6552 return {
6553 type: this.constructor.type,
6554 attributes: this.getAttributes()
6555 };
6556 }
6557 contentsForInspection() {
6558 return {
6559 type: this.constructor.type,
6560 attributes: this.attributes.inspect()
6561 };
6562 }
6563
6564 // Grouping
6565
6566 canBeGrouped() {
6567 return this.hasAttribute("href");
6568 }
6569 canBeGroupedWith(piece) {
6570 return this.getAttribute("href") === piece.getAttribute("href");
6571 }
6572
6573 // Splittable
6574
6575 getLength() {
6576 return this.length;
6577 }
6578 canBeConsolidatedWith(piece) {
6579 return false;
6580 }
6581 }
6582 _defineProperty(Piece, "types", {});
6583
6584 class ImagePreloadOperation extends Operation {
6585 constructor(url) {
6586 super(...arguments);
6587 this.url = url;
6588 }
6589 perform(callback) {
6590 const image = new Image();
6591 image.onload = () => {
6592 image.width = this.width = image.naturalWidth;
6593 image.height = this.height = image.naturalHeight;
6594 return callback(true, image);
6595 };
6596 image.onerror = () => callback(false);
6597 image.src = this.url;
6598 }
6599 }
6600
6601 class Attachment extends TrixObject {
6602 static attachmentForFile(file) {
6603 const attributes = this.attributesForFile(file);
6604 const attachment = new this(attributes);
6605 attachment.setFile(file);
6606 return attachment;
6607 }
6608 static attributesForFile(file) {
6609 return new Hash({
6610 filename: file.name,
6611 filesize: file.size,
6612 contentType: file.type
6613 });
6614 }
6615 static fromJSON(attachmentJSON) {
6616 return new this(attachmentJSON);
6617 }
6618 constructor() {
6619 let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6620 super(attributes);
6621 this.releaseFile = this.releaseFile.bind(this);
6622 this.attributes = Hash.box(attributes);
6623 this.didChangeAttributes();
6624 }
6625 getAttribute(attribute) {
6626 return this.attributes.get(attribute);
6627 }
6628 hasAttribute(attribute) {
6629 return this.attributes.has(attribute);
6630 }
6631 getAttributes() {
6632 return this.attributes.toObject();
6633 }
6634 setAttributes() {
6635 let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6636 const newAttributes = this.attributes.merge(attributes);
6637 if (!this.attributes.isEqualTo(newAttributes)) {
6638 var _this$previewDelegate, _this$previewDelegate2, _this$delegate, _this$delegate$attach;
6639 this.attributes = newAttributes;
6640 this.didChangeAttributes();
6641 (_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);
6642 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);
6643 }
6644 }
6645 didChangeAttributes() {
6646 if (this.isPreviewable()) {
6647 return this.preloadURL();
6648 }
6649 }
6650 isPending() {
6651 return this.file != null && !(this.getURL() || this.getHref());
6652 }
6653 isPreviewable() {
6654 if (this.attributes.has("previewable")) {
6655 return this.attributes.get("previewable");
6656 } else {
6657 return Attachment.previewablePattern.test(this.getContentType());
6658 }
6659 }
6660 getType() {
6661 if (this.hasContent()) {
6662 return "content";
6663 } else if (this.isPreviewable()) {
6664 return "preview";
6665 } else {
6666 return "file";
6667 }
6668 }
6669 getURL() {
6670 return this.attributes.get("url");
6671 }
6672 getHref() {
6673 return this.attributes.get("href");
6674 }
6675 getFilename() {
6676 return this.attributes.get("filename") || "";
6677 }
6678 getFilesize() {
6679 return this.attributes.get("filesize");
6680 }
6681 getFormattedFilesize() {
6682 const filesize = this.attributes.get("filesize");
6683 if (typeof filesize === "number") {
6684 return file_size_formatting.formatter(filesize);
6685 } else {
6686 return "";
6687 }
6688 }
6689 getExtension() {
6690 var _this$getFilename$mat;
6691 return (_this$getFilename$mat = this.getFilename().match(/\.(\w+)$/)) === null || _this$getFilename$mat === void 0 ? void 0 : _this$getFilename$mat[1].toLowerCase();
6692 }
6693 getContentType() {
6694 return this.attributes.get("contentType");
6695 }
6696 hasContent() {
6697 return this.attributes.has("content");
6698 }
6699 getContent() {
6700 return this.attributes.get("content");
6701 }
6702 getWidth() {
6703 return this.attributes.get("width");
6704 }
6705 getHeight() {
6706 return this.attributes.get("height");
6707 }
6708 getFile() {
6709 return this.file;
6710 }
6711 setFile(file) {
6712 this.file = file;
6713 if (this.isPreviewable()) {
6714 return this.preloadFile();
6715 }
6716 }
6717 releaseFile() {
6718 this.releasePreloadedFile();
6719 this.file = null;
6720 }
6721 getUploadProgress() {
6722 return this.uploadProgress != null ? this.uploadProgress : 0;
6723 }
6724 setUploadProgress(value) {
6725 if (this.uploadProgress !== value) {
6726 var _this$uploadProgressD, _this$uploadProgressD2;
6727 this.uploadProgress = value;
6728 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);
6729 }
6730 }
6731 toJSON() {
6732 return this.getAttributes();
6733 }
6734 getCacheKey() {
6735 return [super.getCacheKey(...arguments), this.attributes.getCacheKey(), this.getPreviewURL()].join("/");
6736 }
6737
6738 // Previewable
6739
6740 getPreviewURL() {
6741 return this.previewURL || this.preloadingURL;
6742 }
6743 setPreviewURL(url) {
6744 if (url !== this.getPreviewURL()) {
6745 var _this$previewDelegate3, _this$previewDelegate4, _this$delegate2, _this$delegate2$attac;
6746 this.previewURL = url;
6747 (_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);
6748 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);
6749 }
6750 }
6751 preloadURL() {
6752 return this.preload(this.getURL(), this.releaseFile);
6753 }
6754 preloadFile() {
6755 if (this.file) {
6756 this.fileObjectURL = URL.createObjectURL(this.file);
6757 return this.preload(this.fileObjectURL);
6758 }
6759 }
6760 releasePreloadedFile() {
6761 if (this.fileObjectURL) {
6762 URL.revokeObjectURL(this.fileObjectURL);
6763 this.fileObjectURL = null;
6764 }
6765 }
6766 preload(url, callback) {
6767 if (url && url !== this.getPreviewURL()) {
6768 this.preloadingURL = url;
6769 const operation = new ImagePreloadOperation(url);
6770 return operation.then(_ref => {
6771 let {
6772 width,
6773 height
6774 } = _ref;
6775 if (!this.getWidth() || !this.getHeight()) {
6776 this.setAttributes({
6777 width,
6778 height
6779 });
6780 }
6781 this.preloadingURL = null;
6782 this.setPreviewURL(url);
6783 return callback === null || callback === void 0 ? void 0 : callback();
6784 }).catch(() => {
6785 this.preloadingURL = null;
6786 return callback === null || callback === void 0 ? void 0 : callback();
6787 });
6788 }
6789 }
6790 }
6791 _defineProperty(Attachment, "previewablePattern", /^image(\/(gif|png|webp|jpe?g)|$)/);
6792
6793 class AttachmentPiece extends Piece {
6794 static fromJSON(pieceJSON) {
6795 return new this(Attachment.fromJSON(pieceJSON.attachment), pieceJSON.attributes);
6796 }
6797 constructor(attachment) {
6798 super(...arguments);
6799 this.attachment = attachment;
6800 this.length = 1;
6801 this.ensureAttachmentExclusivelyHasAttribute("href");
6802 if (!this.attachment.hasContent()) {
6803 this.removeProhibitedAttributes();
6804 }
6805 }
6806 ensureAttachmentExclusivelyHasAttribute(attribute) {
6807 if (this.hasAttribute(attribute)) {
6808 if (!this.attachment.hasAttribute(attribute)) {
6809 this.attachment.setAttributes(this.attributes.slice([attribute]));
6810 }
6811 this.attributes = this.attributes.remove(attribute);
6812 }
6813 }
6814 removeProhibitedAttributes() {
6815 const attributes = this.attributes.slice(AttachmentPiece.permittedAttributes);
6816 if (!attributes.isEqualTo(this.attributes)) {
6817 this.attributes = attributes;
6818 }
6819 }
6820 getValue() {
6821 return this.attachment;
6822 }
6823 isSerializable() {
6824 return !this.attachment.isPending();
6825 }
6826 getCaption() {
6827 return this.attributes.get("caption") || "";
6828 }
6829 isEqualTo(piece) {
6830 var _piece$attachment;
6831 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);
6832 }
6833 toString() {
6834 return OBJECT_REPLACEMENT_CHARACTER;
6835 }
6836 toJSON() {
6837 const json = super.toJSON(...arguments);
6838 json.attachment = this.attachment;
6839 return json;
6840 }
6841 getCacheKey() {
6842 return [super.getCacheKey(...arguments), this.attachment.getCacheKey()].join("/");
6843 }
6844 toConsole() {
6845 return JSON.stringify(this.toString());
6846 }
6847 }
6848 _defineProperty(AttachmentPiece, "permittedAttributes", ["caption", "presentation"]);
6849 Piece.registerType("attachment", AttachmentPiece);
6850
6851 class StringPiece extends Piece {
6852 static fromJSON(pieceJSON) {
6853 return new this(pieceJSON.string, pieceJSON.attributes);
6854 }
6855 constructor(string) {
6856 super(...arguments);
6857 this.string = normalizeNewlines(string);
6858 this.length = this.string.length;
6859 }
6860 getValue() {
6861 return this.string;
6862 }
6863 toString() {
6864 return this.string.toString();
6865 }
6866 isBlockBreak() {
6867 return this.toString() === "\n" && this.getAttribute("blockBreak") === true;
6868 }
6869 toJSON() {
6870 const result = super.toJSON(...arguments);
6871 result.string = this.string;
6872 return result;
6873 }
6874
6875 // Splittable
6876
6877 canBeConsolidatedWith(piece) {
6878 return piece && this.hasSameConstructorAs(piece) && this.hasSameAttributesAsPiece(piece);
6879 }
6880 consolidateWith(piece) {
6881 return new this.constructor(this.toString() + piece.toString(), this.attributes);
6882 }
6883 splitAtOffset(offset) {
6884 let left, right;
6885 if (offset === 0) {
6886 left = null;
6887 right = this;
6888 } else if (offset === this.length) {
6889 left = this;
6890 right = null;
6891 } else {
6892 left = new this.constructor(this.string.slice(0, offset), this.attributes);
6893 right = new this.constructor(this.string.slice(offset), this.attributes);
6894 }
6895 return [left, right];
6896 }
6897 toConsole() {
6898 let {
6899 string
6900 } = this;
6901 if (string.length > 15) {
6902 string = string.slice(0, 14) + "…";
6903 }
6904 return JSON.stringify(string.toString());
6905 }
6906 }
6907 Piece.registerType("string", StringPiece);
6908
6909 /* eslint-disable
6910 prefer-const,
6911 */
6912 class SplittableList extends TrixObject {
6913 static box(objects) {
6914 if (objects instanceof this) {
6915 return objects;
6916 } else {
6917 return new this(objects);
6918 }
6919 }
6920 constructor() {
6921 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
6922 super(...arguments);
6923 this.objects = objects.slice(0);
6924 this.length = this.objects.length;
6925 }
6926 indexOf(object) {
6927 return this.objects.indexOf(object);
6928 }
6929 splice() {
6930 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
6931 args[_key] = arguments[_key];
6932 }
6933 return new this.constructor(spliceArray(this.objects, ...args));
6934 }
6935 eachObject(callback) {
6936 return this.objects.map((object, index) => callback(object, index));
6937 }
6938 insertObjectAtIndex(object, index) {
6939 return this.splice(index, 0, object);
6940 }
6941 insertSplittableListAtIndex(splittableList, index) {
6942 return this.splice(index, 0, ...splittableList.objects);
6943 }
6944 insertSplittableListAtPosition(splittableList, position) {
6945 const [objects, index] = this.splitObjectAtPosition(position);
6946 return new this.constructor(objects).insertSplittableListAtIndex(splittableList, index);
6947 }
6948 editObjectAtIndex(index, callback) {
6949 return this.replaceObjectAtIndex(callback(this.objects[index]), index);
6950 }
6951 replaceObjectAtIndex(object, index) {
6952 return this.splice(index, 1, object);
6953 }
6954 removeObjectAtIndex(index) {
6955 return this.splice(index, 1);
6956 }
6957 getObjectAtIndex(index) {
6958 return this.objects[index];
6959 }
6960 getSplittableListInRange(range) {
6961 const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range);
6962 return new this.constructor(objects.slice(leftIndex, rightIndex + 1));
6963 }
6964 selectSplittableList(test) {
6965 const objects = this.objects.filter(object => test(object));
6966 return new this.constructor(objects);
6967 }
6968 removeObjectsInRange(range) {
6969 const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range);
6970 return new this.constructor(objects).splice(leftIndex, rightIndex - leftIndex + 1);
6971 }
6972 transformObjectsInRange(range, transform) {
6973 const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range);
6974 const transformedObjects = objects.map((object, index) => leftIndex <= index && index <= rightIndex ? transform(object) : object);
6975 return new this.constructor(transformedObjects);
6976 }
6977 splitObjectsAtRange(range) {
6978 let rightOuterIndex;
6979 let [objects, leftInnerIndex, offset] = this.splitObjectAtPosition(startOfRange(range));
6980 [objects, rightOuterIndex] = new this.constructor(objects).splitObjectAtPosition(endOfRange(range) + offset);
6981 return [objects, leftInnerIndex, rightOuterIndex - 1];
6982 }
6983 getObjectAtPosition(position) {
6984 const {
6985 index
6986 } = this.findIndexAndOffsetAtPosition(position);
6987 return this.objects[index];
6988 }
6989 splitObjectAtPosition(position) {
6990 let splitIndex, splitOffset;
6991 const {
6992 index,
6993 offset
6994 } = this.findIndexAndOffsetAtPosition(position);
6995 const objects = this.objects.slice(0);
6996 if (index != null) {
6997 if (offset === 0) {
6998 splitIndex = index;
6999 splitOffset = 0;
7000 } else {
7001 const object = this.getObjectAtIndex(index);
7002 const [leftObject, rightObject] = object.splitAtOffset(offset);
7003 objects.splice(index, 1, leftObject, rightObject);
7004 splitIndex = index + 1;
7005 splitOffset = leftObject.getLength() - offset;
7006 }
7007 } else {
7008 splitIndex = objects.length;
7009 splitOffset = 0;
7010 }
7011 return [objects, splitIndex, splitOffset];
7012 }
7013 consolidate() {
7014 const objects = [];
7015 let pendingObject = this.objects[0];
7016 this.objects.slice(1).forEach(object => {
7017 var _pendingObject$canBeC, _pendingObject;
7018 if ((_pendingObject$canBeC = (_pendingObject = pendingObject).canBeConsolidatedWith) !== null && _pendingObject$canBeC !== void 0 && _pendingObject$canBeC.call(_pendingObject, object)) {
7019 pendingObject = pendingObject.consolidateWith(object);
7020 } else {
7021 objects.push(pendingObject);
7022 pendingObject = object;
7023 }
7024 });
7025 if (pendingObject) {
7026 objects.push(pendingObject);
7027 }
7028 return new this.constructor(objects);
7029 }
7030 consolidateFromIndexToIndex(startIndex, endIndex) {
7031 const objects = this.objects.slice(0);
7032 const objectsInRange = objects.slice(startIndex, endIndex + 1);
7033 const consolidatedInRange = new this.constructor(objectsInRange).consolidate().toArray();
7034 return this.splice(startIndex, objectsInRange.length, ...consolidatedInRange);
7035 }
7036 findIndexAndOffsetAtPosition(position) {
7037 let index;
7038 let currentPosition = 0;
7039 for (index = 0; index < this.objects.length; index++) {
7040 const object = this.objects[index];
7041 const nextPosition = currentPosition + object.getLength();
7042 if (currentPosition <= position && position < nextPosition) {
7043 return {
7044 index,
7045 offset: position - currentPosition
7046 };
7047 }
7048 currentPosition = nextPosition;
7049 }
7050 return {
7051 index: null,
7052 offset: null
7053 };
7054 }
7055 findPositionAtIndexAndOffset(index, offset) {
7056 let position = 0;
7057 for (let currentIndex = 0; currentIndex < this.objects.length; currentIndex++) {
7058 const object = this.objects[currentIndex];
7059 if (currentIndex < index) {
7060 position += object.getLength();
7061 } else if (currentIndex === index) {
7062 position += offset;
7063 break;
7064 }
7065 }
7066 return position;
7067 }
7068 getEndPosition() {
7069 if (this.endPosition == null) {
7070 this.endPosition = 0;
7071 this.objects.forEach(object => this.endPosition += object.getLength());
7072 }
7073 return this.endPosition;
7074 }
7075 toString() {
7076 return this.objects.join("");
7077 }
7078 toArray() {
7079 return this.objects.slice(0);
7080 }
7081 toJSON() {
7082 return this.toArray();
7083 }
7084 isEqualTo(splittableList) {
7085 return super.isEqualTo(...arguments) || objectArraysAreEqual(this.objects, splittableList === null || splittableList === void 0 ? void 0 : splittableList.objects);
7086 }
7087 contentsForInspection() {
7088 return {
7089 objects: "[".concat(this.objects.map(object => object.inspect()).join(", "), "]")
7090 };
7091 }
7092 }
7093 const objectArraysAreEqual = function (left) {
7094 let right = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
7095 if (left.length !== right.length) {
7096 return false;
7097 }
7098 let result = true;
7099 for (let index = 0; index < left.length; index++) {
7100 const object = left[index];
7101 if (result && !object.isEqualTo(right[index])) {
7102 result = false;
7103 }
7104 }
7105 return result;
7106 };
7107 const startOfRange = range => range[0];
7108 const endOfRange = range => range[1];
7109
7110 class Text extends TrixObject {
7111 static textForAttachmentWithAttributes(attachment, attributes) {
7112 const piece = new AttachmentPiece(attachment, attributes);
7113 return new this([piece]);
7114 }
7115 static textForStringWithAttributes(string, attributes) {
7116 const piece = new StringPiece(string, attributes);
7117 return new this([piece]);
7118 }
7119 static fromJSON(textJSON) {
7120 const pieces = Array.from(textJSON).map(pieceJSON => Piece.fromJSON(pieceJSON));
7121 return new this(pieces);
7122 }
7123 constructor() {
7124 let pieces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
7125 super(...arguments);
7126 const notEmpty = pieces.filter(piece => !piece.isEmpty());
7127 this.pieceList = new SplittableList(notEmpty);
7128 }
7129 copy() {
7130 return this.copyWithPieceList(this.pieceList);
7131 }
7132 copyWithPieceList(pieceList) {
7133 return new this.constructor(pieceList.consolidate().toArray());
7134 }
7135 copyUsingObjectMap(objectMap) {
7136 const pieces = this.getPieces().map(piece => objectMap.find(piece) || piece);
7137 return new this.constructor(pieces);
7138 }
7139 appendText(text) {
7140 return this.insertTextAtPosition(text, this.getLength());
7141 }
7142 insertTextAtPosition(text, position) {
7143 return this.copyWithPieceList(this.pieceList.insertSplittableListAtPosition(text.pieceList, position));
7144 }
7145 removeTextAtRange(range) {
7146 return this.copyWithPieceList(this.pieceList.removeObjectsInRange(range));
7147 }
7148 replaceTextAtRange(text, range) {
7149 return this.removeTextAtRange(range).insertTextAtPosition(text, range[0]);
7150 }
7151 moveTextFromRangeToPosition(range, position) {
7152 if (range[0] <= position && position <= range[1]) return;
7153 const text = this.getTextAtRange(range);
7154 const length = text.getLength();
7155 if (range[0] < position) {
7156 position -= length;
7157 }
7158 return this.removeTextAtRange(range).insertTextAtPosition(text, position);
7159 }
7160 addAttributeAtRange(attribute, value, range) {
7161 const attributes = {};
7162 attributes[attribute] = value;
7163 return this.addAttributesAtRange(attributes, range);
7164 }
7165 addAttributesAtRange(attributes, range) {
7166 return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithAdditionalAttributes(attributes)));
7167 }
7168 removeAttributeAtRange(attribute, range) {
7169 return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithoutAttribute(attribute)));
7170 }
7171 setAttributesAtRange(attributes, range) {
7172 return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithAttributes(attributes)));
7173 }
7174 getAttributesAtPosition(position) {
7175 var _this$pieceList$getOb;
7176 return ((_this$pieceList$getOb = this.pieceList.getObjectAtPosition(position)) === null || _this$pieceList$getOb === void 0 ? void 0 : _this$pieceList$getOb.getAttributes()) || {};
7177 }
7178 getCommonAttributes() {
7179 const objects = Array.from(this.pieceList.toArray()).map(piece => piece.getAttributes());
7180 return Hash.fromCommonAttributesOfObjects(objects).toObject();
7181 }
7182 getCommonAttributesAtRange(range) {
7183 return this.getTextAtRange(range).getCommonAttributes() || {};
7184 }
7185 getExpandedRangeForAttributeAtOffset(attributeName, offset) {
7186 let right;
7187 let left = right = offset;
7188 const length = this.getLength();
7189 while (left > 0 && this.getCommonAttributesAtRange([left - 1, right])[attributeName]) {
7190 left--;
7191 }
7192 while (right < length && this.getCommonAttributesAtRange([offset, right + 1])[attributeName]) {
7193 right++;
7194 }
7195 return [left, right];
7196 }
7197 getTextAtRange(range) {
7198 return this.copyWithPieceList(this.pieceList.getSplittableListInRange(range));
7199 }
7200 getStringAtRange(range) {
7201 return this.pieceList.getSplittableListInRange(range).toString();
7202 }
7203 getStringAtPosition(position) {
7204 return this.getStringAtRange([position, position + 1]);
7205 }
7206 startsWithString(string) {
7207 return this.getStringAtRange([0, string.length]) === string;
7208 }
7209 endsWithString(string) {
7210 const length = this.getLength();
7211 return this.getStringAtRange([length - string.length, length]) === string;
7212 }
7213 getAttachmentPieces() {
7214 return this.pieceList.toArray().filter(piece => !!piece.attachment);
7215 }
7216 getAttachments() {
7217 return this.getAttachmentPieces().map(piece => piece.attachment);
7218 }
7219 getAttachmentAndPositionById(attachmentId) {
7220 let position = 0;
7221 for (const piece of this.pieceList.toArray()) {
7222 var _piece$attachment;
7223 if (((_piece$attachment = piece.attachment) === null || _piece$attachment === void 0 ? void 0 : _piece$attachment.id) === attachmentId) {
7224 return {
7225 attachment: piece.attachment,
7226 position
7227 };
7228 }
7229 position += piece.length;
7230 }
7231 return {
7232 attachment: null,
7233 position: null
7234 };
7235 }
7236 getAttachmentById(attachmentId) {
7237 const {
7238 attachment
7239 } = this.getAttachmentAndPositionById(attachmentId);
7240 return attachment;
7241 }
7242 getRangeOfAttachment(attachment) {
7243 const attachmentAndPosition = this.getAttachmentAndPositionById(attachment.id);
7244 const position = attachmentAndPosition.position;
7245 attachment = attachmentAndPosition.attachment;
7246 if (attachment) {
7247 return [position, position + 1];
7248 }
7249 }
7250 updateAttributesForAttachment(attributes, attachment) {
7251 const range = this.getRangeOfAttachment(attachment);
7252 if (range) {
7253 return this.addAttributesAtRange(attributes, range);
7254 } else {
7255 return this;
7256 }
7257 }
7258 getLength() {
7259 return this.pieceList.getEndPosition();
7260 }
7261 isEmpty() {
7262 return this.getLength() === 0;
7263 }
7264 isEqualTo(text) {
7265 var _text$pieceList;
7266 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));
7267 }
7268 isBlockBreak() {
7269 return this.getLength() === 1 && this.pieceList.getObjectAtIndex(0).isBlockBreak();
7270 }
7271 eachPiece(callback) {
7272 return this.pieceList.eachObject(callback);
7273 }
7274 getPieces() {
7275 return this.pieceList.toArray();
7276 }
7277 getPieceAtPosition(position) {
7278 return this.pieceList.getObjectAtPosition(position);
7279 }
7280 contentsForInspection() {
7281 return {
7282 pieceList: this.pieceList.inspect()
7283 };
7284 }
7285 toSerializableText() {
7286 const pieceList = this.pieceList.selectSplittableList(piece => piece.isSerializable());
7287 return this.copyWithPieceList(pieceList);
7288 }
7289 toString() {
7290 return this.pieceList.toString();
7291 }
7292 toJSON() {
7293 return this.pieceList.toJSON();
7294 }
7295 toConsole() {
7296 return JSON.stringify(this.pieceList.toArray().map(piece => JSON.parse(piece.toConsole())));
7297 }
7298
7299 // BIDI
7300
7301 getDirection() {
7302 return getDirection(this.toString());
7303 }
7304 isRTL() {
7305 return this.getDirection() === "rtl";
7306 }
7307 }
7308
7309 class Block extends TrixObject {
7310 static fromJSON(blockJSON) {
7311 const text = Text.fromJSON(blockJSON.text);
7312 return new this(text, blockJSON.attributes, blockJSON.htmlAttributes);
7313 }
7314 constructor(text, attributes, htmlAttributes) {
7315 super(...arguments);
7316 this.text = applyBlockBreakToText(text || new Text());
7317 this.attributes = attributes || [];
7318 this.htmlAttributes = htmlAttributes || {};
7319 }
7320 isEmpty() {
7321 return this.text.isBlockBreak();
7322 }
7323 isEqualTo(block) {
7324 if (super.isEqualTo(block)) return true;
7325 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);
7326 }
7327 copyWithText(text) {
7328 return new Block(text, this.attributes, this.htmlAttributes);
7329 }
7330 copyWithoutText() {
7331 return this.copyWithText(null);
7332 }
7333 copyWithAttributes(attributes) {
7334 return new Block(this.text, attributes, this.htmlAttributes);
7335 }
7336 copyWithoutAttributes() {
7337 return this.copyWithAttributes(null);
7338 }
7339 copyUsingObjectMap(objectMap) {
7340 const mappedText = objectMap.find(this.text);
7341 if (mappedText) {
7342 return this.copyWithText(mappedText);
7343 } else {
7344 return this.copyWithText(this.text.copyUsingObjectMap(objectMap));
7345 }
7346 }
7347 addAttribute(attribute) {
7348 const attributes = this.attributes.concat(expandAttribute(attribute));
7349 return this.copyWithAttributes(attributes);
7350 }
7351 addHTMLAttribute(attribute, value) {
7352 const htmlAttributes = Object.assign({}, this.htmlAttributes, {
7353 [attribute]: value
7354 });
7355 return new Block(this.text, this.attributes, htmlAttributes);
7356 }
7357 removeAttribute(attribute) {
7358 const {
7359 listAttribute
7360 } = getBlockConfig(attribute);
7361 const attributes = removeLastValue(removeLastValue(this.attributes, attribute), listAttribute);
7362 return this.copyWithAttributes(attributes);
7363 }
7364 removeLastAttribute() {
7365 return this.removeAttribute(this.getLastAttribute());
7366 }
7367 getLastAttribute() {
7368 return getLastElement(this.attributes);
7369 }
7370 getAttributes() {
7371 return this.attributes.slice(0);
7372 }
7373 getAttributeLevel() {
7374 return this.attributes.length;
7375 }
7376 getAttributeAtLevel(level) {
7377 return this.attributes[level - 1];
7378 }
7379 hasAttribute(attributeName) {
7380 return this.attributes.includes(attributeName);
7381 }
7382 hasAttributes() {
7383 return this.getAttributeLevel() > 0;
7384 }
7385 getLastNestableAttribute() {
7386 return getLastElement(this.getNestableAttributes());
7387 }
7388 getNestableAttributes() {
7389 return this.attributes.filter(attribute => getBlockConfig(attribute).nestable);
7390 }
7391 getNestingLevel() {
7392 return this.getNestableAttributes().length;
7393 }
7394 decreaseNestingLevel() {
7395 const attribute = this.getLastNestableAttribute();
7396 if (attribute) {
7397 return this.removeAttribute(attribute);
7398 } else {
7399 return this;
7400 }
7401 }
7402 increaseNestingLevel() {
7403 const attribute = this.getLastNestableAttribute();
7404 if (attribute) {
7405 const index = this.attributes.lastIndexOf(attribute);
7406 const attributes = spliceArray(this.attributes, index + 1, 0, ...expandAttribute(attribute));
7407 return this.copyWithAttributes(attributes);
7408 } else {
7409 return this;
7410 }
7411 }
7412 getListItemAttributes() {
7413 return this.attributes.filter(attribute => getBlockConfig(attribute).listAttribute);
7414 }
7415 isListItem() {
7416 var _getBlockConfig;
7417 return (_getBlockConfig = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.listAttribute;
7418 }
7419 isTerminalBlock() {
7420 var _getBlockConfig2;
7421 return (_getBlockConfig2 = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig2 === void 0 ? void 0 : _getBlockConfig2.terminal;
7422 }
7423 breaksOnReturn() {
7424 var _getBlockConfig3;
7425 return (_getBlockConfig3 = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig3 === void 0 ? void 0 : _getBlockConfig3.breakOnReturn;
7426 }
7427 findLineBreakInDirectionFromPosition(direction, position) {
7428 const string = this.toString();
7429 let result;
7430 switch (direction) {
7431 case "forward":
7432 result = string.indexOf("\n", position);
7433 break;
7434 case "backward":
7435 result = string.slice(0, position).lastIndexOf("\n");
7436 }
7437 if (result !== -1) {
7438 return result;
7439 }
7440 }
7441 contentsForInspection() {
7442 return {
7443 text: this.text.inspect(),
7444 attributes: this.attributes
7445 };
7446 }
7447 toString() {
7448 return this.text.toString();
7449 }
7450 toJSON() {
7451 return {
7452 text: this.text,
7453 attributes: this.attributes,
7454 htmlAttributes: this.htmlAttributes
7455 };
7456 }
7457
7458 // BIDI
7459
7460 getDirection() {
7461 return this.text.getDirection();
7462 }
7463 isRTL() {
7464 return this.text.isRTL();
7465 }
7466
7467 // Splittable
7468
7469 getLength() {
7470 return this.text.getLength();
7471 }
7472 canBeConsolidatedWith(block) {
7473 return !this.hasAttributes() && !block.hasAttributes() && this.getDirection() === block.getDirection();
7474 }
7475 consolidateWith(block) {
7476 const newlineText = Text.textForStringWithAttributes("\n");
7477 const text = this.getTextWithoutBlockBreak().appendText(newlineText);
7478 return this.copyWithText(text.appendText(block.text));
7479 }
7480 splitAtOffset(offset) {
7481 let left, right;
7482 if (offset === 0) {
7483 left = null;
7484 right = this;
7485 } else if (offset === this.getLength()) {
7486 left = this;
7487 right = null;
7488 } else {
7489 left = this.copyWithText(this.text.getTextAtRange([0, offset]));
7490 right = this.copyWithText(this.text.getTextAtRange([offset, this.getLength()]));
7491 }
7492 return [left, right];
7493 }
7494 getBlockBreakPosition() {
7495 return this.text.getLength() - 1;
7496 }
7497 getTextWithoutBlockBreak() {
7498 if (textEndsInBlockBreak(this.text)) {
7499 return this.text.getTextAtRange([0, this.getBlockBreakPosition()]);
7500 } else {
7501 return this.text.copy();
7502 }
7503 }
7504
7505 // Grouping
7506
7507 canBeGrouped(depth) {
7508 return this.attributes[depth];
7509 }
7510 canBeGroupedWith(otherBlock, depth) {
7511 const otherAttributes = otherBlock.getAttributes();
7512 const otherAttribute = otherAttributes[depth];
7513 const attribute = this.attributes[depth];
7514 return attribute === otherAttribute && !(getBlockConfig(attribute).group === false && !getListAttributeNames().includes(otherAttributes[depth + 1])) && (this.getDirection() === otherBlock.getDirection() || otherBlock.isEmpty());
7515 }
7516 }
7517
7518 // Block breaks
7519
7520 const applyBlockBreakToText = function (text) {
7521 text = unmarkExistingInnerBlockBreaksInText(text);
7522 text = addBlockBreakToText(text);
7523 return text;
7524 };
7525 const unmarkExistingInnerBlockBreaksInText = function (text) {
7526 let modified = false;
7527 const pieces = text.getPieces();
7528 let innerPieces = pieces.slice(0, pieces.length - 1);
7529 const lastPiece = pieces[pieces.length - 1];
7530 if (!lastPiece) return text;
7531 innerPieces = innerPieces.map(piece => {
7532 if (piece.isBlockBreak()) {
7533 modified = true;
7534 return unmarkBlockBreakPiece(piece);
7535 } else {
7536 return piece;
7537 }
7538 });
7539 if (modified) {
7540 return new Text([...innerPieces, lastPiece]);
7541 } else {
7542 return text;
7543 }
7544 };
7545 const blockBreakText = Text.textForStringWithAttributes("\n", {
7546 blockBreak: true
7547 });
7548 const addBlockBreakToText = function (text) {
7549 if (textEndsInBlockBreak(text)) {
7550 return text;
7551 } else {
7552 return text.appendText(blockBreakText);
7553 }
7554 };
7555 const textEndsInBlockBreak = function (text) {
7556 const length = text.getLength();
7557 if (length === 0) {
7558 return false;
7559 }
7560 const endText = text.getTextAtRange([length - 1, length]);
7561 return endText.isBlockBreak();
7562 };
7563 const unmarkBlockBreakPiece = piece => piece.copyWithoutAttribute("blockBreak");
7564
7565 // Attributes
7566
7567 const expandAttribute = function (attribute) {
7568 const {
7569 listAttribute
7570 } = getBlockConfig(attribute);
7571 if (listAttribute) {
7572 return [listAttribute, attribute];
7573 } else {
7574 return [attribute];
7575 }
7576 };
7577
7578 // Array helpers
7579
7580 const getLastElement = array => array.slice(-1)[0];
7581 const removeLastValue = function (array, value) {
7582 const index = array.lastIndexOf(value);
7583 if (index === -1) {
7584 return array;
7585 } else {
7586 return spliceArray(array, index, 1);
7587 }
7588 };
7589
7590 class Document extends TrixObject {
7591 static fromJSON(documentJSON) {
7592 const blocks = Array.from(documentJSON).map(blockJSON => Block.fromJSON(blockJSON));
7593 return new this(blocks);
7594 }
7595 static fromString(string, textAttributes) {
7596 const text = Text.textForStringWithAttributes(string, textAttributes);
7597 return new this([new Block(text)]);
7598 }
7599 constructor() {
7600 let blocks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
7601 super(...arguments);
7602 if (blocks.length === 0) {
7603 blocks = [new Block()];
7604 }
7605 this.blockList = SplittableList.box(blocks);
7606 }
7607 isEmpty() {
7608 const block = this.getBlockAtIndex(0);
7609 return this.blockList.length === 1 && block.isEmpty() && !block.hasAttributes();
7610 }
7611 copy() {
7612 let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
7613 const blocks = options.consolidateBlocks ? this.blockList.consolidate().toArray() : this.blockList.toArray();
7614 return new this.constructor(blocks);
7615 }
7616 copyUsingObjectsFromDocument(sourceDocument) {
7617 const objectMap = new ObjectMap(sourceDocument.getObjects());
7618 return this.copyUsingObjectMap(objectMap);
7619 }
7620 copyUsingObjectMap(objectMap) {
7621 const blocks = this.getBlocks().map(block => {
7622 const mappedBlock = objectMap.find(block);
7623 return mappedBlock || block.copyUsingObjectMap(objectMap);
7624 });
7625 return new this.constructor(blocks);
7626 }
7627 copyWithBaseBlockAttributes() {
7628 let blockAttributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
7629 const blocks = this.getBlocks().map(block => {
7630 const attributes = blockAttributes.concat(block.getAttributes());
7631 return block.copyWithAttributes(attributes);
7632 });
7633 return new this.constructor(blocks);
7634 }
7635 replaceBlock(oldBlock, newBlock) {
7636 const index = this.blockList.indexOf(oldBlock);
7637 if (index === -1) {
7638 return this;
7639 }
7640 return new this.constructor(this.blockList.replaceObjectAtIndex(newBlock, index));
7641 }
7642 insertDocumentAtRange(document, range) {
7643 const {
7644 blockList
7645 } = document;
7646 range = normalizeRange(range);
7647 let [position] = range;
7648 const {
7649 index,
7650 offset
7651 } = this.locationFromPosition(position);
7652 let result = this;
7653 const block = this.getBlockAtPosition(position);
7654 if (rangeIsCollapsed(range) && block.isEmpty() && !block.hasAttributes()) {
7655 result = new this.constructor(result.blockList.removeObjectAtIndex(index));
7656 } else if (block.getBlockBreakPosition() === offset) {
7657 position++;
7658 }
7659 result = result.removeTextAtRange(range);
7660 return new this.constructor(result.blockList.insertSplittableListAtPosition(blockList, position));
7661 }
7662 mergeDocumentAtRange(document, range) {
7663 let formattedDocument, result;
7664 range = normalizeRange(range);
7665 const [startPosition] = range;
7666 const startLocation = this.locationFromPosition(startPosition);
7667 const blockAttributes = this.getBlockAtIndex(startLocation.index).getAttributes();
7668 const baseBlockAttributes = document.getBaseBlockAttributes();
7669 const trailingBlockAttributes = blockAttributes.slice(-baseBlockAttributes.length);
7670 if (arraysAreEqual(baseBlockAttributes, trailingBlockAttributes)) {
7671 const leadingBlockAttributes = blockAttributes.slice(0, -baseBlockAttributes.length);
7672 formattedDocument = document.copyWithBaseBlockAttributes(leadingBlockAttributes);
7673 } else {
7674 formattedDocument = document.copy({
7675 consolidateBlocks: true
7676 }).copyWithBaseBlockAttributes(blockAttributes);
7677 }
7678 const blockCount = formattedDocument.getBlockCount();
7679 const firstBlock = formattedDocument.getBlockAtIndex(0);
7680 if (arraysAreEqual(blockAttributes, firstBlock.getAttributes())) {
7681 const firstText = firstBlock.getTextWithoutBlockBreak();
7682 result = this.insertTextAtRange(firstText, range);
7683 if (blockCount > 1) {
7684 formattedDocument = new this.constructor(formattedDocument.getBlocks().slice(1));
7685 const position = startPosition + firstText.getLength();
7686 result = result.insertDocumentAtRange(formattedDocument, position);
7687 }
7688 } else {
7689 result = this.insertDocumentAtRange(formattedDocument, range);
7690 }
7691 return result;
7692 }
7693 insertTextAtRange(text, range) {
7694 range = normalizeRange(range);
7695 const [startPosition] = range;
7696 const {
7697 index,
7698 offset
7699 } = this.locationFromPosition(startPosition);
7700 const document = this.removeTextAtRange(range);
7701 return new this.constructor(document.blockList.editObjectAtIndex(index, block => block.copyWithText(block.text.insertTextAtPosition(text, offset))));
7702 }
7703 removeTextAtRange(range) {
7704 let blocks;
7705 range = normalizeRange(range);
7706 const [leftPosition, rightPosition] = range;
7707 if (rangeIsCollapsed(range)) {
7708 return this;
7709 }
7710 const [leftLocation, rightLocation] = Array.from(this.locationRangeFromRange(range));
7711 const leftIndex = leftLocation.index;
7712 const leftOffset = leftLocation.offset;
7713 const leftBlock = this.getBlockAtIndex(leftIndex);
7714 const rightIndex = rightLocation.index;
7715 const rightOffset = rightLocation.offset;
7716 const rightBlock = this.getBlockAtIndex(rightIndex);
7717 const removeRightNewline = rightPosition - leftPosition === 1 && leftBlock.getBlockBreakPosition() === leftOffset && rightBlock.getBlockBreakPosition() !== rightOffset && rightBlock.text.getStringAtPosition(rightOffset) === "\n";
7718 if (removeRightNewline) {
7719 blocks = this.blockList.editObjectAtIndex(rightIndex, block => block.copyWithText(block.text.removeTextAtRange([rightOffset, rightOffset + 1])));
7720 } else {
7721 let block;
7722 const leftText = leftBlock.text.getTextAtRange([0, leftOffset]);
7723 const rightText = rightBlock.text.getTextAtRange([rightOffset, rightBlock.getLength()]);
7724 const text = leftText.appendText(rightText);
7725 const removingLeftBlock = leftIndex !== rightIndex && leftOffset === 0;
7726 const useRightBlock = removingLeftBlock && leftBlock.getAttributeLevel() >= rightBlock.getAttributeLevel();
7727 if (useRightBlock) {
7728 block = rightBlock.copyWithText(text);
7729 } else {
7730 block = leftBlock.copyWithText(text);
7731 }
7732 const affectedBlockCount = rightIndex + 1 - leftIndex;
7733 blocks = this.blockList.splice(leftIndex, affectedBlockCount, block);
7734 }
7735 return new this.constructor(blocks);
7736 }
7737 moveTextFromRangeToPosition(range, position) {
7738 let text;
7739 range = normalizeRange(range);
7740 const [startPosition, endPosition] = range;
7741 if (startPosition <= position && position <= endPosition) {
7742 return this;
7743 }
7744 let document = this.getDocumentAtRange(range);
7745 let result = this.removeTextAtRange(range);
7746 const movingRightward = startPosition < position;
7747 if (movingRightward) {
7748 position -= document.getLength();
7749 }
7750 const [firstBlock, ...blocks] = document.getBlocks();
7751 if (blocks.length === 0) {
7752 text = firstBlock.getTextWithoutBlockBreak();
7753 if (movingRightward) {
7754 position += 1;
7755 }
7756 } else {
7757 text = firstBlock.text;
7758 }
7759 result = result.insertTextAtRange(text, position);
7760 if (blocks.length === 0) {
7761 return result;
7762 }
7763 document = new this.constructor(blocks);
7764 position += text.getLength();
7765 return result.insertDocumentAtRange(document, position);
7766 }
7767 addAttributeAtRange(attribute, value, range) {
7768 let {
7769 blockList
7770 } = this;
7771 this.eachBlockAtRange(range, (block, textRange, index) => blockList = blockList.editObjectAtIndex(index, function () {
7772 if (getBlockConfig(attribute)) {
7773 return block.addAttribute(attribute, value);
7774 } else {
7775 if (textRange[0] === textRange[1]) {
7776 return block;
7777 } else {
7778 return block.copyWithText(block.text.addAttributeAtRange(attribute, value, textRange));
7779 }
7780 }
7781 }));
7782 return new this.constructor(blockList);
7783 }
7784 addAttribute(attribute, value) {
7785 let {
7786 blockList
7787 } = this;
7788 this.eachBlock((block, index) => blockList = blockList.editObjectAtIndex(index, () => block.addAttribute(attribute, value)));
7789 return new this.constructor(blockList);
7790 }
7791 removeAttributeAtRange(attribute, range) {
7792 let {
7793 blockList
7794 } = this;
7795 this.eachBlockAtRange(range, function (block, textRange, index) {
7796 if (getBlockConfig(attribute)) {
7797 blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(attribute));
7798 } else if (textRange[0] !== textRange[1]) {
7799 blockList = blockList.editObjectAtIndex(index, () => block.copyWithText(block.text.removeAttributeAtRange(attribute, textRange)));
7800 }
7801 });
7802 return new this.constructor(blockList);
7803 }
7804 updateAttributesForAttachment(attributes, attachment) {
7805 const range = this.getRangeOfAttachment(attachment);
7806 const [startPosition] = Array.from(range);
7807 const {
7808 index
7809 } = this.locationFromPosition(startPosition);
7810 const text = this.getTextAtIndex(index);
7811 return new this.constructor(this.blockList.editObjectAtIndex(index, block => block.copyWithText(text.updateAttributesForAttachment(attributes, attachment))));
7812 }
7813 removeAttributeForAttachment(attribute, attachment) {
7814 const range = this.getRangeOfAttachment(attachment);
7815 return this.removeAttributeAtRange(attribute, range);
7816 }
7817 setHTMLAttributeAtPosition(position, name, value) {
7818 const block = this.getBlockAtPosition(position);
7819 const updatedBlock = block.addHTMLAttribute(name, value);
7820 return this.replaceBlock(block, updatedBlock);
7821 }
7822 insertBlockBreakAtRange(range) {
7823 let blocks;
7824 range = normalizeRange(range);
7825 const [startPosition] = range;
7826 const {
7827 offset
7828 } = this.locationFromPosition(startPosition);
7829 const document = this.removeTextAtRange(range);
7830 if (offset === 0) {
7831 blocks = [new Block()];
7832 }
7833 return new this.constructor(document.blockList.insertSplittableListAtPosition(new SplittableList(blocks), startPosition));
7834 }
7835 applyBlockAttributeAtRange(attributeName, value, range) {
7836 const expanded = this.expandRangeToLineBreaksAndSplitBlocks(range);
7837 let document = expanded.document;
7838 range = expanded.range;
7839 const blockConfig = getBlockConfig(attributeName);
7840 if (blockConfig.listAttribute) {
7841 document = document.removeLastListAttributeAtRange(range, {
7842 exceptAttributeName: attributeName
7843 });
7844 const converted = document.convertLineBreaksToBlockBreaksInRange(range);
7845 document = converted.document;
7846 range = converted.range;
7847 } else if (blockConfig.exclusive) {
7848 document = document.removeBlockAttributesAtRange(range);
7849 } else if (blockConfig.terminal) {
7850 document = document.removeLastTerminalAttributeAtRange(range);
7851 } else {
7852 document = document.consolidateBlocksAtRange(range);
7853 }
7854 return document.addAttributeAtRange(attributeName, value, range);
7855 }
7856 removeLastListAttributeAtRange(range) {
7857 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7858 let {
7859 blockList
7860 } = this;
7861 this.eachBlockAtRange(range, function (block, textRange, index) {
7862 const lastAttributeName = block.getLastAttribute();
7863 if (!lastAttributeName) {
7864 return;
7865 }
7866 if (!getBlockConfig(lastAttributeName).listAttribute) {
7867 return;
7868 }
7869 if (lastAttributeName === options.exceptAttributeName) {
7870 return;
7871 }
7872 blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(lastAttributeName));
7873 });
7874 return new this.constructor(blockList);
7875 }
7876 removeLastTerminalAttributeAtRange(range) {
7877 let {
7878 blockList
7879 } = this;
7880 this.eachBlockAtRange(range, function (block, textRange, index) {
7881 const lastAttributeName = block.getLastAttribute();
7882 if (!lastAttributeName) {
7883 return;
7884 }
7885 if (!getBlockConfig(lastAttributeName).terminal) {
7886 return;
7887 }
7888 blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(lastAttributeName));
7889 });
7890 return new this.constructor(blockList);
7891 }
7892 removeBlockAttributesAtRange(range) {
7893 let {
7894 blockList
7895 } = this;
7896 this.eachBlockAtRange(range, function (block, textRange, index) {
7897 if (block.hasAttributes()) {
7898 blockList = blockList.editObjectAtIndex(index, () => block.copyWithoutAttributes());
7899 }
7900 });
7901 return new this.constructor(blockList);
7902 }
7903 expandRangeToLineBreaksAndSplitBlocks(range) {
7904 let position;
7905 range = normalizeRange(range);
7906 let [startPosition, endPosition] = range;
7907 const startLocation = this.locationFromPosition(startPosition);
7908 const endLocation = this.locationFromPosition(endPosition);
7909 let document = this;
7910 const startBlock = document.getBlockAtIndex(startLocation.index);
7911 startLocation.offset = startBlock.findLineBreakInDirectionFromPosition("backward", startLocation.offset);
7912 if (startLocation.offset != null) {
7913 position = document.positionFromLocation(startLocation);
7914 document = document.insertBlockBreakAtRange([position, position + 1]);
7915 endLocation.index += 1;
7916 endLocation.offset -= document.getBlockAtIndex(startLocation.index).getLength();
7917 startLocation.index += 1;
7918 }
7919 startLocation.offset = 0;
7920 if (endLocation.offset === 0 && endLocation.index > startLocation.index) {
7921 endLocation.index -= 1;
7922 endLocation.offset = document.getBlockAtIndex(endLocation.index).getBlockBreakPosition();
7923 } else {
7924 const endBlock = document.getBlockAtIndex(endLocation.index);
7925 if (endBlock.text.getStringAtRange([endLocation.offset - 1, endLocation.offset]) === "\n") {
7926 endLocation.offset -= 1;
7927 } else {
7928 endLocation.offset = endBlock.findLineBreakInDirectionFromPosition("forward", endLocation.offset);
7929 }
7930 if (endLocation.offset !== endBlock.getBlockBreakPosition()) {
7931 position = document.positionFromLocation(endLocation);
7932 document = document.insertBlockBreakAtRange([position, position + 1]);
7933 }
7934 }
7935 startPosition = document.positionFromLocation(startLocation);
7936 endPosition = document.positionFromLocation(endLocation);
7937 range = normalizeRange([startPosition, endPosition]);
7938 return {
7939 document,
7940 range
7941 };
7942 }
7943 convertLineBreaksToBlockBreaksInRange(range) {
7944 range = normalizeRange(range);
7945 let [position] = range;
7946 const string = this.getStringAtRange(range).slice(0, -1);
7947 let document = this;
7948 string.replace(/.*?\n/g, function (match) {
7949 position += match.length;
7950 document = document.insertBlockBreakAtRange([position - 1, position]);
7951 });
7952 return {
7953 document,
7954 range
7955 };
7956 }
7957 consolidateBlocksAtRange(range) {
7958 range = normalizeRange(range);
7959 const [startPosition, endPosition] = range;
7960 const startIndex = this.locationFromPosition(startPosition).index;
7961 const endIndex = this.locationFromPosition(endPosition).index;
7962 return new this.constructor(this.blockList.consolidateFromIndexToIndex(startIndex, endIndex));
7963 }
7964 getDocumentAtRange(range) {
7965 range = normalizeRange(range);
7966 const blocks = this.blockList.getSplittableListInRange(range).toArray();
7967 return new this.constructor(blocks);
7968 }
7969 getStringAtRange(range) {
7970 let endIndex;
7971 const array = range = normalizeRange(range),
7972 endPosition = array[array.length - 1];
7973 if (endPosition !== this.getLength()) {
7974 endIndex = -1;
7975 }
7976 return this.getDocumentAtRange(range).toString().slice(0, endIndex);
7977 }
7978 getBlockAtIndex(index) {
7979 return this.blockList.getObjectAtIndex(index);
7980 }
7981 getBlockAtPosition(position) {
7982 const {
7983 index
7984 } = this.locationFromPosition(position);
7985 return this.getBlockAtIndex(index);
7986 }
7987 getTextAtIndex(index) {
7988 var _this$getBlockAtIndex;
7989 return (_this$getBlockAtIndex = this.getBlockAtIndex(index)) === null || _this$getBlockAtIndex === void 0 ? void 0 : _this$getBlockAtIndex.text;
7990 }
7991 getTextAtPosition(position) {
7992 const {
7993 index
7994 } = this.locationFromPosition(position);
7995 return this.getTextAtIndex(index);
7996 }
7997 getPieceAtPosition(position) {
7998 const {
7999 index,
8000 offset
8001 } = this.locationFromPosition(position);
8002 return this.getTextAtIndex(index).getPieceAtPosition(offset);
8003 }
8004 getCharacterAtPosition(position) {
8005 const {
8006 index,
8007 offset
8008 } = this.locationFromPosition(position);
8009 return this.getTextAtIndex(index).getStringAtRange([offset, offset + 1]);
8010 }
8011 getLength() {
8012 return this.blockList.getEndPosition();
8013 }
8014 getBlocks() {
8015 return this.blockList.toArray();
8016 }
8017 getBlockCount() {
8018 return this.blockList.length;
8019 }
8020 getEditCount() {
8021 return this.editCount;
8022 }
8023 eachBlock(callback) {
8024 return this.blockList.eachObject(callback);
8025 }
8026 eachBlockAtRange(range, callback) {
8027 let block, textRange;
8028 range = normalizeRange(range);
8029 const [startPosition, endPosition] = range;
8030 const startLocation = this.locationFromPosition(startPosition);
8031 const endLocation = this.locationFromPosition(endPosition);
8032 if (startLocation.index === endLocation.index) {
8033 block = this.getBlockAtIndex(startLocation.index);
8034 textRange = [startLocation.offset, endLocation.offset];
8035 return callback(block, textRange, startLocation.index);
8036 } else {
8037 for (let index = startLocation.index; index <= endLocation.index; index++) {
8038 block = this.getBlockAtIndex(index);
8039 if (block) {
8040 switch (index) {
8041 case startLocation.index:
8042 textRange = [startLocation.offset, block.text.getLength()];
8043 break;
8044 case endLocation.index:
8045 textRange = [0, endLocation.offset];
8046 break;
8047 default:
8048 textRange = [0, block.text.getLength()];
8049 }
8050 callback(block, textRange, index);
8051 }
8052 }
8053 }
8054 }
8055 getCommonAttributesAtRange(range) {
8056 range = normalizeRange(range);
8057 const [startPosition] = range;
8058 if (rangeIsCollapsed(range)) {
8059 return this.getCommonAttributesAtPosition(startPosition);
8060 } else {
8061 const textAttributes = [];
8062 const blockAttributes = [];
8063 this.eachBlockAtRange(range, function (block, textRange) {
8064 if (textRange[0] !== textRange[1]) {
8065 textAttributes.push(block.text.getCommonAttributesAtRange(textRange));
8066 return blockAttributes.push(attributesForBlock(block));
8067 }
8068 });
8069 return Hash.fromCommonAttributesOfObjects(textAttributes).merge(Hash.fromCommonAttributesOfObjects(blockAttributes)).toObject();
8070 }
8071 }
8072 getCommonAttributesAtPosition(position) {
8073 let key, value;
8074 const {
8075 index,
8076 offset
8077 } = this.locationFromPosition(position);
8078 const block = this.getBlockAtIndex(index);
8079 if (!block) {
8080 return {};
8081 }
8082 const commonAttributes = attributesForBlock(block);
8083 const attributes = block.text.getAttributesAtPosition(offset);
8084 const attributesLeft = block.text.getAttributesAtPosition(offset - 1);
8085 const inheritableAttributes = Object.keys(text_attributes).filter(key => {
8086 return text_attributes[key].inheritable;
8087 });
8088 for (key in attributesLeft) {
8089 value = attributesLeft[key];
8090 if (value === attributes[key] || inheritableAttributes.includes(key)) {
8091 commonAttributes[key] = value;
8092 }
8093 }
8094 return commonAttributes;
8095 }
8096 getRangeOfCommonAttributeAtPosition(attributeName, position) {
8097 const {
8098 index,
8099 offset
8100 } = this.locationFromPosition(position);
8101 const text = this.getTextAtIndex(index);
8102 const [startOffset, endOffset] = Array.from(text.getExpandedRangeForAttributeAtOffset(attributeName, offset));
8103 const start = this.positionFromLocation({
8104 index,
8105 offset: startOffset
8106 });
8107 const end = this.positionFromLocation({
8108 index,
8109 offset: endOffset
8110 });
8111 return normalizeRange([start, end]);
8112 }
8113 getBaseBlockAttributes() {
8114 let baseBlockAttributes = this.getBlockAtIndex(0).getAttributes();
8115 for (let blockIndex = 1; blockIndex < this.getBlockCount(); blockIndex++) {
8116 const blockAttributes = this.getBlockAtIndex(blockIndex).getAttributes();
8117 const lastAttributeIndex = Math.min(baseBlockAttributes.length, blockAttributes.length);
8118 baseBlockAttributes = (() => {
8119 const result = [];
8120 for (let index = 0; index < lastAttributeIndex; index++) {
8121 if (blockAttributes[index] !== baseBlockAttributes[index]) {
8122 break;
8123 }
8124 result.push(blockAttributes[index]);
8125 }
8126 return result;
8127 })();
8128 }
8129 return baseBlockAttributes;
8130 }
8131 getAttachmentById(attachmentId) {
8132 for (const attachment of this.getAttachments()) {
8133 if (attachment.id === attachmentId) {
8134 return attachment;
8135 }
8136 }
8137 }
8138 getAttachmentPieces() {
8139 let attachmentPieces = [];
8140 this.blockList.eachObject(_ref => {
8141 let {
8142 text
8143 } = _ref;
8144 return attachmentPieces = attachmentPieces.concat(text.getAttachmentPieces());
8145 });
8146 return attachmentPieces;
8147 }
8148 getAttachments() {
8149 return this.getAttachmentPieces().map(piece => piece.attachment);
8150 }
8151 getRangeOfAttachment(attachment) {
8152 let position = 0;
8153 const iterable = this.blockList.toArray();
8154 for (let index = 0; index < iterable.length; index++) {
8155 const {
8156 text
8157 } = iterable[index];
8158 const textRange = text.getRangeOfAttachment(attachment);
8159 if (textRange) {
8160 return normalizeRange([position + textRange[0], position + textRange[1]]);
8161 }
8162 position += text.getLength();
8163 }
8164 }
8165 getLocationRangeOfAttachment(attachment) {
8166 const range = this.getRangeOfAttachment(attachment);
8167 return this.locationRangeFromRange(range);
8168 }
8169 getAttachmentPieceForAttachment(attachment) {
8170 for (const piece of this.getAttachmentPieces()) {
8171 if (piece.attachment === attachment) {
8172 return piece;
8173 }
8174 }
8175 }
8176 findRangesForBlockAttribute(attributeName) {
8177 let position = 0;
8178 const ranges = [];
8179 this.getBlocks().forEach(block => {
8180 const length = block.getLength();
8181 if (block.hasAttribute(attributeName)) {
8182 ranges.push([position, position + length]);
8183 }
8184 position += length;
8185 });
8186 return ranges;
8187 }
8188 findRangesForTextAttribute(attributeName) {
8189 let {
8190 withValue
8191 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8192 let position = 0;
8193 let range = [];
8194 const ranges = [];
8195 const match = function (piece) {
8196 if (withValue) {
8197 return piece.getAttribute(attributeName) === withValue;
8198 } else {
8199 return piece.hasAttribute(attributeName);
8200 }
8201 };
8202 this.getPieces().forEach(piece => {
8203 const length = piece.getLength();
8204 if (match(piece)) {
8205 if (range[1] === position) {
8206 range[1] = position + length;
8207 } else {
8208 ranges.push(range = [position, position + length]);
8209 }
8210 }
8211 position += length;
8212 });
8213 return ranges;
8214 }
8215 locationFromPosition(position) {
8216 const location = this.blockList.findIndexAndOffsetAtPosition(Math.max(0, position));
8217 if (location.index != null) {
8218 return location;
8219 } else {
8220 const blocks = this.getBlocks();
8221 return {
8222 index: blocks.length - 1,
8223 offset: blocks[blocks.length - 1].getLength()
8224 };
8225 }
8226 }
8227 positionFromLocation(location) {
8228 return this.blockList.findPositionAtIndexAndOffset(location.index, location.offset);
8229 }
8230 locationRangeFromPosition(position) {
8231 return normalizeRange(this.locationFromPosition(position));
8232 }
8233 locationRangeFromRange(range) {
8234 range = normalizeRange(range);
8235 if (!range) return;
8236 const [startPosition, endPosition] = Array.from(range);
8237 const startLocation = this.locationFromPosition(startPosition);
8238 const endLocation = this.locationFromPosition(endPosition);
8239 return normalizeRange([startLocation, endLocation]);
8240 }
8241 rangeFromLocationRange(locationRange) {
8242 let rightPosition;
8243 locationRange = normalizeRange(locationRange);
8244 const leftPosition = this.positionFromLocation(locationRange[0]);
8245 if (!rangeIsCollapsed(locationRange)) {
8246 rightPosition = this.positionFromLocation(locationRange[1]);
8247 }
8248 return normalizeRange([leftPosition, rightPosition]);
8249 }
8250 isEqualTo(document) {
8251 return this.blockList.isEqualTo(document === null || document === void 0 ? void 0 : document.blockList);
8252 }
8253 getTexts() {
8254 return this.getBlocks().map(block => block.text);
8255 }
8256 getPieces() {
8257 const pieces = [];
8258 Array.from(this.getTexts()).forEach(text => {
8259 pieces.push(...Array.from(text.getPieces() || []));
8260 });
8261 return pieces;
8262 }
8263 getObjects() {
8264 return this.getBlocks().concat(this.getTexts()).concat(this.getPieces());
8265 }
8266 toSerializableDocument() {
8267 const blocks = [];
8268 this.blockList.eachObject(block => blocks.push(block.copyWithText(block.text.toSerializableText())));
8269 return new this.constructor(blocks);
8270 }
8271 toString() {
8272 return this.blockList.toString();
8273 }
8274 toJSON() {
8275 return this.blockList.toJSON();
8276 }
8277 toConsole() {
8278 return JSON.stringify(this.blockList.toArray().map(block => JSON.parse(block.text.toConsole())));
8279 }
8280 }
8281 const attributesForBlock = function (block) {
8282 const attributes = {};
8283 const attributeName = block.getLastAttribute();
8284 if (attributeName) {
8285 attributes[attributeName] = true;
8286 }
8287 return attributes;
8288 };
8289
8290 /* eslint-disable
8291 no-case-declarations,
8292 no-irregular-whitespace,
8293 */
8294 const pieceForString = function (string) {
8295 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8296 const type = "string";
8297 string = normalizeSpaces(string);
8298 return {
8299 string,
8300 attributes,
8301 type
8302 };
8303 };
8304 const pieceForAttachment = function (attachment) {
8305 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8306 const type = "attachment";
8307 return {
8308 attachment,
8309 attributes,
8310 type
8311 };
8312 };
8313 const blockForAttributes = function () {
8314 let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
8315 let htmlAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8316 const text = [];
8317 return {
8318 text,
8319 attributes,
8320 htmlAttributes
8321 };
8322 };
8323 const parseTrixDataAttribute = (element, name) => {
8324 try {
8325 return JSON.parse(element.getAttribute("data-trix-".concat(name)));
8326 } catch (error) {
8327 return {};
8328 }
8329 };
8330 const getImageDimensions = element => {
8331 const width = element.getAttribute("width");
8332 const height = element.getAttribute("height");
8333 const dimensions = {};
8334 if (width) {
8335 dimensions.width = parseInt(width, 10);
8336 }
8337 if (height) {
8338 dimensions.height = parseInt(height, 10);
8339 }
8340 return dimensions;
8341 };
8342 class HTMLParser extends BasicObject {
8343 static parse(html, options) {
8344 const parser = new this(html, options);
8345 parser.parse();
8346 return parser;
8347 }
8348 constructor(html) {
8349 let {
8350 referenceElement
8351 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8352 super(...arguments);
8353 this.html = html;
8354 this.referenceElement = referenceElement;
8355 this.blocks = [];
8356 this.blockElements = [];
8357 this.processedElements = [];
8358 }
8359 getDocument() {
8360 return Document.fromJSON(this.blocks);
8361 }
8362
8363 // HTML parsing
8364
8365 parse() {
8366 try {
8367 this.createHiddenContainer();
8368 HTMLSanitizer.setHTML(this.containerElement, this.html);
8369 const walker = walkTree(this.containerElement, {
8370 usingFilter: nodeFilter
8371 });
8372 while (walker.nextNode()) {
8373 this.processNode(walker.currentNode);
8374 }
8375 return this.translateBlockElementMarginsToNewlines();
8376 } finally {
8377 this.removeHiddenContainer();
8378 }
8379 }
8380 createHiddenContainer() {
8381 if (this.referenceElement) {
8382 this.containerElement = this.referenceElement.cloneNode(false);
8383 this.containerElement.removeAttribute("id");
8384 this.containerElement.setAttribute("data-trix-internal", "");
8385 this.containerElement.style.display = "none";
8386 return this.referenceElement.parentNode.insertBefore(this.containerElement, this.referenceElement.nextSibling);
8387 } else {
8388 this.containerElement = makeElement({
8389 tagName: "div",
8390 style: {
8391 display: "none"
8392 }
8393 });
8394 return document.body.appendChild(this.containerElement);
8395 }
8396 }
8397 removeHiddenContainer() {
8398 return removeNode(this.containerElement);
8399 }
8400 processNode(node) {
8401 switch (node.nodeType) {
8402 case Node.TEXT_NODE:
8403 if (!this.isInsignificantTextNode(node)) {
8404 this.appendBlockForTextNode(node);
8405 return this.processTextNode(node);
8406 }
8407 break;
8408 case Node.ELEMENT_NODE:
8409 this.appendBlockForElement(node);
8410 return this.processElement(node);
8411 }
8412 }
8413 appendBlockForTextNode(node) {
8414 const element = node.parentNode;
8415 if (element === this.currentBlockElement && this.isBlockElement(node.previousSibling)) {
8416 return this.appendStringWithAttributes("\n");
8417 } else if (element === this.containerElement || this.isBlockElement(element)) {
8418 var _this$currentBlock;
8419 const attributes = this.getBlockAttributes(element);
8420 const htmlAttributes = this.getBlockHTMLAttributes(element);
8421 if (!arraysAreEqual(attributes, (_this$currentBlock = this.currentBlock) === null || _this$currentBlock === void 0 ? void 0 : _this$currentBlock.attributes)) {
8422 this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
8423 this.currentBlockElement = element;
8424 }
8425 }
8426 }
8427 appendBlockForElement(element) {
8428 const elementIsBlockElement = this.isBlockElement(element);
8429 const currentBlockContainsElement = elementContainsNode(this.currentBlockElement, element);
8430 if (elementIsBlockElement && !this.isBlockElement(element.firstChild)) {
8431 if (!this.isInsignificantTextNode(element.firstChild) || !this.isBlockElement(element.firstElementChild)) {
8432 const attributes = this.getBlockAttributes(element);
8433 const htmlAttributes = this.getBlockHTMLAttributes(element);
8434 if (element.firstChild) {
8435 if (!(currentBlockContainsElement && arraysAreEqual(attributes, this.currentBlock.attributes))) {
8436 this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
8437 this.currentBlockElement = element;
8438 } else {
8439 return this.appendStringWithAttributes("\n");
8440 }
8441 }
8442 }
8443 } else if (this.currentBlockElement && !currentBlockContainsElement && !elementIsBlockElement) {
8444 const parentBlockElement = this.findParentBlockElement(element);
8445 if (parentBlockElement) {
8446 return this.appendBlockForElement(parentBlockElement);
8447 } else {
8448 this.currentBlock = this.appendEmptyBlock();
8449 this.currentBlockElement = null;
8450 }
8451 }
8452 }
8453 findParentBlockElement(element) {
8454 let {
8455 parentElement
8456 } = element;
8457 while (parentElement && parentElement !== this.containerElement) {
8458 if (this.isBlockElement(parentElement) && this.blockElements.includes(parentElement)) {
8459 return parentElement;
8460 } else {
8461 parentElement = parentElement.parentElement;
8462 }
8463 }
8464 return null;
8465 }
8466 processTextNode(node) {
8467 let string = node.data;
8468 if (!elementCanDisplayPreformattedText(node.parentNode)) {
8469 var _node$previousSibling;
8470 string = squishBreakableWhitespace(string);
8471 if (stringEndsWithWhitespace((_node$previousSibling = node.previousSibling) === null || _node$previousSibling === void 0 ? void 0 : _node$previousSibling.textContent)) {
8472 string = leftTrimBreakableWhitespace(string);
8473 }
8474 }
8475 return this.appendStringWithAttributes(string, this.getTextAttributes(node.parentNode));
8476 }
8477 processElement(element) {
8478 let attributes;
8479 if (nodeIsAttachmentElement(element)) {
8480 attributes = parseTrixDataAttribute(element, "attachment");
8481 if (Object.keys(attributes).length) {
8482 const textAttributes = this.getTextAttributes(element);
8483 this.appendAttachmentWithAttributes(attributes, textAttributes);
8484 // We have everything we need so avoid processing inner nodes
8485 element.innerHTML = "";
8486 }
8487 return this.processedElements.push(element);
8488 } else {
8489 switch (tagName(element)) {
8490 case "br":
8491 if (!this.isExtraBR(element) && !this.isBlockElement(element.nextSibling)) {
8492 this.appendStringWithAttributes("\n", this.getTextAttributes(element));
8493 }
8494 return this.processedElements.push(element);
8495 case "img":
8496 attributes = {
8497 url: element.getAttribute("src"),
8498 contentType: "image"
8499 };
8500 const object = getImageDimensions(element);
8501 for (const key in object) {
8502 const value = object[key];
8503 attributes[key] = value;
8504 }
8505 this.appendAttachmentWithAttributes(attributes, this.getTextAttributes(element));
8506 return this.processedElements.push(element);
8507 case "tr":
8508 if (this.needsTableSeparator(element)) {
8509 return this.appendStringWithAttributes(parser.tableRowSeparator);
8510 }
8511 break;
8512 case "td":
8513 if (this.needsTableSeparator(element)) {
8514 return this.appendStringWithAttributes(parser.tableCellSeparator);
8515 }
8516 break;
8517 }
8518 }
8519 }
8520
8521 // Document construction
8522
8523 appendBlockForAttributesWithElement(attributes, element) {
8524 let htmlAttributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
8525 this.blockElements.push(element);
8526 const block = blockForAttributes(attributes, htmlAttributes);
8527 this.blocks.push(block);
8528 return block;
8529 }
8530 appendEmptyBlock() {
8531 return this.appendBlockForAttributesWithElement([], null);
8532 }
8533 appendStringWithAttributes(string, attributes) {
8534 return this.appendPiece(pieceForString(string, attributes));
8535 }
8536 appendAttachmentWithAttributes(attachment, attributes) {
8537 return this.appendPiece(pieceForAttachment(attachment, attributes));
8538 }
8539 appendPiece(piece) {
8540 if (this.blocks.length === 0) {
8541 this.appendEmptyBlock();
8542 }
8543 return this.blocks[this.blocks.length - 1].text.push(piece);
8544 }
8545 appendStringToTextAtIndex(string, index) {
8546 const {
8547 text
8548 } = this.blocks[index];
8549 const piece = text[text.length - 1];
8550 if ((piece === null || piece === void 0 ? void 0 : piece.type) === "string") {
8551 piece.string += string;
8552 } else {
8553 return text.push(pieceForString(string));
8554 }
8555 }
8556 prependStringToTextAtIndex(string, index) {
8557 const {
8558 text
8559 } = this.blocks[index];
8560 const piece = text[0];
8561 if ((piece === null || piece === void 0 ? void 0 : piece.type) === "string") {
8562 piece.string = string + piece.string;
8563 } else {
8564 return text.unshift(pieceForString(string));
8565 }
8566 }
8567
8568 // Attribute parsing
8569
8570 getTextAttributes(element) {
8571 let value;
8572 const attributes = {};
8573 for (const attribute in text_attributes) {
8574 const configAttr = text_attributes[attribute];
8575 if (configAttr.tagName && findClosestElementFromNode(element, {
8576 matchingSelector: configAttr.tagName,
8577 untilNode: this.containerElement
8578 })) {
8579 attributes[attribute] = true;
8580 } else if (configAttr.parser) {
8581 value = configAttr.parser(element);
8582 if (value) {
8583 let attributeInheritedFromBlock = false;
8584 for (const blockElement of this.findBlockElementAncestors(element)) {
8585 if (configAttr.parser(blockElement) === value) {
8586 attributeInheritedFromBlock = true;
8587 break;
8588 }
8589 }
8590 if (!attributeInheritedFromBlock) {
8591 attributes[attribute] = value;
8592 }
8593 }
8594 } else if (configAttr.styleProperty) {
8595 value = element.style[configAttr.styleProperty];
8596 if (value) {
8597 attributes[attribute] = value;
8598 }
8599 }
8600 }
8601 if (nodeIsAttachmentElement(element)) {
8602 const object = parseTrixDataAttribute(element, "attributes");
8603 for (const key in object) {
8604 value = object[key];
8605 attributes[key] = value;
8606 }
8607 }
8608 return attributes;
8609 }
8610 getBlockAttributes(element) {
8611 const attributes$1 = [];
8612 while (element && element !== this.containerElement) {
8613 for (const attribute in attributes) {
8614 const attrConfig = attributes[attribute];
8615 if (attrConfig.parse !== false) {
8616 if (tagName(element) === attrConfig.tagName) {
8617 var _attrConfig$test;
8618 if ((_attrConfig$test = attrConfig.test) !== null && _attrConfig$test !== void 0 && _attrConfig$test.call(attrConfig, element) || !attrConfig.test) {
8619 attributes$1.push(attribute);
8620 if (attrConfig.listAttribute) {
8621 attributes$1.push(attrConfig.listAttribute);
8622 }
8623 }
8624 }
8625 }
8626 }
8627 element = element.parentNode;
8628 }
8629 return attributes$1.reverse();
8630 }
8631 getBlockHTMLAttributes(element) {
8632 const attributes$1 = {};
8633 const blockConfig = Object.values(attributes).find(settings => settings.tagName === tagName(element));
8634 const allowedAttributes = (blockConfig === null || blockConfig === void 0 ? void 0 : blockConfig.htmlAttributes) || [];
8635 allowedAttributes.forEach(attribute => {
8636 if (element.hasAttribute(attribute)) {
8637 attributes$1[attribute] = element.getAttribute(attribute);
8638 }
8639 });
8640 return attributes$1;
8641 }
8642 findBlockElementAncestors(element) {
8643 const ancestors = [];
8644 while (element && element !== this.containerElement) {
8645 const tag = tagName(element);
8646 if (getBlockTagNames().includes(tag)) {
8647 ancestors.push(element);
8648 }
8649 element = element.parentNode;
8650 }
8651 return ancestors;
8652 }
8653
8654 // Element inspection
8655
8656 isBlockElement(element) {
8657 if ((element === null || element === void 0 ? void 0 : element.nodeType) !== Node.ELEMENT_NODE) return;
8658 if (nodeIsAttachmentElement(element)) return;
8659 if (findClosestElementFromNode(element, {
8660 matchingSelector: "td",
8661 untilNode: this.containerElement
8662 })) return;
8663 return getBlockTagNames().includes(tagName(element)) || window.getComputedStyle(element).display === "block";
8664 }
8665 isInsignificantTextNode(node) {
8666 if ((node === null || node === void 0 ? void 0 : node.nodeType) !== Node.TEXT_NODE) return;
8667 if (!stringIsAllBreakableWhitespace(node.data)) return;
8668 const {
8669 parentNode,
8670 previousSibling,
8671 nextSibling
8672 } = node;
8673 if (nodeEndsWithNonWhitespace(parentNode.previousSibling) && !this.isBlockElement(parentNode.previousSibling)) return;
8674 if (elementCanDisplayPreformattedText(parentNode)) return;
8675 return !previousSibling || this.isBlockElement(previousSibling) || !nextSibling || this.isBlockElement(nextSibling);
8676 }
8677 isExtraBR(element) {
8678 return tagName(element) === "br" && this.isBlockElement(element.parentNode) && element.parentNode.lastChild === element;
8679 }
8680 needsTableSeparator(element) {
8681 if (parser.removeBlankTableCells) {
8682 var _element$previousSibl;
8683 const content = (_element$previousSibl = element.previousSibling) === null || _element$previousSibl === void 0 ? void 0 : _element$previousSibl.textContent;
8684 return content && /\S/.test(content);
8685 } else {
8686 return element.previousSibling;
8687 }
8688 }
8689
8690 // Margin translation
8691
8692 translateBlockElementMarginsToNewlines() {
8693 const defaultMargin = this.getMarginOfDefaultBlockElement();
8694 for (let index = 0; index < this.blocks.length; index++) {
8695 const margin = this.getMarginOfBlockElementAtIndex(index);
8696 if (margin) {
8697 if (margin.top > defaultMargin.top * 2) {
8698 this.prependStringToTextAtIndex("\n", index);
8699 }
8700 if (margin.bottom > defaultMargin.bottom * 2) {
8701 this.appendStringToTextAtIndex("\n", index);
8702 }
8703 }
8704 }
8705 }
8706 getMarginOfBlockElementAtIndex(index) {
8707 const element = this.blockElements[index];
8708 if (element) {
8709 if (element.textContent) {
8710 if (!getBlockTagNames().includes(tagName(element)) && !this.processedElements.includes(element)) {
8711 return getBlockElementMargin(element);
8712 }
8713 }
8714 }
8715 }
8716 getMarginOfDefaultBlockElement() {
8717 const element = makeElement(attributes.default.tagName);
8718 this.containerElement.appendChild(element);
8719 return getBlockElementMargin(element);
8720 }
8721 }
8722
8723 // Helpers
8724
8725 const elementCanDisplayPreformattedText = function (element) {
8726 const {
8727 whiteSpace
8728 } = window.getComputedStyle(element);
8729 return ["pre", "pre-wrap", "pre-line"].includes(whiteSpace);
8730 };
8731 const nodeEndsWithNonWhitespace = node => node && !stringEndsWithWhitespace(node.textContent);
8732 const getBlockElementMargin = function (element) {
8733 const style = window.getComputedStyle(element);
8734 if (style.display === "block") {
8735 return {
8736 top: parseInt(style.marginTop),
8737 bottom: parseInt(style.marginBottom)
8738 };
8739 }
8740 };
8741 const nodeFilter = function (node) {
8742 if (tagName(node) === "style") {
8743 return NodeFilter.FILTER_REJECT;
8744 } else {
8745 return NodeFilter.FILTER_ACCEPT;
8746 }
8747 };
8748
8749 // Whitespace
8750
8751 const leftTrimBreakableWhitespace = string => string.replace(new RegExp("^".concat(breakableWhitespacePattern.source, "+")), "");
8752 const stringIsAllBreakableWhitespace = string => new RegExp("^".concat(breakableWhitespacePattern.source, "*$")).test(string);
8753 const stringEndsWithWhitespace = string => /\s$/.test(string);
8754
8755 /* eslint-disable
8756 no-empty,
8757 */
8758 const unserializableElementSelector = "[data-trix-serialize=false]";
8759 const unserializableAttributeNames = ["contenteditable", "data-trix-id", "data-trix-store-key", "data-trix-mutable", "data-trix-placeholder", "tabindex"];
8760 const serializedAttributesAttribute = "data-trix-serialized-attributes";
8761 const serializedAttributesSelector = "[".concat(serializedAttributesAttribute, "]");
8762 const blockCommentPattern = new RegExp("<!--block-->", "g");
8763 const serializers = {
8764 "application/json": function (serializable) {
8765 let document;
8766 if (serializable instanceof Document) {
8767 document = serializable;
8768 } else if (serializable instanceof HTMLElement) {
8769 document = HTMLParser.parse(serializable.innerHTML).getDocument();
8770 } else {
8771 throw new Error("unserializable object");
8772 }
8773 return document.toSerializableDocument().toJSONString();
8774 },
8775 "text/html": function (serializable) {
8776 let element;
8777 if (serializable instanceof Document) {
8778 element = DocumentView.render(serializable);
8779 } else if (serializable instanceof HTMLElement) {
8780 element = serializable.cloneNode(true);
8781 } else {
8782 throw new Error("unserializable object");
8783 }
8784
8785 // Remove unserializable elements
8786 Array.from(element.querySelectorAll(unserializableElementSelector)).forEach(el => {
8787 removeNode(el);
8788 });
8789
8790 // Remove unserializable attributes
8791 unserializableAttributeNames.forEach(attribute => {
8792 Array.from(element.querySelectorAll("[".concat(attribute, "]"))).forEach(el => {
8793 el.removeAttribute(attribute);
8794 });
8795 });
8796
8797 // Rewrite elements with serialized attribute overrides
8798 Array.from(element.querySelectorAll(serializedAttributesSelector)).forEach(el => {
8799 try {
8800 const attributes = JSON.parse(el.getAttribute(serializedAttributesAttribute));
8801 el.removeAttribute(serializedAttributesAttribute);
8802 for (const name in attributes) {
8803 const value = attributes[name];
8804 el.setAttribute(name, value);
8805 }
8806 } catch (error) {}
8807 });
8808 return element.innerHTML.replace(blockCommentPattern, "");
8809 }
8810 };
8811 const deserializers = {
8812 "application/json": function (string) {
8813 return Document.fromJSONString(string);
8814 },
8815 "text/html": function (string) {
8816 return HTMLParser.parse(string).getDocument();
8817 }
8818 };
8819 const serializeToContentType = function (serializable, contentType) {
8820 const serializer = serializers[contentType];
8821 if (serializer) {
8822 return serializer(serializable);
8823 } else {
8824 throw new Error("unknown content type: ".concat(contentType));
8825 }
8826 };
8827 const deserializeFromContentType = function (string, contentType) {
8828 const deserializer = deserializers[contentType];
8829 if (deserializer) {
8830 return deserializer(string);
8831 } else {
8832 throw new Error("unknown content type: ".concat(contentType));
8833 }
8834 };
8835
8836 var core = /*#__PURE__*/Object.freeze({
8837 __proto__: null
8838 });
8839
8840 class ManagedAttachment extends BasicObject {
8841 constructor(attachmentManager, attachment) {
8842 super(...arguments);
8843 this.attachmentManager = attachmentManager;
8844 this.attachment = attachment;
8845 this.id = this.attachment.id;
8846 this.file = this.attachment.file;
8847 }
8848 remove() {
8849 return this.attachmentManager.requestRemovalOfAttachment(this.attachment);
8850 }
8851 }
8852 ManagedAttachment.proxyMethod("attachment.getAttribute");
8853 ManagedAttachment.proxyMethod("attachment.hasAttribute");
8854 ManagedAttachment.proxyMethod("attachment.setAttribute");
8855 ManagedAttachment.proxyMethod("attachment.getAttributes");
8856 ManagedAttachment.proxyMethod("attachment.setAttributes");
8857 ManagedAttachment.proxyMethod("attachment.isPending");
8858 ManagedAttachment.proxyMethod("attachment.isPreviewable");
8859 ManagedAttachment.proxyMethod("attachment.getURL");
8860 ManagedAttachment.proxyMethod("attachment.getHref");
8861 ManagedAttachment.proxyMethod("attachment.getFilename");
8862 ManagedAttachment.proxyMethod("attachment.getFilesize");
8863 ManagedAttachment.proxyMethod("attachment.getFormattedFilesize");
8864 ManagedAttachment.proxyMethod("attachment.getExtension");
8865 ManagedAttachment.proxyMethod("attachment.getContentType");
8866 ManagedAttachment.proxyMethod("attachment.getFile");
8867 ManagedAttachment.proxyMethod("attachment.setFile");
8868 ManagedAttachment.proxyMethod("attachment.releaseFile");
8869 ManagedAttachment.proxyMethod("attachment.getUploadProgress");
8870 ManagedAttachment.proxyMethod("attachment.setUploadProgress");
8871
8872 class AttachmentManager extends BasicObject {
8873 constructor() {
8874 let attachments = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
8875 super(...arguments);
8876 this.managedAttachments = {};
8877 Array.from(attachments).forEach(attachment => {
8878 this.manageAttachment(attachment);
8879 });
8880 }
8881 getAttachments() {
8882 const result = [];
8883 for (const id in this.managedAttachments) {
8884 const attachment = this.managedAttachments[id];
8885 result.push(attachment);
8886 }
8887 return result;
8888 }
8889 manageAttachment(attachment) {
8890 if (!this.managedAttachments[attachment.id]) {
8891 this.managedAttachments[attachment.id] = new ManagedAttachment(this, attachment);
8892 }
8893 return this.managedAttachments[attachment.id];
8894 }
8895 attachmentIsManaged(attachment) {
8896 return attachment.id in this.managedAttachments;
8897 }
8898 requestRemovalOfAttachment(attachment) {
8899 if (this.attachmentIsManaged(attachment)) {
8900 var _this$delegate, _this$delegate$attach;
8901 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);
8902 }
8903 }
8904 unmanageAttachment(attachment) {
8905 const managedAttachment = this.managedAttachments[attachment.id];
8906 delete this.managedAttachments[attachment.id];
8907 return managedAttachment;
8908 }
8909 }
8910
8911 class LineBreakInsertion {
8912 constructor(composition) {
8913 this.composition = composition;
8914 this.document = this.composition.document;
8915 const selectedRange = this.composition.getSelectedRange();
8916 this.startPosition = selectedRange[0];
8917 this.endPosition = selectedRange[1];
8918 this.startLocation = this.document.locationFromPosition(this.startPosition);
8919 this.endLocation = this.document.locationFromPosition(this.endPosition);
8920 this.block = this.document.getBlockAtIndex(this.endLocation.index);
8921 this.breaksOnReturn = this.block.breaksOnReturn();
8922 this.previousCharacter = this.block.text.getStringAtPosition(this.endLocation.offset - 1);
8923 this.nextCharacter = this.block.text.getStringAtPosition(this.endLocation.offset);
8924 }
8925 shouldInsertBlockBreak() {
8926 if (this.block.hasAttributes() && this.block.isListItem() && !this.block.isEmpty()) {
8927 return this.startLocation.offset !== 0;
8928 } else {
8929 return this.breaksOnReturn && this.nextCharacter !== "\n";
8930 }
8931 }
8932 shouldBreakFormattedBlock() {
8933 return this.block.hasAttributes() && !this.block.isListItem() && (this.breaksOnReturn && this.nextCharacter === "\n" || this.previousCharacter === "\n");
8934 }
8935 shouldDecreaseListLevel() {
8936 return this.block.hasAttributes() && this.block.isListItem() && this.block.isEmpty();
8937 }
8938 shouldPrependListItem() {
8939 return this.block.isListItem() && this.startLocation.offset === 0 && !this.block.isEmpty();
8940 }
8941 shouldRemoveLastBlockAttribute() {
8942 return this.block.hasAttributes() && !this.block.isListItem() && this.block.isEmpty();
8943 }
8944 }
8945
8946 const PLACEHOLDER = " ";
8947 class Composition extends BasicObject {
8948 constructor() {
8949 super(...arguments);
8950 this.document = new Document();
8951 this.attachments = [];
8952 this.currentAttributes = {};
8953 this.revision = 0;
8954 }
8955 setDocument(document) {
8956 if (!document.isEqualTo(this.document)) {
8957 var _this$delegate, _this$delegate$compos;
8958 this.document = document;
8959 this.refreshAttachments();
8960 this.revision++;
8961 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);
8962 }
8963 }
8964
8965 // Snapshots
8966
8967 getSnapshot() {
8968 return {
8969 document: this.document,
8970 selectedRange: this.getSelectedRange()
8971 };
8972 }
8973 loadSnapshot(_ref) {
8974 var _this$delegate2, _this$delegate2$compo, _this$delegate3, _this$delegate3$compo;
8975 let {
8976 document,
8977 selectedRange
8978 } = _ref;
8979 (_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);
8980 this.setDocument(document != null ? document : new Document());
8981 this.setSelection(selectedRange != null ? selectedRange : [0, 0]);
8982 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);
8983 }
8984
8985 // Responder protocol
8986
8987 insertText(text) {
8988 let {
8989 updatePosition
8990 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
8991 updatePosition: true
8992 };
8993 const selectedRange = this.getSelectedRange();
8994 this.setDocument(this.document.insertTextAtRange(text, selectedRange));
8995 const startPosition = selectedRange[0];
8996 const endPosition = startPosition + text.getLength();
8997 if (updatePosition) {
8998 this.setSelection(endPosition);
8999 }
9000 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
9001 }
9002 insertBlock() {
9003 let block = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Block();
9004 const document = new Document([block]);
9005 return this.insertDocument(document);
9006 }
9007 insertDocument() {
9008 let document = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Document();
9009 const selectedRange = this.getSelectedRange();
9010 this.setDocument(this.document.insertDocumentAtRange(document, selectedRange));
9011 const startPosition = selectedRange[0];
9012 const endPosition = startPosition + document.getLength();
9013 this.setSelection(endPosition);
9014 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
9015 }
9016 insertString(string, options) {
9017 const attributes = this.getCurrentTextAttributes();
9018 const text = Text.textForStringWithAttributes(string, attributes);
9019 return this.insertText(text, options);
9020 }
9021 insertBlockBreak() {
9022 const selectedRange = this.getSelectedRange();
9023 this.setDocument(this.document.insertBlockBreakAtRange(selectedRange));
9024 const startPosition = selectedRange[0];
9025 const endPosition = startPosition + 1;
9026 this.setSelection(endPosition);
9027 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
9028 }
9029 insertLineBreak() {
9030 const insertion = new LineBreakInsertion(this);
9031 if (insertion.shouldDecreaseListLevel()) {
9032 this.decreaseListLevel();
9033 return this.setSelection(insertion.startPosition);
9034 } else if (insertion.shouldPrependListItem()) {
9035 const document = new Document([insertion.block.copyWithoutText()]);
9036 return this.insertDocument(document);
9037 } else if (insertion.shouldInsertBlockBreak()) {
9038 return this.insertBlockBreak();
9039 } else if (insertion.shouldRemoveLastBlockAttribute()) {
9040 return this.removeLastBlockAttribute();
9041 } else if (insertion.shouldBreakFormattedBlock()) {
9042 return this.breakFormattedBlock(insertion);
9043 } else {
9044 return this.insertString("\n");
9045 }
9046 }
9047 insertHTML(html) {
9048 const document = HTMLParser.parse(html).getDocument();
9049 const selectedRange = this.getSelectedRange();
9050 this.setDocument(this.document.mergeDocumentAtRange(document, selectedRange));
9051 const startPosition = selectedRange[0];
9052 const endPosition = startPosition + document.getLength() - 1;
9053 this.setSelection(endPosition);
9054 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
9055 }
9056 replaceHTML(html) {
9057 const document = HTMLParser.parse(html).getDocument().copyUsingObjectsFromDocument(this.document);
9058 const locationRange = this.getLocationRange({
9059 strict: false
9060 });
9061 const selectedRange = this.document.rangeFromLocationRange(locationRange);
9062 this.setDocument(document);
9063 return this.setSelection(selectedRange);
9064 }
9065 insertFile(file) {
9066 return this.insertFiles([file]);
9067 }
9068 insertFiles(files) {
9069 const attachments = [];
9070 Array.from(files).forEach(file => {
9071 var _this$delegate4;
9072 if ((_this$delegate4 = this.delegate) !== null && _this$delegate4 !== void 0 && _this$delegate4.compositionShouldAcceptFile(file)) {
9073 const attachment = Attachment.attachmentForFile(file);
9074 attachments.push(attachment);
9075 }
9076 });
9077 return this.insertAttachments(attachments);
9078 }
9079 insertAttachment(attachment) {
9080 return this.insertAttachments([attachment]);
9081 }
9082 insertAttachments(attachments$1) {
9083 let text = new Text();
9084 Array.from(attachments$1).forEach(attachment => {
9085 var _config$attachments$t;
9086 const type = attachment.getType();
9087 const presentation = (_config$attachments$t = attachments[type]) === null || _config$attachments$t === void 0 ? void 0 : _config$attachments$t.presentation;
9088 const attributes = this.getCurrentTextAttributes();
9089 if (presentation) {
9090 attributes.presentation = presentation;
9091 }
9092 const attachmentText = Text.textForAttachmentWithAttributes(attachment, attributes);
9093 text = text.appendText(attachmentText);
9094 });
9095 return this.insertText(text);
9096 }
9097 shouldManageDeletingInDirection(direction) {
9098 const locationRange = this.getLocationRange();
9099 if (rangeIsCollapsed(locationRange)) {
9100 if (direction === "backward" && locationRange[0].offset === 0) {
9101 return true;
9102 }
9103 if (this.shouldManageMovingCursorInDirection(direction)) {
9104 return true;
9105 }
9106 } else {
9107 if (locationRange[0].index !== locationRange[1].index) {
9108 return true;
9109 }
9110 }
9111 return false;
9112 }
9113 deleteInDirection(direction) {
9114 let {
9115 length
9116 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9117 let attachment, deletingIntoPreviousBlock, selectionSpansBlocks;
9118 const locationRange = this.getLocationRange();
9119 let range = this.getSelectedRange();
9120 const selectionIsCollapsed = rangeIsCollapsed(range);
9121 if (selectionIsCollapsed) {
9122 deletingIntoPreviousBlock = direction === "backward" && locationRange[0].offset === 0;
9123 } else {
9124 selectionSpansBlocks = locationRange[0].index !== locationRange[1].index;
9125 }
9126 if (deletingIntoPreviousBlock) {
9127 if (this.canDecreaseBlockAttributeLevel()) {
9128 const block = this.getBlock();
9129 if (block.isListItem()) {
9130 this.decreaseListLevel();
9131 } else {
9132 this.decreaseBlockAttributeLevel();
9133 }
9134 this.setSelection(range[0]);
9135 if (block.isEmpty()) {
9136 return false;
9137 }
9138 }
9139 }
9140 if (selectionIsCollapsed) {
9141 range = this.getExpandedRangeInDirection(direction, {
9142 length
9143 });
9144 if (direction === "backward") {
9145 attachment = this.getAttachmentAtRange(range);
9146 }
9147 }
9148 if (attachment) {
9149 this.editAttachment(attachment);
9150 return false;
9151 } else {
9152 this.setDocument(this.document.removeTextAtRange(range));
9153 this.setSelection(range[0]);
9154 if (deletingIntoPreviousBlock || selectionSpansBlocks) {
9155 return false;
9156 }
9157 }
9158 }
9159 moveTextFromRange(range) {
9160 const [position] = Array.from(this.getSelectedRange());
9161 this.setDocument(this.document.moveTextFromRangeToPosition(range, position));
9162 return this.setSelection(position);
9163 }
9164 removeAttachment(attachment) {
9165 const range = this.document.getRangeOfAttachment(attachment);
9166 if (range) {
9167 this.stopEditingAttachment();
9168 this.setDocument(this.document.removeTextAtRange(range));
9169 return this.setSelection(range[0]);
9170 }
9171 }
9172 removeLastBlockAttribute() {
9173 const [startPosition, endPosition] = Array.from(this.getSelectedRange());
9174 const block = this.document.getBlockAtPosition(endPosition);
9175 this.removeCurrentAttribute(block.getLastAttribute());
9176 return this.setSelection(startPosition);
9177 }
9178 insertPlaceholder() {
9179 this.placeholderPosition = this.getPosition();
9180 return this.insertString(PLACEHOLDER);
9181 }
9182 selectPlaceholder() {
9183 if (this.placeholderPosition != null) {
9184 this.setSelectedRange([this.placeholderPosition, this.placeholderPosition + PLACEHOLDER.length]);
9185 return this.getSelectedRange();
9186 }
9187 }
9188 forgetPlaceholder() {
9189 this.placeholderPosition = null;
9190 }
9191
9192 // Current attributes
9193
9194 hasCurrentAttribute(attributeName) {
9195 const value = this.currentAttributes[attributeName];
9196 return value != null && value !== false;
9197 }
9198 toggleCurrentAttribute(attributeName) {
9199 const value = !this.currentAttributes[attributeName];
9200 if (value) {
9201 return this.setCurrentAttribute(attributeName, value);
9202 } else {
9203 return this.removeCurrentAttribute(attributeName);
9204 }
9205 }
9206 canSetCurrentAttribute(attributeName) {
9207 if (getBlockConfig(attributeName)) {
9208 return this.canSetCurrentBlockAttribute(attributeName);
9209 } else {
9210 return this.canSetCurrentTextAttribute(attributeName);
9211 }
9212 }
9213 canSetCurrentTextAttribute(attributeName) {
9214 const document = this.getSelectedDocument();
9215 if (!document) return;
9216 for (const attachment of Array.from(document.getAttachments())) {
9217 if (!attachment.hasContent()) {
9218 return false;
9219 }
9220 }
9221 return true;
9222 }
9223 canSetCurrentBlockAttribute(attributeName) {
9224 const block = this.getBlock();
9225 if (!block) return;
9226 return !block.isTerminalBlock();
9227 }
9228 setCurrentAttribute(attributeName, value) {
9229 if (getBlockConfig(attributeName)) {
9230 return this.setBlockAttribute(attributeName, value);
9231 } else {
9232 this.setTextAttribute(attributeName, value);
9233 this.currentAttributes[attributeName] = value;
9234 return this.notifyDelegateOfCurrentAttributesChange();
9235 }
9236 }
9237 setHTMLAtributeAtPosition(position, attributeName, value) {
9238 var _getBlockConfig;
9239 const block = this.document.getBlockAtPosition(position);
9240 const allowedHTMLAttributes = (_getBlockConfig = getBlockConfig(block.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.htmlAttributes;
9241 if (block && allowedHTMLAttributes !== null && allowedHTMLAttributes !== void 0 && allowedHTMLAttributes.includes(attributeName)) {
9242 const newDocument = this.document.setHTMLAttributeAtPosition(position, attributeName, value);
9243 this.setDocument(newDocument);
9244 }
9245 }
9246 setTextAttribute(attributeName, value) {
9247 const selectedRange = this.getSelectedRange();
9248 if (!selectedRange) return;
9249 const [startPosition, endPosition] = Array.from(selectedRange);
9250 if (startPosition === endPosition) {
9251 if (attributeName === "href") {
9252 const text = Text.textForStringWithAttributes(value, {
9253 href: value
9254 });
9255 return this.insertText(text);
9256 }
9257 } else {
9258 return this.setDocument(this.document.addAttributeAtRange(attributeName, value, selectedRange));
9259 }
9260 }
9261 setBlockAttribute(attributeName, value) {
9262 const selectedRange = this.getSelectedRange();
9263 if (this.canSetCurrentAttribute(attributeName)) {
9264 this.setDocument(this.document.applyBlockAttributeAtRange(attributeName, value, selectedRange));
9265 return this.setSelection(selectedRange);
9266 }
9267 }
9268 removeCurrentAttribute(attributeName) {
9269 if (getBlockConfig(attributeName)) {
9270 this.removeBlockAttribute(attributeName);
9271 return this.updateCurrentAttributes();
9272 } else {
9273 this.removeTextAttribute(attributeName);
9274 delete this.currentAttributes[attributeName];
9275 return this.notifyDelegateOfCurrentAttributesChange();
9276 }
9277 }
9278 removeTextAttribute(attributeName) {
9279 const selectedRange = this.getSelectedRange();
9280 if (!selectedRange) return;
9281 return this.setDocument(this.document.removeAttributeAtRange(attributeName, selectedRange));
9282 }
9283 removeBlockAttribute(attributeName) {
9284 const selectedRange = this.getSelectedRange();
9285 if (!selectedRange) return;
9286 return this.setDocument(this.document.removeAttributeAtRange(attributeName, selectedRange));
9287 }
9288 canDecreaseNestingLevel() {
9289 var _this$getBlock;
9290 return ((_this$getBlock = this.getBlock()) === null || _this$getBlock === void 0 ? void 0 : _this$getBlock.getNestingLevel()) > 0;
9291 }
9292 canIncreaseNestingLevel() {
9293 var _getBlockConfig2;
9294 const block = this.getBlock();
9295 if (!block) return;
9296 if ((_getBlockConfig2 = getBlockConfig(block.getLastNestableAttribute())) !== null && _getBlockConfig2 !== void 0 && _getBlockConfig2.listAttribute) {
9297 const previousBlock = this.getPreviousBlock();
9298 if (previousBlock) {
9299 return arrayStartsWith(previousBlock.getListItemAttributes(), block.getListItemAttributes());
9300 }
9301 } else {
9302 return block.getNestingLevel() > 0;
9303 }
9304 }
9305 decreaseNestingLevel() {
9306 const block = this.getBlock();
9307 if (!block) return;
9308 return this.setDocument(this.document.replaceBlock(block, block.decreaseNestingLevel()));
9309 }
9310 increaseNestingLevel() {
9311 const block = this.getBlock();
9312 if (!block) return;
9313 return this.setDocument(this.document.replaceBlock(block, block.increaseNestingLevel()));
9314 }
9315 canDecreaseBlockAttributeLevel() {
9316 var _this$getBlock2;
9317 return ((_this$getBlock2 = this.getBlock()) === null || _this$getBlock2 === void 0 ? void 0 : _this$getBlock2.getAttributeLevel()) > 0;
9318 }
9319 decreaseBlockAttributeLevel() {
9320 var _this$getBlock3;
9321 const attribute = (_this$getBlock3 = this.getBlock()) === null || _this$getBlock3 === void 0 ? void 0 : _this$getBlock3.getLastAttribute();
9322 if (attribute) {
9323 return this.removeCurrentAttribute(attribute);
9324 }
9325 }
9326 decreaseListLevel() {
9327 let [startPosition] = Array.from(this.getSelectedRange());
9328 const {
9329 index
9330 } = this.document.locationFromPosition(startPosition);
9331 let endIndex = index;
9332 const attributeLevel = this.getBlock().getAttributeLevel();
9333 let block = this.document.getBlockAtIndex(endIndex + 1);
9334 while (block) {
9335 if (!block.isListItem() || block.getAttributeLevel() <= attributeLevel) {
9336 break;
9337 }
9338 endIndex++;
9339 block = this.document.getBlockAtIndex(endIndex + 1);
9340 }
9341 startPosition = this.document.positionFromLocation({
9342 index,
9343 offset: 0
9344 });
9345 const endPosition = this.document.positionFromLocation({
9346 index: endIndex,
9347 offset: 0
9348 });
9349 return this.setDocument(this.document.removeLastListAttributeAtRange([startPosition, endPosition]));
9350 }
9351 updateCurrentAttributes() {
9352 const selectedRange = this.getSelectedRange({
9353 ignoreLock: true
9354 });
9355 if (selectedRange) {
9356 const currentAttributes = this.document.getCommonAttributesAtRange(selectedRange);
9357 Array.from(getAllAttributeNames()).forEach(attributeName => {
9358 if (!currentAttributes[attributeName]) {
9359 if (!this.canSetCurrentAttribute(attributeName)) {
9360 currentAttributes[attributeName] = false;
9361 }
9362 }
9363 });
9364 if (!objectsAreEqual(currentAttributes, this.currentAttributes)) {
9365 this.currentAttributes = currentAttributes;
9366 return this.notifyDelegateOfCurrentAttributesChange();
9367 }
9368 }
9369 }
9370 getCurrentAttributes() {
9371 return extend.call({}, this.currentAttributes);
9372 }
9373 getCurrentTextAttributes() {
9374 const attributes = {};
9375 for (const key in this.currentAttributes) {
9376 const value = this.currentAttributes[key];
9377 if (value !== false) {
9378 if (getTextConfig(key)) {
9379 attributes[key] = value;
9380 }
9381 }
9382 }
9383 return attributes;
9384 }
9385
9386 // Selection freezing
9387
9388 freezeSelection() {
9389 return this.setCurrentAttribute("frozen", true);
9390 }
9391 thawSelection() {
9392 return this.removeCurrentAttribute("frozen");
9393 }
9394 hasFrozenSelection() {
9395 return this.hasCurrentAttribute("frozen");
9396 }
9397 setSelection(selectedRange) {
9398 var _this$delegate5;
9399 const locationRange = this.document.locationRangeFromRange(selectedRange);
9400 return (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 ? void 0 : _this$delegate5.compositionDidRequestChangingSelectionToLocationRange(locationRange);
9401 }
9402 getSelectedRange() {
9403 const locationRange = this.getLocationRange();
9404 if (locationRange) {
9405 return this.document.rangeFromLocationRange(locationRange);
9406 }
9407 }
9408 setSelectedRange(selectedRange) {
9409 const locationRange = this.document.locationRangeFromRange(selectedRange);
9410 return this.getSelectionManager().setLocationRange(locationRange);
9411 }
9412 getPosition() {
9413 const locationRange = this.getLocationRange();
9414 if (locationRange) {
9415 return this.document.positionFromLocation(locationRange[0]);
9416 }
9417 }
9418 getLocationRange(options) {
9419 if (this.targetLocationRange) {
9420 return this.targetLocationRange;
9421 } else {
9422 return this.getSelectionManager().getLocationRange(options) || normalizeRange({
9423 index: 0,
9424 offset: 0
9425 });
9426 }
9427 }
9428 withTargetLocationRange(locationRange, fn) {
9429 let result;
9430 this.targetLocationRange = locationRange;
9431 try {
9432 result = fn();
9433 } finally {
9434 this.targetLocationRange = null;
9435 }
9436 return result;
9437 }
9438 withTargetRange(range, fn) {
9439 const locationRange = this.document.locationRangeFromRange(range);
9440 return this.withTargetLocationRange(locationRange, fn);
9441 }
9442 withTargetDOMRange(domRange, fn) {
9443 const locationRange = this.createLocationRangeFromDOMRange(domRange, {
9444 strict: false
9445 });
9446 return this.withTargetLocationRange(locationRange, fn);
9447 }
9448 getExpandedRangeInDirection(direction) {
9449 let {
9450 length
9451 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9452 let [startPosition, endPosition] = Array.from(this.getSelectedRange());
9453 if (direction === "backward") {
9454 if (length) {
9455 startPosition -= length;
9456 } else {
9457 startPosition = this.translateUTF16PositionFromOffset(startPosition, -1);
9458 }
9459 } else {
9460 if (length) {
9461 endPosition += length;
9462 } else {
9463 endPosition = this.translateUTF16PositionFromOffset(endPosition, 1);
9464 }
9465 }
9466 return normalizeRange([startPosition, endPosition]);
9467 }
9468 shouldManageMovingCursorInDirection(direction) {
9469 if (this.editingAttachment) {
9470 return true;
9471 }
9472 const range = this.getExpandedRangeInDirection(direction);
9473 return this.getAttachmentAtRange(range) != null;
9474 }
9475 moveCursorInDirection(direction) {
9476 let canEditAttachment, range;
9477 if (this.editingAttachment) {
9478 range = this.document.getRangeOfAttachment(this.editingAttachment);
9479 } else {
9480 const selectedRange = this.getSelectedRange();
9481 range = this.getExpandedRangeInDirection(direction);
9482 canEditAttachment = !rangesAreEqual(selectedRange, range);
9483 }
9484 if (direction === "backward") {
9485 this.setSelectedRange(range[0]);
9486 } else {
9487 this.setSelectedRange(range[1]);
9488 }
9489 if (canEditAttachment) {
9490 const attachment = this.getAttachmentAtRange(range);
9491 if (attachment) {
9492 return this.editAttachment(attachment);
9493 }
9494 }
9495 }
9496 expandSelectionInDirection(direction) {
9497 let {
9498 length
9499 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9500 const range = this.getExpandedRangeInDirection(direction, {
9501 length
9502 });
9503 return this.setSelectedRange(range);
9504 }
9505 expandSelectionForEditing() {
9506 if (this.hasCurrentAttribute("href")) {
9507 return this.expandSelectionAroundCommonAttribute("href");
9508 }
9509 }
9510 expandSelectionAroundCommonAttribute(attributeName) {
9511 const position = this.getPosition();
9512 const range = this.document.getRangeOfCommonAttributeAtPosition(attributeName, position);
9513 return this.setSelectedRange(range);
9514 }
9515 selectionContainsAttachments() {
9516 var _this$getSelectedAtta;
9517 return ((_this$getSelectedAtta = this.getSelectedAttachments()) === null || _this$getSelectedAtta === void 0 ? void 0 : _this$getSelectedAtta.length) > 0;
9518 }
9519 selectionIsInCursorTarget() {
9520 return this.editingAttachment || this.positionIsCursorTarget(this.getPosition());
9521 }
9522 positionIsCursorTarget(position) {
9523 const location = this.document.locationFromPosition(position);
9524 if (location) {
9525 return this.locationIsCursorTarget(location);
9526 }
9527 }
9528 positionIsBlockBreak(position) {
9529 var _this$document$getPie;
9530 return (_this$document$getPie = this.document.getPieceAtPosition(position)) === null || _this$document$getPie === void 0 ? void 0 : _this$document$getPie.isBlockBreak();
9531 }
9532 getSelectedDocument() {
9533 const selectedRange = this.getSelectedRange();
9534 if (selectedRange) {
9535 return this.document.getDocumentAtRange(selectedRange);
9536 }
9537 }
9538 getSelectedAttachments() {
9539 var _this$getSelectedDocu;
9540 return (_this$getSelectedDocu = this.getSelectedDocument()) === null || _this$getSelectedDocu === void 0 ? void 0 : _this$getSelectedDocu.getAttachments();
9541 }
9542
9543 // Attachments
9544
9545 getAttachments() {
9546 return this.attachments.slice(0);
9547 }
9548 refreshAttachments() {
9549 const attachments = this.document.getAttachments();
9550 const {
9551 added,
9552 removed
9553 } = summarizeArrayChange(this.attachments, attachments);
9554 this.attachments = attachments;
9555 Array.from(removed).forEach(attachment => {
9556 var _this$delegate6, _this$delegate6$compo;
9557 attachment.delegate = null;
9558 (_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);
9559 });
9560 return (() => {
9561 const result = [];
9562 Array.from(added).forEach(attachment => {
9563 var _this$delegate7, _this$delegate7$compo;
9564 attachment.delegate = this;
9565 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));
9566 });
9567 return result;
9568 })();
9569 }
9570
9571 // Attachment delegate
9572
9573 attachmentDidChangeAttributes(attachment) {
9574 var _this$delegate8, _this$delegate8$compo;
9575 this.revision++;
9576 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);
9577 }
9578 attachmentDidChangePreviewURL(attachment) {
9579 var _this$delegate9, _this$delegate9$compo;
9580 this.revision++;
9581 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);
9582 }
9583
9584 // Attachment editing
9585
9586 editAttachment(attachment, options) {
9587 var _this$delegate10, _this$delegate10$comp;
9588 if (attachment === this.editingAttachment) return;
9589 this.stopEditingAttachment();
9590 this.editingAttachment = attachment;
9591 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);
9592 }
9593 stopEditingAttachment() {
9594 var _this$delegate11, _this$delegate11$comp;
9595 if (!this.editingAttachment) return;
9596 (_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);
9597 this.editingAttachment = null;
9598 }
9599 updateAttributesForAttachment(attributes, attachment) {
9600 return this.setDocument(this.document.updateAttributesForAttachment(attributes, attachment));
9601 }
9602 removeAttributeForAttachment(attribute, attachment) {
9603 return this.setDocument(this.document.removeAttributeForAttachment(attribute, attachment));
9604 }
9605
9606 // Private
9607
9608 breakFormattedBlock(insertion) {
9609 let {
9610 document
9611 } = insertion;
9612 const {
9613 block
9614 } = insertion;
9615 let position = insertion.startPosition;
9616 let range = [position - 1, position];
9617 if (block.getBlockBreakPosition() === insertion.startLocation.offset) {
9618 if (block.breaksOnReturn() && insertion.nextCharacter === "\n") {
9619 position += 1;
9620 } else {
9621 document = document.removeTextAtRange(range);
9622 }
9623 range = [position, position];
9624 } else if (insertion.nextCharacter === "\n") {
9625 if (insertion.previousCharacter === "\n") {
9626 range = [position - 1, position + 1];
9627 } else {
9628 range = [position, position + 1];
9629 position += 1;
9630 }
9631 } else if (insertion.startLocation.offset - 1 !== 0) {
9632 position += 1;
9633 }
9634 const newDocument = new Document([block.removeLastAttribute().copyWithoutText()]);
9635 this.setDocument(document.insertDocumentAtRange(newDocument, range));
9636 return this.setSelection(position);
9637 }
9638 getPreviousBlock() {
9639 const locationRange = this.getLocationRange();
9640 if (locationRange) {
9641 const {
9642 index
9643 } = locationRange[0];
9644 if (index > 0) {
9645 return this.document.getBlockAtIndex(index - 1);
9646 }
9647 }
9648 }
9649 getBlock() {
9650 const locationRange = this.getLocationRange();
9651 if (locationRange) {
9652 return this.document.getBlockAtIndex(locationRange[0].index);
9653 }
9654 }
9655 getAttachmentAtRange(range) {
9656 const document = this.document.getDocumentAtRange(range);
9657 if (document.toString() === "".concat(OBJECT_REPLACEMENT_CHARACTER, "\n")) {
9658 return document.getAttachments()[0];
9659 }
9660 }
9661 notifyDelegateOfCurrentAttributesChange() {
9662 var _this$delegate12, _this$delegate12$comp;
9663 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);
9664 }
9665 notifyDelegateOfInsertionAtRange(range) {
9666 var _this$delegate13, _this$delegate13$comp;
9667 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);
9668 }
9669 translateUTF16PositionFromOffset(position, offset) {
9670 const utf16string = this.document.toUTF16String();
9671 const utf16position = utf16string.offsetFromUCS2Offset(position);
9672 return utf16string.offsetToUCS2Offset(utf16position + offset);
9673 }
9674 }
9675 Composition.proxyMethod("getSelectionManager().getPointRange");
9676 Composition.proxyMethod("getSelectionManager().setLocationRangeFromPointRange");
9677 Composition.proxyMethod("getSelectionManager().createLocationRangeFromDOMRange");
9678 Composition.proxyMethod("getSelectionManager().locationIsCursorTarget");
9679 Composition.proxyMethod("getSelectionManager().selectionIsExpanded");
9680 Composition.proxyMethod("delegate?.getSelectionManager");
9681
9682 class UndoManager extends BasicObject {
9683 constructor(composition) {
9684 super(...arguments);
9685 this.composition = composition;
9686 this.undoEntries = [];
9687 this.redoEntries = [];
9688 }
9689 recordUndoEntry(description) {
9690 let {
9691 context,
9692 consolidatable
9693 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9694 const previousEntry = this.undoEntries.slice(-1)[0];
9695 if (!consolidatable || !entryHasDescriptionAndContext(previousEntry, description, context)) {
9696 const undoEntry = this.createEntry({
9697 description,
9698 context
9699 });
9700 this.undoEntries.push(undoEntry);
9701 this.redoEntries = [];
9702 }
9703 }
9704 undo() {
9705 const undoEntry = this.undoEntries.pop();
9706 if (undoEntry) {
9707 const redoEntry = this.createEntry(undoEntry);
9708 this.redoEntries.push(redoEntry);
9709 return this.composition.loadSnapshot(undoEntry.snapshot);
9710 }
9711 }
9712 redo() {
9713 const redoEntry = this.redoEntries.pop();
9714 if (redoEntry) {
9715 const undoEntry = this.createEntry(redoEntry);
9716 this.undoEntries.push(undoEntry);
9717 return this.composition.loadSnapshot(redoEntry.snapshot);
9718 }
9719 }
9720 canUndo() {
9721 return this.undoEntries.length > 0;
9722 }
9723 canRedo() {
9724 return this.redoEntries.length > 0;
9725 }
9726
9727 // Private
9728
9729 createEntry() {
9730 let {
9731 description,
9732 context
9733 } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
9734 return {
9735 description: description === null || description === void 0 ? void 0 : description.toString(),
9736 context: JSON.stringify(context),
9737 snapshot: this.composition.getSnapshot()
9738 };
9739 }
9740 }
9741 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);
9742
9743 const BLOCK_ATTRIBUTE_NAME = "attachmentGallery";
9744 const TEXT_ATTRIBUTE_NAME = "presentation";
9745 const TEXT_ATTRIBUTE_VALUE = "gallery";
9746 class Filter {
9747 constructor(snapshot) {
9748 this.document = snapshot.document;
9749 this.selectedRange = snapshot.selectedRange;
9750 }
9751 perform() {
9752 this.removeBlockAttribute();
9753 return this.applyBlockAttribute();
9754 }
9755 getSnapshot() {
9756 return {
9757 document: this.document,
9758 selectedRange: this.selectedRange
9759 };
9760 }
9761
9762 // Private
9763
9764 removeBlockAttribute() {
9765 return this.findRangesOfBlocks().map(range => this.document = this.document.removeAttributeAtRange(BLOCK_ATTRIBUTE_NAME, range));
9766 }
9767 applyBlockAttribute() {
9768 let offset = 0;
9769 this.findRangesOfPieces().forEach(range => {
9770 if (range[1] - range[0] > 1) {
9771 range[0] += offset;
9772 range[1] += offset;
9773 if (this.document.getCharacterAtPosition(range[1]) !== "\n") {
9774 this.document = this.document.insertBlockBreakAtRange(range[1]);
9775 if (range[1] < this.selectedRange[1]) {
9776 this.moveSelectedRangeForward();
9777 }
9778 range[1]++;
9779 offset++;
9780 }
9781 if (range[0] !== 0) {
9782 if (this.document.getCharacterAtPosition(range[0] - 1) !== "\n") {
9783 this.document = this.document.insertBlockBreakAtRange(range[0]);
9784 if (range[0] < this.selectedRange[0]) {
9785 this.moveSelectedRangeForward();
9786 }
9787 range[0]++;
9788 offset++;
9789 }
9790 }
9791 this.document = this.document.applyBlockAttributeAtRange(BLOCK_ATTRIBUTE_NAME, true, range);
9792 }
9793 });
9794 }
9795 findRangesOfBlocks() {
9796 return this.document.findRangesForBlockAttribute(BLOCK_ATTRIBUTE_NAME);
9797 }
9798 findRangesOfPieces() {
9799 return this.document.findRangesForTextAttribute(TEXT_ATTRIBUTE_NAME, {
9800 withValue: TEXT_ATTRIBUTE_VALUE
9801 });
9802 }
9803 moveSelectedRangeForward() {
9804 this.selectedRange[0] += 1;
9805 this.selectedRange[1] += 1;
9806 }
9807 }
9808
9809 const attachmentGalleryFilter = function (snapshot) {
9810 const filter = new Filter(snapshot);
9811 filter.perform();
9812 return filter.getSnapshot();
9813 };
9814
9815 const DEFAULT_FILTERS = [attachmentGalleryFilter];
9816 class Editor {
9817 constructor(composition, selectionManager, element) {
9818 this.insertFiles = this.insertFiles.bind(this);
9819 this.composition = composition;
9820 this.selectionManager = selectionManager;
9821 this.element = element;
9822 this.undoManager = new UndoManager(this.composition);
9823 this.filters = DEFAULT_FILTERS.slice(0);
9824 }
9825 loadDocument(document) {
9826 return this.loadSnapshot({
9827 document,
9828 selectedRange: [0, 0]
9829 });
9830 }
9831 loadHTML() {
9832 let html = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
9833 const document = HTMLParser.parse(html, {
9834 referenceElement: this.element
9835 }).getDocument();
9836 return this.loadDocument(document);
9837 }
9838 loadJSON(_ref) {
9839 let {
9840 document,
9841 selectedRange
9842 } = _ref;
9843 document = Document.fromJSON(document);
9844 return this.loadSnapshot({
9845 document,
9846 selectedRange
9847 });
9848 }
9849 loadSnapshot(snapshot) {
9850 this.undoManager = new UndoManager(this.composition);
9851 return this.composition.loadSnapshot(snapshot);
9852 }
9853 getDocument() {
9854 return this.composition.document;
9855 }
9856 getSelectedDocument() {
9857 return this.composition.getSelectedDocument();
9858 }
9859 getSnapshot() {
9860 return this.composition.getSnapshot();
9861 }
9862 toJSON() {
9863 return this.getSnapshot();
9864 }
9865
9866 // Document manipulation
9867
9868 deleteInDirection(direction) {
9869 return this.composition.deleteInDirection(direction);
9870 }
9871 insertAttachment(attachment) {
9872 return this.composition.insertAttachment(attachment);
9873 }
9874 insertAttachments(attachments) {
9875 return this.composition.insertAttachments(attachments);
9876 }
9877 insertDocument(document) {
9878 return this.composition.insertDocument(document);
9879 }
9880 insertFile(file) {
9881 return this.composition.insertFile(file);
9882 }
9883 insertFiles(files) {
9884 return this.composition.insertFiles(files);
9885 }
9886 insertHTML(html) {
9887 return this.composition.insertHTML(html);
9888 }
9889 insertString(string) {
9890 return this.composition.insertString(string);
9891 }
9892 insertText(text) {
9893 return this.composition.insertText(text);
9894 }
9895 insertLineBreak() {
9896 return this.composition.insertLineBreak();
9897 }
9898
9899 // Selection
9900
9901 getSelectedRange() {
9902 return this.composition.getSelectedRange();
9903 }
9904 getPosition() {
9905 return this.composition.getPosition();
9906 }
9907 getClientRectAtPosition(position) {
9908 const locationRange = this.getDocument().locationRangeFromRange([position, position + 1]);
9909 return this.selectionManager.getClientRectAtLocationRange(locationRange);
9910 }
9911 expandSelectionInDirection(direction) {
9912 return this.composition.expandSelectionInDirection(direction);
9913 }
9914 moveCursorInDirection(direction) {
9915 return this.composition.moveCursorInDirection(direction);
9916 }
9917 setSelectedRange(selectedRange) {
9918 return this.composition.setSelectedRange(selectedRange);
9919 }
9920
9921 // Attributes
9922
9923 activateAttribute(name) {
9924 let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
9925 return this.composition.setCurrentAttribute(name, value);
9926 }
9927 attributeIsActive(name) {
9928 return this.composition.hasCurrentAttribute(name);
9929 }
9930 canActivateAttribute(name) {
9931 return this.composition.canSetCurrentAttribute(name);
9932 }
9933 deactivateAttribute(name) {
9934 return this.composition.removeCurrentAttribute(name);
9935 }
9936
9937 // HTML attributes
9938 setHTMLAtributeAtPosition(position, name, value) {
9939 this.composition.setHTMLAtributeAtPosition(position, name, value);
9940 }
9941
9942 // Nesting level
9943
9944 canDecreaseNestingLevel() {
9945 return this.composition.canDecreaseNestingLevel();
9946 }
9947 canIncreaseNestingLevel() {
9948 return this.composition.canIncreaseNestingLevel();
9949 }
9950 decreaseNestingLevel() {
9951 if (this.canDecreaseNestingLevel()) {
9952 return this.composition.decreaseNestingLevel();
9953 }
9954 }
9955 increaseNestingLevel() {
9956 if (this.canIncreaseNestingLevel()) {
9957 return this.composition.increaseNestingLevel();
9958 }
9959 }
9960
9961 // Undo/redo
9962
9963 canRedo() {
9964 return this.undoManager.canRedo();
9965 }
9966 canUndo() {
9967 return this.undoManager.canUndo();
9968 }
9969 recordUndoEntry(description) {
9970 let {
9971 context,
9972 consolidatable
9973 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9974 return this.undoManager.recordUndoEntry(description, {
9975 context,
9976 consolidatable
9977 });
9978 }
9979 redo() {
9980 if (this.canRedo()) {
9981 return this.undoManager.redo();
9982 }
9983 }
9984 undo() {
9985 if (this.canUndo()) {
9986 return this.undoManager.undo();
9987 }
9988 }
9989 }
9990
9991 /* eslint-disable
9992 no-var,
9993 prefer-const,
9994 */
9995 class LocationMapper {
9996 constructor(element) {
9997 this.element = element;
9998 }
9999 findLocationFromContainerAndOffset(container, offset) {
10000 let {
10001 strict
10002 } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
10003 strict: true
10004 };
10005 let childIndex = 0;
10006 let foundBlock = false;
10007 const location = {
10008 index: 0,
10009 offset: 0
10010 };
10011 const attachmentElement = this.findAttachmentElementParentForNode(container);
10012 if (attachmentElement) {
10013 container = attachmentElement.parentNode;
10014 offset = findChildIndexOfNode(attachmentElement);
10015 }
10016 const walker = walkTree(this.element, {
10017 usingFilter: rejectAttachmentContents
10018 });
10019 while (walker.nextNode()) {
10020 const node = walker.currentNode;
10021 if (node === container && nodeIsTextNode(container)) {
10022 if (!nodeIsCursorTarget(node)) {
10023 location.offset += offset;
10024 }
10025 break;
10026 } else {
10027 if (node.parentNode === container) {
10028 if (childIndex++ === offset) {
10029 break;
10030 }
10031 } else if (!elementContainsNode(container, node)) {
10032 if (childIndex > 0) {
10033 break;
10034 }
10035 }
10036 if (nodeIsBlockStart(node, {
10037 strict
10038 })) {
10039 if (foundBlock) {
10040 location.index++;
10041 }
10042 location.offset = 0;
10043 foundBlock = true;
10044 } else {
10045 location.offset += nodeLength(node);
10046 }
10047 }
10048 }
10049 return location;
10050 }
10051 findContainerAndOffsetFromLocation(location) {
10052 let container, offset;
10053 if (location.index === 0 && location.offset === 0) {
10054 container = this.element;
10055 offset = 0;
10056 while (container.firstChild) {
10057 container = container.firstChild;
10058 if (nodeIsBlockContainer(container)) {
10059 offset = 1;
10060 break;
10061 }
10062 }
10063 return [container, offset];
10064 }
10065 let [node, nodeOffset] = this.findNodeAndOffsetFromLocation(location);
10066 if (!node) return;
10067 if (nodeIsTextNode(node)) {
10068 if (nodeLength(node) === 0) {
10069 container = node.parentNode.parentNode;
10070 offset = findChildIndexOfNode(node.parentNode);
10071 if (nodeIsCursorTarget(node, {
10072 name: "right"
10073 })) {
10074 offset++;
10075 }
10076 } else {
10077 container = node;
10078 offset = location.offset - nodeOffset;
10079 }
10080 } else {
10081 container = node.parentNode;
10082 if (!nodeIsBlockStart(node.previousSibling)) {
10083 if (!nodeIsBlockContainer(container)) {
10084 while (node === container.lastChild) {
10085 node = container;
10086 container = container.parentNode;
10087 if (nodeIsBlockContainer(container)) {
10088 break;
10089 }
10090 }
10091 }
10092 }
10093 offset = findChildIndexOfNode(node);
10094 if (location.offset !== 0) {
10095 offset++;
10096 }
10097 }
10098 return [container, offset];
10099 }
10100 findNodeAndOffsetFromLocation(location) {
10101 let node, nodeOffset;
10102 let offset = 0;
10103 for (const currentNode of this.getSignificantNodesForIndex(location.index)) {
10104 const length = nodeLength(currentNode);
10105 if (location.offset <= offset + length) {
10106 if (nodeIsTextNode(currentNode)) {
10107 node = currentNode;
10108 nodeOffset = offset;
10109 if (location.offset === nodeOffset && nodeIsCursorTarget(node)) {
10110 break;
10111 }
10112 } else if (!node) {
10113 node = currentNode;
10114 nodeOffset = offset;
10115 }
10116 }
10117 offset += length;
10118 if (offset > location.offset) {
10119 break;
10120 }
10121 }
10122 return [node, nodeOffset];
10123 }
10124
10125 // Private
10126
10127 findAttachmentElementParentForNode(node) {
10128 while (node && node !== this.element) {
10129 if (nodeIsAttachmentElement(node)) {
10130 return node;
10131 }
10132 node = node.parentNode;
10133 }
10134 }
10135 getSignificantNodesForIndex(index) {
10136 const nodes = [];
10137 const walker = walkTree(this.element, {
10138 usingFilter: acceptSignificantNodes
10139 });
10140 let recordingNodes = false;
10141 while (walker.nextNode()) {
10142 const node = walker.currentNode;
10143 if (nodeIsBlockStartComment(node)) {
10144 var blockIndex;
10145 if (blockIndex != null) {
10146 blockIndex++;
10147 } else {
10148 blockIndex = 0;
10149 }
10150 if (blockIndex === index) {
10151 recordingNodes = true;
10152 } else if (recordingNodes) {
10153 break;
10154 }
10155 } else if (recordingNodes) {
10156 nodes.push(node);
10157 }
10158 }
10159 return nodes;
10160 }
10161 }
10162 const nodeLength = function (node) {
10163 if (node.nodeType === Node.TEXT_NODE) {
10164 if (nodeIsCursorTarget(node)) {
10165 return 0;
10166 } else {
10167 const string = node.textContent;
10168 return string.length;
10169 }
10170 } else if (tagName(node) === "br" || nodeIsAttachmentElement(node)) {
10171 return 1;
10172 } else {
10173 return 0;
10174 }
10175 };
10176 const acceptSignificantNodes = function (node) {
10177 if (rejectEmptyTextNodes(node) === NodeFilter.FILTER_ACCEPT) {
10178 return rejectAttachmentContents(node);
10179 } else {
10180 return NodeFilter.FILTER_REJECT;
10181 }
10182 };
10183 const rejectEmptyTextNodes = function (node) {
10184 if (nodeIsEmptyTextNode(node)) {
10185 return NodeFilter.FILTER_REJECT;
10186 } else {
10187 return NodeFilter.FILTER_ACCEPT;
10188 }
10189 };
10190 const rejectAttachmentContents = function (node) {
10191 if (nodeIsAttachmentElement(node.parentNode)) {
10192 return NodeFilter.FILTER_REJECT;
10193 } else {
10194 return NodeFilter.FILTER_ACCEPT;
10195 }
10196 };
10197
10198 /* eslint-disable
10199 id-length,
10200 no-empty,
10201 */
10202 class PointMapper {
10203 createDOMRangeFromPoint(_ref) {
10204 let {
10205 x,
10206 y
10207 } = _ref;
10208 let domRange;
10209 if (document.caretPositionFromPoint) {
10210 const {
10211 offsetNode,
10212 offset
10213 } = document.caretPositionFromPoint(x, y);
10214 domRange = document.createRange();
10215 domRange.setStart(offsetNode, offset);
10216 return domRange;
10217 } else if (document.caretRangeFromPoint) {
10218 return document.caretRangeFromPoint(x, y);
10219 } else if (document.body.createTextRange) {
10220 const originalDOMRange = getDOMRange();
10221 try {
10222 // IE 11 throws "Unspecified error" when using moveToPoint
10223 // during a drag-and-drop operation.
10224 const textRange = document.body.createTextRange();
10225 textRange.moveToPoint(x, y);
10226 textRange.select();
10227 } catch (error) {}
10228 domRange = getDOMRange();
10229 setDOMRange(originalDOMRange);
10230 return domRange;
10231 }
10232 }
10233 getClientRectsForDOMRange(domRange) {
10234 const array = Array.from(domRange.getClientRects());
10235 const start = array[0];
10236 const end = array[array.length - 1];
10237 return [start, end];
10238 }
10239 }
10240
10241 /* eslint-disable
10242 */
10243 class SelectionManager extends BasicObject {
10244 constructor(element) {
10245 super(...arguments);
10246 this.didMouseDown = this.didMouseDown.bind(this);
10247 this.selectionDidChange = this.selectionDidChange.bind(this);
10248 this.element = element;
10249 this.locationMapper = new LocationMapper(this.element);
10250 this.pointMapper = new PointMapper();
10251 this.lockCount = 0;
10252 handleEvent("mousedown", {
10253 onElement: this.element,
10254 withCallback: this.didMouseDown
10255 });
10256 }
10257 getLocationRange() {
10258 let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
10259 if (options.strict === false) {
10260 return this.createLocationRangeFromDOMRange(getDOMRange());
10261 } else if (options.ignoreLock) {
10262 return this.currentLocationRange;
10263 } else if (this.lockedLocationRange) {
10264 return this.lockedLocationRange;
10265 } else {
10266 return this.currentLocationRange;
10267 }
10268 }
10269 setLocationRange(locationRange) {
10270 if (this.lockedLocationRange) return;
10271 locationRange = normalizeRange(locationRange);
10272 const domRange = this.createDOMRangeFromLocationRange(locationRange);
10273 if (domRange) {
10274 setDOMRange(domRange);
10275 this.updateCurrentLocationRange(locationRange);
10276 }
10277 }
10278 setLocationRangeFromPointRange(pointRange) {
10279 pointRange = normalizeRange(pointRange);
10280 const startLocation = this.getLocationAtPoint(pointRange[0]);
10281 const endLocation = this.getLocationAtPoint(pointRange[1]);
10282 this.setLocationRange([startLocation, endLocation]);
10283 }
10284 getClientRectAtLocationRange(locationRange) {
10285 const domRange = this.createDOMRangeFromLocationRange(locationRange);
10286 if (domRange) {
10287 return this.getClientRectsForDOMRange(domRange)[1];
10288 }
10289 }
10290 locationIsCursorTarget(location) {
10291 const node = Array.from(this.findNodeAndOffsetFromLocation(location))[0];
10292 return nodeIsCursorTarget(node);
10293 }
10294 lock() {
10295 if (this.lockCount++ === 0) {
10296 this.updateCurrentLocationRange();
10297 this.lockedLocationRange = this.getLocationRange();
10298 }
10299 }
10300 unlock() {
10301 if (--this.lockCount === 0) {
10302 const {
10303 lockedLocationRange
10304 } = this;
10305 this.lockedLocationRange = null;
10306 if (lockedLocationRange != null) {
10307 return this.setLocationRange(lockedLocationRange);
10308 }
10309 }
10310 }
10311 clearSelection() {
10312 var _getDOMSelection;
10313 return (_getDOMSelection = getDOMSelection()) === null || _getDOMSelection === void 0 ? void 0 : _getDOMSelection.removeAllRanges();
10314 }
10315 selectionIsCollapsed() {
10316 var _getDOMRange;
10317 return ((_getDOMRange = getDOMRange()) === null || _getDOMRange === void 0 ? void 0 : _getDOMRange.collapsed) === true;
10318 }
10319 selectionIsExpanded() {
10320 return !this.selectionIsCollapsed();
10321 }
10322 createLocationRangeFromDOMRange(domRange, options) {
10323 if (domRange == null || !this.domRangeWithinElement(domRange)) return;
10324 const start = this.findLocationFromContainerAndOffset(domRange.startContainer, domRange.startOffset, options);
10325 if (!start) return;
10326 const end = domRange.collapsed ? undefined : this.findLocationFromContainerAndOffset(domRange.endContainer, domRange.endOffset, options);
10327 return normalizeRange([start, end]);
10328 }
10329 didMouseDown() {
10330 return this.pauseTemporarily();
10331 }
10332 pauseTemporarily() {
10333 let resumeHandlers;
10334 this.paused = true;
10335 const resume = () => {
10336 this.paused = false;
10337 clearTimeout(resumeTimeout);
10338 Array.from(resumeHandlers).forEach(handler => {
10339 handler.destroy();
10340 });
10341 if (elementContainsNode(document, this.element)) {
10342 return this.selectionDidChange();
10343 }
10344 };
10345 const resumeTimeout = setTimeout(resume, 200);
10346 resumeHandlers = ["mousemove", "keydown"].map(eventName => handleEvent(eventName, {
10347 onElement: document,
10348 withCallback: resume
10349 }));
10350 }
10351 selectionDidChange() {
10352 if (!this.paused && !innerElementIsActive(this.element)) {
10353 return this.updateCurrentLocationRange();
10354 }
10355 }
10356 updateCurrentLocationRange(locationRange) {
10357 if (locationRange != null ? locationRange : locationRange = this.createLocationRangeFromDOMRange(getDOMRange())) {
10358 if (!rangesAreEqual(locationRange, this.currentLocationRange)) {
10359 var _this$delegate, _this$delegate$locati;
10360 this.currentLocationRange = locationRange;
10361 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));
10362 }
10363 }
10364 }
10365 createDOMRangeFromLocationRange(locationRange) {
10366 const rangeStart = this.findContainerAndOffsetFromLocation(locationRange[0]);
10367 const rangeEnd = rangeIsCollapsed(locationRange) ? rangeStart : this.findContainerAndOffsetFromLocation(locationRange[1]) || rangeStart;
10368 if (rangeStart != null && rangeEnd != null) {
10369 const domRange = document.createRange();
10370 domRange.setStart(...Array.from(rangeStart || []));
10371 domRange.setEnd(...Array.from(rangeEnd || []));
10372 return domRange;
10373 }
10374 }
10375 getLocationAtPoint(point) {
10376 const domRange = this.createDOMRangeFromPoint(point);
10377 if (domRange) {
10378 var _this$createLocationR;
10379 return (_this$createLocationR = this.createLocationRangeFromDOMRange(domRange)) === null || _this$createLocationR === void 0 ? void 0 : _this$createLocationR[0];
10380 }
10381 }
10382 domRangeWithinElement(domRange) {
10383 if (domRange.collapsed) {
10384 return elementContainsNode(this.element, domRange.startContainer);
10385 } else {
10386 return elementContainsNode(this.element, domRange.startContainer) && elementContainsNode(this.element, domRange.endContainer);
10387 }
10388 }
10389 }
10390 SelectionManager.proxyMethod("locationMapper.findLocationFromContainerAndOffset");
10391 SelectionManager.proxyMethod("locationMapper.findContainerAndOffsetFromLocation");
10392 SelectionManager.proxyMethod("locationMapper.findNodeAndOffsetFromLocation");
10393 SelectionManager.proxyMethod("pointMapper.createDOMRangeFromPoint");
10394 SelectionManager.proxyMethod("pointMapper.getClientRectsForDOMRange");
10395
10396 var models = /*#__PURE__*/Object.freeze({
10397 __proto__: null,
10398 Attachment: Attachment,
10399 AttachmentManager: AttachmentManager,
10400 AttachmentPiece: AttachmentPiece,
10401 Block: Block,
10402 Composition: Composition,
10403 Document: Document,
10404 Editor: Editor,
10405 HTMLParser: HTMLParser,
10406 HTMLSanitizer: HTMLSanitizer,
10407 LineBreakInsertion: LineBreakInsertion,
10408 LocationMapper: LocationMapper,
10409 ManagedAttachment: ManagedAttachment,
10410 Piece: Piece,
10411 PointMapper: PointMapper,
10412 SelectionManager: SelectionManager,
10413 SplittableList: SplittableList,
10414 StringPiece: StringPiece,
10415 Text: Text,
10416 UndoManager: UndoManager
10417 });
10418
10419 var views = /*#__PURE__*/Object.freeze({
10420 __proto__: null,
10421 ObjectView: ObjectView,
10422 AttachmentView: AttachmentView,
10423 BlockView: BlockView,
10424 DocumentView: DocumentView,
10425 PieceView: PieceView,
10426 PreviewableAttachmentView: PreviewableAttachmentView,
10427 TextView: TextView
10428 });
10429
10430 const {
10431 lang,
10432 css,
10433 keyNames: keyNames$1
10434 } = config;
10435 const undoable = function (fn) {
10436 return function () {
10437 const commands = fn.apply(this, arguments);
10438 commands.do();
10439 if (!this.undos) {
10440 this.undos = [];
10441 }
10442 this.undos.push(commands.undo);
10443 };
10444 };
10445 class AttachmentEditorController extends BasicObject {
10446 constructor(attachmentPiece, _element, container) {
10447 let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
10448 super(...arguments);
10449 // Installing and uninstalling
10450 _defineProperty(this, "makeElementMutable", undoable(() => {
10451 return {
10452 do: () => {
10453 this.element.dataset.trixMutable = true;
10454 },
10455 undo: () => delete this.element.dataset.trixMutable
10456 };
10457 }));
10458 _defineProperty(this, "addToolbar", undoable(() => {
10459 // <div class="#{css.attachmentMetadataContainer}" data-trix-mutable="true">
10460 // <div class="trix-button-row">
10461 // <span class="trix-button-group trix-button-group--actions">
10462 // <button type="button" class="trix-button trix-button--remove" title="#{lang.remove}" data-trix-action="remove">#{lang.remove}</button>
10463 // </span>
10464 // </div>
10465 // </div>
10466 const element = makeElement({
10467 tagName: "div",
10468 className: css.attachmentToolbar,
10469 data: {
10470 trixMutable: true
10471 },
10472 childNodes: makeElement({
10473 tagName: "div",
10474 className: "trix-button-row",
10475 childNodes: makeElement({
10476 tagName: "span",
10477 className: "trix-button-group trix-button-group--actions",
10478 childNodes: makeElement({
10479 tagName: "button",
10480 className: "trix-button trix-button--remove",
10481 textContent: lang.remove,
10482 attributes: {
10483 title: lang.remove
10484 },
10485 data: {
10486 trixAction: "remove"
10487 }
10488 })
10489 })
10490 })
10491 });
10492 if (this.attachment.isPreviewable()) {
10493 // <div class="#{css.attachmentMetadataContainer}">
10494 // <span class="#{css.attachmentMetadata}">
10495 // <span class="#{css.attachmentName}" title="#{name}">#{name}</span>
10496 // <span class="#{css.attachmentSize}">#{size}</span>
10497 // </span>
10498 // </div>
10499 element.appendChild(makeElement({
10500 tagName: "div",
10501 className: css.attachmentMetadataContainer,
10502 childNodes: makeElement({
10503 tagName: "span",
10504 className: css.attachmentMetadata,
10505 childNodes: [makeElement({
10506 tagName: "span",
10507 className: css.attachmentName,
10508 textContent: this.attachment.getFilename(),
10509 attributes: {
10510 title: this.attachment.getFilename()
10511 }
10512 }), makeElement({
10513 tagName: "span",
10514 className: css.attachmentSize,
10515 textContent: this.attachment.getFormattedFilesize()
10516 })]
10517 })
10518 }));
10519 }
10520 handleEvent("click", {
10521 onElement: element,
10522 withCallback: this.didClickToolbar
10523 });
10524 handleEvent("click", {
10525 onElement: element,
10526 matchingSelector: "[data-trix-action]",
10527 withCallback: this.didClickActionButton
10528 });
10529 triggerEvent("trix-attachment-before-toolbar", {
10530 onElement: this.element,
10531 attributes: {
10532 toolbar: element,
10533 attachment: this.attachment
10534 }
10535 });
10536 return {
10537 do: () => this.element.appendChild(element),
10538 undo: () => removeNode(element)
10539 };
10540 }));
10541 _defineProperty(this, "installCaptionEditor", undoable(() => {
10542 const textarea = makeElement({
10543 tagName: "textarea",
10544 className: css.attachmentCaptionEditor,
10545 attributes: {
10546 placeholder: lang.captionPlaceholder
10547 },
10548 data: {
10549 trixMutable: true
10550 }
10551 });
10552 textarea.value = this.attachmentPiece.getCaption();
10553 const textareaClone = textarea.cloneNode();
10554 textareaClone.classList.add("trix-autoresize-clone");
10555 textareaClone.tabIndex = -1;
10556 const autoresize = function () {
10557 textareaClone.value = textarea.value;
10558 textarea.style.height = textareaClone.scrollHeight + "px";
10559 };
10560 handleEvent("input", {
10561 onElement: textarea,
10562 withCallback: autoresize
10563 });
10564 handleEvent("input", {
10565 onElement: textarea,
10566 withCallback: this.didInputCaption
10567 });
10568 handleEvent("keydown", {
10569 onElement: textarea,
10570 withCallback: this.didKeyDownCaption
10571 });
10572 handleEvent("change", {
10573 onElement: textarea,
10574 withCallback: this.didChangeCaption
10575 });
10576 handleEvent("blur", {
10577 onElement: textarea,
10578 withCallback: this.didBlurCaption
10579 });
10580 const figcaption = this.element.querySelector("figcaption");
10581 const editingFigcaption = figcaption.cloneNode();
10582 return {
10583 do: () => {
10584 figcaption.style.display = "none";
10585 editingFigcaption.appendChild(textarea);
10586 editingFigcaption.appendChild(textareaClone);
10587 editingFigcaption.classList.add("".concat(css.attachmentCaption, "--editing"));
10588 figcaption.parentElement.insertBefore(editingFigcaption, figcaption);
10589 autoresize();
10590 if (this.options.editCaption) {
10591 return defer(() => textarea.focus());
10592 }
10593 },
10594 undo() {
10595 removeNode(editingFigcaption);
10596 figcaption.style.display = null;
10597 }
10598 };
10599 }));
10600 this.didClickToolbar = this.didClickToolbar.bind(this);
10601 this.didClickActionButton = this.didClickActionButton.bind(this);
10602 this.didKeyDownCaption = this.didKeyDownCaption.bind(this);
10603 this.didInputCaption = this.didInputCaption.bind(this);
10604 this.didChangeCaption = this.didChangeCaption.bind(this);
10605 this.didBlurCaption = this.didBlurCaption.bind(this);
10606 this.attachmentPiece = attachmentPiece;
10607 this.element = _element;
10608 this.container = container;
10609 this.options = options;
10610 this.attachment = this.attachmentPiece.attachment;
10611 if (tagName(this.element) === "a") {
10612 this.element = this.element.firstChild;
10613 }
10614 this.install();
10615 }
10616 install() {
10617 this.makeElementMutable();
10618 this.addToolbar();
10619 if (this.attachment.isPreviewable()) {
10620 this.installCaptionEditor();
10621 }
10622 }
10623 uninstall() {
10624 var _this$delegate;
10625 let undo = this.undos.pop();
10626 this.savePendingCaption();
10627 while (undo) {
10628 undo();
10629 undo = this.undos.pop();
10630 }
10631 (_this$delegate = this.delegate) === null || _this$delegate === void 0 || _this$delegate.didUninstallAttachmentEditor(this);
10632 }
10633
10634 // Private
10635
10636 savePendingCaption() {
10637 if (this.pendingCaption != null) {
10638 const caption = this.pendingCaption;
10639 this.pendingCaption = null;
10640 if (caption) {
10641 var _this$delegate2, _this$delegate2$attac;
10642 (_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, {
10643 caption
10644 }, this.attachment);
10645 } else {
10646 var _this$delegate3, _this$delegate3$attac;
10647 (_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);
10648 }
10649 }
10650 }
10651 // Event handlers
10652
10653 didClickToolbar(event) {
10654 event.preventDefault();
10655 return event.stopPropagation();
10656 }
10657 didClickActionButton(event) {
10658 var _this$delegate4;
10659 const action = event.target.getAttribute("data-trix-action");
10660 switch (action) {
10661 case "remove":
10662 return (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 ? void 0 : _this$delegate4.attachmentEditorDidRequestRemovalOfAttachment(this.attachment);
10663 }
10664 }
10665 didKeyDownCaption(event) {
10666 if (keyNames$1[event.keyCode] === "return") {
10667 var _this$delegate5, _this$delegate5$attac;
10668 event.preventDefault();
10669 this.savePendingCaption();
10670 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);
10671 }
10672 }
10673 didInputCaption(event) {
10674 this.pendingCaption = event.target.value.replace(/\s/g, " ").trim();
10675 }
10676 didChangeCaption(event) {
10677 return this.savePendingCaption();
10678 }
10679 didBlurCaption(event) {
10680 return this.savePendingCaption();
10681 }
10682 }
10683
10684 class CompositionController extends BasicObject {
10685 constructor(element, composition) {
10686 super(...arguments);
10687 this.didFocus = this.didFocus.bind(this);
10688 this.didBlur = this.didBlur.bind(this);
10689 this.didClickAttachment = this.didClickAttachment.bind(this);
10690 this.element = element;
10691 this.composition = composition;
10692 this.documentView = new DocumentView(this.composition.document, {
10693 element: this.element
10694 });
10695 handleEvent("focus", {
10696 onElement: this.element,
10697 withCallback: this.didFocus
10698 });
10699 handleEvent("blur", {
10700 onElement: this.element,
10701 withCallback: this.didBlur
10702 });
10703 handleEvent("click", {
10704 onElement: this.element,
10705 matchingSelector: "a[contenteditable=false]",
10706 preventDefault: true
10707 });
10708 handleEvent("mousedown", {
10709 onElement: this.element,
10710 matchingSelector: attachmentSelector,
10711 withCallback: this.didClickAttachment
10712 });
10713 handleEvent("click", {
10714 onElement: this.element,
10715 matchingSelector: "a".concat(attachmentSelector),
10716 preventDefault: true
10717 });
10718 }
10719 didFocus(event) {
10720 var _this$blurPromise;
10721 const perform = () => {
10722 if (!this.focused) {
10723 var _this$delegate, _this$delegate$compos;
10724 this.focused = true;
10725 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);
10726 }
10727 };
10728 return ((_this$blurPromise = this.blurPromise) === null || _this$blurPromise === void 0 ? void 0 : _this$blurPromise.then(perform)) || perform();
10729 }
10730 didBlur(event) {
10731 this.blurPromise = new Promise(resolve => {
10732 return defer(() => {
10733 if (!innerElementIsActive(this.element)) {
10734 var _this$delegate2, _this$delegate2$compo;
10735 this.focused = null;
10736 (_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);
10737 }
10738 this.blurPromise = null;
10739 return resolve();
10740 });
10741 });
10742 }
10743 didClickAttachment(event, target) {
10744 var _this$delegate3, _this$delegate3$compo;
10745 const attachment = this.findAttachmentForElement(target);
10746 const editCaption = !!findClosestElementFromNode(event.target, {
10747 matchingSelector: "figcaption"
10748 });
10749 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, {
10750 editCaption
10751 });
10752 }
10753 getSerializableElement() {
10754 if (this.isEditingAttachment()) {
10755 return this.documentView.shadowElement;
10756 } else {
10757 return this.element;
10758 }
10759 }
10760 render() {
10761 var _this$delegate6, _this$delegate6$compo;
10762 if (this.revision !== this.composition.revision) {
10763 this.documentView.setDocument(this.composition.document);
10764 this.documentView.render();
10765 this.revision = this.composition.revision;
10766 }
10767 if (this.canSyncDocumentView() && !this.documentView.isSynced()) {
10768 var _this$delegate4, _this$delegate4$compo, _this$delegate5, _this$delegate5$compo;
10769 (_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);
10770 this.documentView.sync();
10771 (_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);
10772 }
10773 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);
10774 }
10775 rerenderViewForObject(object) {
10776 this.invalidateViewForObject(object);
10777 return this.render();
10778 }
10779 invalidateViewForObject(object) {
10780 return this.documentView.invalidateViewForObject(object);
10781 }
10782 isViewCachingEnabled() {
10783 return this.documentView.isViewCachingEnabled();
10784 }
10785 enableViewCaching() {
10786 return this.documentView.enableViewCaching();
10787 }
10788 disableViewCaching() {
10789 return this.documentView.disableViewCaching();
10790 }
10791 refreshViewCache() {
10792 return this.documentView.garbageCollectCachedViews();
10793 }
10794
10795 // Attachment editor management
10796
10797 isEditingAttachment() {
10798 return !!this.attachmentEditor;
10799 }
10800 installAttachmentEditorForAttachment(attachment, options) {
10801 var _this$attachmentEdito;
10802 if (((_this$attachmentEdito = this.attachmentEditor) === null || _this$attachmentEdito === void 0 ? void 0 : _this$attachmentEdito.attachment) === attachment) return;
10803 const element = this.documentView.findElementForObject(attachment);
10804 if (!element) return;
10805 this.uninstallAttachmentEditor();
10806 const attachmentPiece = this.composition.document.getAttachmentPieceForAttachment(attachment);
10807 this.attachmentEditor = new AttachmentEditorController(attachmentPiece, element, this.element, options);
10808 this.attachmentEditor.delegate = this;
10809 }
10810 uninstallAttachmentEditor() {
10811 var _this$attachmentEdito2;
10812 return (_this$attachmentEdito2 = this.attachmentEditor) === null || _this$attachmentEdito2 === void 0 ? void 0 : _this$attachmentEdito2.uninstall();
10813 }
10814
10815 // Attachment controller delegate
10816
10817 didUninstallAttachmentEditor() {
10818 this.attachmentEditor = null;
10819 return this.render();
10820 }
10821 attachmentEditorDidRequestUpdatingAttributesForAttachment(attributes, attachment) {
10822 var _this$delegate7, _this$delegate7$compo;
10823 (_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);
10824 return this.composition.updateAttributesForAttachment(attributes, attachment);
10825 }
10826 attachmentEditorDidRequestRemovingAttributeForAttachment(attribute, attachment) {
10827 var _this$delegate8, _this$delegate8$compo;
10828 (_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);
10829 return this.composition.removeAttributeForAttachment(attribute, attachment);
10830 }
10831 attachmentEditorDidRequestRemovalOfAttachment(attachment) {
10832 var _this$delegate9, _this$delegate9$compo;
10833 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);
10834 }
10835 attachmentEditorDidRequestDeselectingAttachment(attachment) {
10836 var _this$delegate10, _this$delegate10$comp;
10837 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);
10838 }
10839
10840 // Private
10841
10842 canSyncDocumentView() {
10843 return !this.isEditingAttachment();
10844 }
10845 findAttachmentForElement(element) {
10846 return this.composition.document.getAttachmentById(parseInt(element.dataset.trixId, 10));
10847 }
10848 }
10849
10850 class Controller extends BasicObject {}
10851
10852 const mutableAttributeName = "data-trix-mutable";
10853 const mutableSelector = "[".concat(mutableAttributeName, "]");
10854 const options = {
10855 attributes: true,
10856 childList: true,
10857 characterData: true,
10858 characterDataOldValue: true,
10859 subtree: true
10860 };
10861 class MutationObserver extends BasicObject {
10862 constructor(element) {
10863 super(element);
10864 this.didMutate = this.didMutate.bind(this);
10865 this.element = element;
10866 this.observer = new window.MutationObserver(this.didMutate);
10867 this.start();
10868 }
10869 start() {
10870 this.reset();
10871 return this.observer.observe(this.element, options);
10872 }
10873 stop() {
10874 return this.observer.disconnect();
10875 }
10876 didMutate(mutations) {
10877 this.mutations.push(...Array.from(this.findSignificantMutations(mutations) || []));
10878 if (this.mutations.length) {
10879 var _this$delegate, _this$delegate$elemen;
10880 (_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());
10881 return this.reset();
10882 }
10883 }
10884
10885 // Private
10886
10887 reset() {
10888 this.mutations = [];
10889 }
10890 findSignificantMutations(mutations) {
10891 return mutations.filter(mutation => {
10892 return this.mutationIsSignificant(mutation);
10893 });
10894 }
10895 mutationIsSignificant(mutation) {
10896 if (this.nodeIsMutable(mutation.target)) {
10897 return false;
10898 }
10899 for (const node of Array.from(this.nodesModifiedByMutation(mutation))) {
10900 if (this.nodeIsSignificant(node)) return true;
10901 }
10902 return false;
10903 }
10904 nodeIsSignificant(node) {
10905 return node !== this.element && !this.nodeIsMutable(node) && !nodeIsEmptyTextNode(node);
10906 }
10907 nodeIsMutable(node) {
10908 return findClosestElementFromNode(node, {
10909 matchingSelector: mutableSelector
10910 });
10911 }
10912 nodesModifiedByMutation(mutation) {
10913 const nodes = [];
10914 switch (mutation.type) {
10915 case "attributes":
10916 if (mutation.attributeName !== mutableAttributeName) {
10917 nodes.push(mutation.target);
10918 }
10919 break;
10920 case "characterData":
10921 // Changes to text nodes should consider the parent element
10922 nodes.push(mutation.target.parentNode);
10923 nodes.push(mutation.target);
10924 break;
10925 case "childList":
10926 // Consider each added or removed node
10927 nodes.push(...Array.from(mutation.addedNodes || []));
10928 nodes.push(...Array.from(mutation.removedNodes || []));
10929 break;
10930 }
10931 return nodes;
10932 }
10933 getMutationSummary() {
10934 return this.getTextMutationSummary();
10935 }
10936 getTextMutationSummary() {
10937 const {
10938 additions,
10939 deletions
10940 } = this.getTextChangesFromCharacterData();
10941 const textChanges = this.getTextChangesFromChildList();
10942 Array.from(textChanges.additions).forEach(addition => {
10943 if (!Array.from(additions).includes(addition)) {
10944 additions.push(addition);
10945 }
10946 });
10947 deletions.push(...Array.from(textChanges.deletions || []));
10948 const summary = {};
10949 const added = additions.join("");
10950 if (added) {
10951 summary.textAdded = added;
10952 }
10953 const deleted = deletions.join("");
10954 if (deleted) {
10955 summary.textDeleted = deleted;
10956 }
10957 return summary;
10958 }
10959 getMutationsByType(type) {
10960 return Array.from(this.mutations).filter(mutation => mutation.type === type);
10961 }
10962 getTextChangesFromChildList() {
10963 let textAdded, textRemoved;
10964 const addedNodes = [];
10965 const removedNodes = [];
10966 Array.from(this.getMutationsByType("childList")).forEach(mutation => {
10967 addedNodes.push(...Array.from(mutation.addedNodes || []));
10968 removedNodes.push(...Array.from(mutation.removedNodes || []));
10969 });
10970 const singleBlockCommentRemoved = addedNodes.length === 0 && removedNodes.length === 1 && nodeIsBlockStartComment(removedNodes[0]);
10971 if (singleBlockCommentRemoved) {
10972 textAdded = [];
10973 textRemoved = ["\n"];
10974 } else {
10975 textAdded = getTextForNodes(addedNodes);
10976 textRemoved = getTextForNodes(removedNodes);
10977 }
10978 const additions = textAdded.filter((text, index) => text !== textRemoved[index]).map(normalizeSpaces);
10979 const deletions = textRemoved.filter((text, index) => text !== textAdded[index]).map(normalizeSpaces);
10980 return {
10981 additions,
10982 deletions
10983 };
10984 }
10985 getTextChangesFromCharacterData() {
10986 let added, removed;
10987 const characterMutations = this.getMutationsByType("characterData");
10988 if (characterMutations.length) {
10989 const startMutation = characterMutations[0],
10990 endMutation = characterMutations[characterMutations.length - 1];
10991 const oldString = normalizeSpaces(startMutation.oldValue);
10992 const newString = normalizeSpaces(endMutation.target.data);
10993 const summarized = summarizeStringChange(oldString, newString);
10994 added = summarized.added;
10995 removed = summarized.removed;
10996 }
10997 return {
10998 additions: added ? [added] : [],
10999 deletions: removed ? [removed] : []
11000 };
11001 }
11002 }
11003 const getTextForNodes = function () {
11004 let nodes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
11005 const text = [];
11006 for (const node of Array.from(nodes)) {
11007 switch (node.nodeType) {
11008 case Node.TEXT_NODE:
11009 text.push(node.data);
11010 break;
11011 case Node.ELEMENT_NODE:
11012 if (tagName(node) === "br") {
11013 text.push("\n");
11014 } else {
11015 text.push(...Array.from(getTextForNodes(node.childNodes) || []));
11016 }
11017 break;
11018 }
11019 }
11020 return text;
11021 };
11022
11023 /* eslint-disable
11024 no-empty,
11025 */
11026 class FileVerificationOperation extends Operation {
11027 constructor(file) {
11028 super(...arguments);
11029 this.file = file;
11030 }
11031 perform(callback) {
11032 const reader = new FileReader();
11033 reader.onerror = () => callback(false);
11034 reader.onload = () => {
11035 reader.onerror = null;
11036 try {
11037 reader.abort();
11038 } catch (error) {}
11039 return callback(true, this.file);
11040 };
11041 return reader.readAsArrayBuffer(this.file);
11042 }
11043 }
11044
11045 // Each software keyboard on Android emits its own set of events and some of them can be buggy.
11046 // This class detects when some buggy events are being emitted and lets know the input controller
11047 // that they should be ignored.
11048 class FlakyAndroidKeyboardDetector {
11049 constructor(element) {
11050 this.element = element;
11051 }
11052 shouldIgnore(event) {
11053 if (!browser$1.samsungAndroid) return false;
11054 this.previousEvent = this.event;
11055 this.event = event;
11056 this.checkSamsungKeyboardBuggyModeStart();
11057 this.checkSamsungKeyboardBuggyModeEnd();
11058 return this.buggyMode;
11059 }
11060
11061 // private
11062
11063 // The Samsung keyboard on Android can enter a buggy state in which it emits a flurry of confused events that,
11064 // if processed, corrupts the editor. The buggy mode always starts with an insertText event, right after a
11065 // keydown event with for an "Unidentified" key, with the same text as the editor element, except for a few
11066 // extra whitespace, or exotic utf8, characters.
11067 checkSamsungKeyboardBuggyModeStart() {
11068 if (this.insertingLongTextAfterUnidentifiedChar() && differsInWhitespace(this.element.innerText, this.event.data)) {
11069 this.buggyMode = true;
11070 this.event.preventDefault();
11071 }
11072 }
11073
11074 // The flurry of buggy events are always insertText. If we see any other type, it means it's over.
11075 checkSamsungKeyboardBuggyModeEnd() {
11076 if (this.buggyMode && this.event.inputType !== "insertText") {
11077 this.buggyMode = false;
11078 }
11079 }
11080 insertingLongTextAfterUnidentifiedChar() {
11081 var _this$event$data;
11082 return this.isBeforeInputInsertText() && this.previousEventWasUnidentifiedKeydown() && ((_this$event$data = this.event.data) === null || _this$event$data === void 0 ? void 0 : _this$event$data.length) > 50;
11083 }
11084 isBeforeInputInsertText() {
11085 return this.event.type === "beforeinput" && this.event.inputType === "insertText";
11086 }
11087 previousEventWasUnidentifiedKeydown() {
11088 var _this$previousEvent, _this$previousEvent2;
11089 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";
11090 }
11091 }
11092 const differsInWhitespace = (text1, text2) => {
11093 return normalize(text1) === normalize(text2);
11094 };
11095 const whiteSpaceNormalizerRegexp = new RegExp("(".concat(OBJECT_REPLACEMENT_CHARACTER, "|").concat(ZERO_WIDTH_SPACE, "|").concat(NON_BREAKING_SPACE, "|\\s)+"), "g");
11096 const normalize = text => text.replace(whiteSpaceNormalizerRegexp, " ").trim();
11097
11098 class InputController extends BasicObject {
11099 constructor(element) {
11100 super(...arguments);
11101 this.element = element;
11102 this.mutationObserver = new MutationObserver(this.element);
11103 this.mutationObserver.delegate = this;
11104 this.flakyKeyboardDetector = new FlakyAndroidKeyboardDetector(this.element);
11105 for (const eventName in this.constructor.events) {
11106 handleEvent(eventName, {
11107 onElement: this.element,
11108 withCallback: this.handlerFor(eventName)
11109 });
11110 }
11111 }
11112 elementDidMutate(mutationSummary) {}
11113 editorWillSyncDocumentView() {
11114 return this.mutationObserver.stop();
11115 }
11116 editorDidSyncDocumentView() {
11117 return this.mutationObserver.start();
11118 }
11119 requestRender() {
11120 var _this$delegate, _this$delegate$inputC;
11121 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);
11122 }
11123 requestReparse() {
11124 var _this$delegate2, _this$delegate2$input;
11125 (_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);
11126 return this.requestRender();
11127 }
11128 attachFiles(files) {
11129 const operations = Array.from(files).map(file => new FileVerificationOperation(file));
11130 return Promise.all(operations).then(files => {
11131 this.handleInput(function () {
11132 var _this$delegate3, _this$responder;
11133 (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || _this$delegate3.inputControllerWillAttachFiles();
11134 (_this$responder = this.responder) === null || _this$responder === void 0 || _this$responder.insertFiles(files);
11135 return this.requestRender();
11136 });
11137 });
11138 }
11139
11140 // Private
11141
11142 handlerFor(eventName) {
11143 return event => {
11144 if (!event.defaultPrevented) {
11145 this.handleInput(() => {
11146 if (!innerElementIsActive(this.element)) {
11147 if (this.flakyKeyboardDetector.shouldIgnore(event)) return;
11148 this.eventName = eventName;
11149 this.constructor.events[eventName].call(this, event);
11150 }
11151 });
11152 }
11153 };
11154 }
11155 handleInput(callback) {
11156 try {
11157 var _this$delegate4;
11158 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillHandleInput();
11159 callback.call(this);
11160 } finally {
11161 var _this$delegate5;
11162 (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.inputControllerDidHandleInput();
11163 }
11164 }
11165 createLinkHTML(href, text) {
11166 const link = document.createElement("a");
11167 link.href = href;
11168 link.textContent = text ? text : href;
11169 return link.outerHTML;
11170 }
11171 }
11172 _defineProperty(InputController, "events", {});
11173
11174 var _$codePointAt, _;
11175 const {
11176 browser,
11177 keyNames
11178 } = config;
11179 let pastedFileCount = 0;
11180 class Level0InputController extends InputController {
11181 constructor() {
11182 super(...arguments);
11183 this.resetInputSummary();
11184 }
11185 setInputSummary() {
11186 let summary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
11187 this.inputSummary.eventName = this.eventName;
11188 for (const key in summary) {
11189 const value = summary[key];
11190 this.inputSummary[key] = value;
11191 }
11192 return this.inputSummary;
11193 }
11194 resetInputSummary() {
11195 this.inputSummary = {};
11196 }
11197 reset() {
11198 this.resetInputSummary();
11199 return selectionChangeObserver.reset();
11200 }
11201
11202 // Mutation observer delegate
11203
11204 elementDidMutate(mutationSummary) {
11205 if (this.isComposing()) {
11206 var _this$delegate, _this$delegate$inputC;
11207 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);
11208 } else {
11209 return this.handleInput(function () {
11210 if (this.mutationIsSignificant(mutationSummary)) {
11211 if (this.mutationIsExpected(mutationSummary)) {
11212 this.requestRender();
11213 } else {
11214 this.requestReparse();
11215 }
11216 }
11217 return this.reset();
11218 });
11219 }
11220 }
11221 mutationIsExpected(_ref) {
11222 let {
11223 textAdded,
11224 textDeleted
11225 } = _ref;
11226 if (this.inputSummary.preferDocument) {
11227 return true;
11228 }
11229 const mutationAdditionMatchesSummary = textAdded != null ? textAdded === this.inputSummary.textAdded : !this.inputSummary.textAdded;
11230 const mutationDeletionMatchesSummary = textDeleted != null ? this.inputSummary.didDelete : !this.inputSummary.didDelete;
11231 const unexpectedNewlineAddition = ["\n", " \n"].includes(textAdded) && !mutationAdditionMatchesSummary;
11232 const unexpectedNewlineDeletion = textDeleted === "\n" && !mutationDeletionMatchesSummary;
11233 const singleUnexpectedNewline = unexpectedNewlineAddition && !unexpectedNewlineDeletion || unexpectedNewlineDeletion && !unexpectedNewlineAddition;
11234 if (singleUnexpectedNewline) {
11235 const range = this.getSelectedRange();
11236 if (range) {
11237 var _this$responder;
11238 const offset = unexpectedNewlineAddition ? textAdded.replace(/\n$/, "").length || -1 : (textAdded === null || textAdded === void 0 ? void 0 : textAdded.length) || 1;
11239 if ((_this$responder = this.responder) !== null && _this$responder !== void 0 && _this$responder.positionIsBlockBreak(range[1] + offset)) {
11240 return true;
11241 }
11242 }
11243 }
11244 return mutationAdditionMatchesSummary && mutationDeletionMatchesSummary;
11245 }
11246 mutationIsSignificant(mutationSummary) {
11247 var _this$compositionInpu;
11248 const textChanged = Object.keys(mutationSummary).length > 0;
11249 const composedEmptyString = ((_this$compositionInpu = this.compositionInput) === null || _this$compositionInpu === void 0 ? void 0 : _this$compositionInpu.getEndData()) === "";
11250 return textChanged || !composedEmptyString;
11251 }
11252
11253 // Private
11254
11255 getCompositionInput() {
11256 if (this.isComposing()) {
11257 return this.compositionInput;
11258 } else {
11259 this.compositionInput = new CompositionInput(this);
11260 }
11261 }
11262 isComposing() {
11263 return this.compositionInput && !this.compositionInput.isEnded();
11264 }
11265 deleteInDirection(direction, event) {
11266 var _this$responder2;
11267 if (((_this$responder2 = this.responder) === null || _this$responder2 === void 0 ? void 0 : _this$responder2.deleteInDirection(direction)) === false) {
11268 if (event) {
11269 event.preventDefault();
11270 return this.requestRender();
11271 }
11272 } else {
11273 return this.setInputSummary({
11274 didDelete: true
11275 });
11276 }
11277 }
11278 serializeSelectionToDataTransfer(dataTransfer) {
11279 var _this$responder3;
11280 if (!dataTransferIsWritable(dataTransfer)) return;
11281 const document = (_this$responder3 = this.responder) === null || _this$responder3 === void 0 ? void 0 : _this$responder3.getSelectedDocument().toSerializableDocument();
11282 dataTransfer.setData("application/x-trix-document", JSON.stringify(document));
11283 dataTransfer.setData("text/html", DocumentView.render(document).innerHTML);
11284 dataTransfer.setData("text/plain", document.toString().replace(/\n$/, ""));
11285 return true;
11286 }
11287 canAcceptDataTransfer(dataTransfer) {
11288 const types = {};
11289 Array.from((dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.types) || []).forEach(type => {
11290 types[type] = true;
11291 });
11292 return types.Files || types["application/x-trix-document"] || types["text/html"] || types["text/plain"];
11293 }
11294 getPastedHTMLUsingHiddenElement(callback) {
11295 const selectedRange = this.getSelectedRange();
11296 const style = {
11297 position: "absolute",
11298 left: "".concat(window.pageXOffset, "px"),
11299 top: "".concat(window.pageYOffset, "px"),
11300 opacity: 0
11301 };
11302 const element = makeElement({
11303 style,
11304 tagName: "div",
11305 editable: true
11306 });
11307 document.body.appendChild(element);
11308 element.focus();
11309 return requestAnimationFrame(() => {
11310 const html = element.innerHTML;
11311 removeNode(element);
11312 this.setSelectedRange(selectedRange);
11313 return callback(html);
11314 });
11315 }
11316 }
11317 _defineProperty(Level0InputController, "events", {
11318 keydown(event) {
11319 if (!this.isComposing()) {
11320 this.resetInputSummary();
11321 }
11322 this.inputSummary.didInput = true;
11323 const keyName = keyNames[event.keyCode];
11324 if (keyName) {
11325 var _context2;
11326 let context = this.keys;
11327 ["ctrl", "alt", "shift", "meta"].forEach(modifier => {
11328 if (event["".concat(modifier, "Key")]) {
11329 var _context;
11330 if (modifier === "ctrl") {
11331 modifier = "control";
11332 }
11333 context = (_context = context) === null || _context === void 0 ? void 0 : _context[modifier];
11334 }
11335 });
11336 if (((_context2 = context) === null || _context2 === void 0 ? void 0 : _context2[keyName]) != null) {
11337 this.setInputSummary({
11338 keyName
11339 });
11340 selectionChangeObserver.reset();
11341 context[keyName].call(this, event);
11342 }
11343 }
11344 if (keyEventIsKeyboardCommand(event)) {
11345 const character = String.fromCharCode(event.keyCode).toLowerCase();
11346 if (character) {
11347 var _this$delegate3;
11348 const keys = ["alt", "shift"].map(modifier => {
11349 if (event["".concat(modifier, "Key")]) {
11350 return modifier;
11351 }
11352 }).filter(key => key);
11353 keys.push(character);
11354 if ((_this$delegate3 = this.delegate) !== null && _this$delegate3 !== void 0 && _this$delegate3.inputControllerDidReceiveKeyboardCommand(keys)) {
11355 event.preventDefault();
11356 }
11357 }
11358 }
11359 },
11360 keypress(event) {
11361 if (this.inputSummary.eventName != null) return;
11362 if (event.metaKey) return;
11363 if (event.ctrlKey && !event.altKey) return;
11364 const string = stringFromKeyEvent(event);
11365 if (string) {
11366 var _this$delegate4, _this$responder9;
11367 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillPerformTyping();
11368 (_this$responder9 = this.responder) === null || _this$responder9 === void 0 || _this$responder9.insertString(string);
11369 return this.setInputSummary({
11370 textAdded: string,
11371 didDelete: this.selectionIsExpanded()
11372 });
11373 }
11374 },
11375 textInput(event) {
11376 // Handle autocapitalization
11377 const {
11378 data
11379 } = event;
11380 const {
11381 textAdded
11382 } = this.inputSummary;
11383 if (textAdded && textAdded !== data && textAdded.toUpperCase() === data) {
11384 var _this$responder10;
11385 const range = this.getSelectedRange();
11386 this.setSelectedRange([range[0], range[1] + textAdded.length]);
11387 (_this$responder10 = this.responder) === null || _this$responder10 === void 0 || _this$responder10.insertString(data);
11388 this.setInputSummary({
11389 textAdded: data
11390 });
11391 return this.setSelectedRange(range);
11392 }
11393 },
11394 dragenter(event) {
11395 event.preventDefault();
11396 },
11397 dragstart(event) {
11398 var _this$delegate5, _this$delegate5$input;
11399 this.serializeSelectionToDataTransfer(event.dataTransfer);
11400 this.draggedRange = this.getSelectedRange();
11401 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);
11402 },
11403 dragover(event) {
11404 if (this.draggedRange || this.canAcceptDataTransfer(event.dataTransfer)) {
11405 event.preventDefault();
11406 const draggingPoint = {
11407 x: event.clientX,
11408 y: event.clientY
11409 };
11410 if (!objectsAreEqual(draggingPoint, this.draggingPoint)) {
11411 var _this$delegate6, _this$delegate6$input;
11412 this.draggingPoint = draggingPoint;
11413 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);
11414 }
11415 }
11416 },
11417 dragend(event) {
11418 var _this$delegate7, _this$delegate7$input;
11419 (_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);
11420 this.draggedRange = null;
11421 this.draggingPoint = null;
11422 },
11423 drop(event) {
11424 var _event$dataTransfer, _this$responder11;
11425 event.preventDefault();
11426 const files = (_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.files;
11427 const documentJSON = event.dataTransfer.getData("application/x-trix-document");
11428 const point = {
11429 x: event.clientX,
11430 y: event.clientY
11431 };
11432 (_this$responder11 = this.responder) === null || _this$responder11 === void 0 || _this$responder11.setLocationRangeFromPointRange(point);
11433 if (files !== null && files !== void 0 && files.length) {
11434 this.attachFiles(files);
11435 } else if (this.draggedRange) {
11436 var _this$delegate8, _this$responder12;
11437 (_this$delegate8 = this.delegate) === null || _this$delegate8 === void 0 || _this$delegate8.inputControllerWillMoveText();
11438 (_this$responder12 = this.responder) === null || _this$responder12 === void 0 || _this$responder12.moveTextFromRange(this.draggedRange);
11439 this.draggedRange = null;
11440 this.requestRender();
11441 } else if (documentJSON) {
11442 var _this$responder13;
11443 const document = Document.fromJSONString(documentJSON);
11444 (_this$responder13 = this.responder) === null || _this$responder13 === void 0 || _this$responder13.insertDocument(document);
11445 this.requestRender();
11446 }
11447 this.draggedRange = null;
11448 this.draggingPoint = null;
11449 },
11450 cut(event) {
11451 var _this$responder14;
11452 if ((_this$responder14 = this.responder) !== null && _this$responder14 !== void 0 && _this$responder14.selectionIsExpanded()) {
11453 var _this$delegate9;
11454 if (this.serializeSelectionToDataTransfer(event.clipboardData)) {
11455 event.preventDefault();
11456 }
11457 (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 || _this$delegate9.inputControllerWillCutText();
11458 this.deleteInDirection("backward");
11459 if (event.defaultPrevented) {
11460 return this.requestRender();
11461 }
11462 }
11463 },
11464 copy(event) {
11465 var _this$responder15;
11466 if ((_this$responder15 = this.responder) !== null && _this$responder15 !== void 0 && _this$responder15.selectionIsExpanded()) {
11467 if (this.serializeSelectionToDataTransfer(event.clipboardData)) {
11468 event.preventDefault();
11469 }
11470 }
11471 },
11472 paste(event) {
11473 const clipboard = event.clipboardData || event.testClipboardData;
11474 const paste = {
11475 clipboard
11476 };
11477 if (!clipboard || pasteEventIsCrippledSafariHTMLPaste(event)) {
11478 this.getPastedHTMLUsingHiddenElement(html => {
11479 var _this$delegate10, _this$responder16, _this$delegate11;
11480 paste.type = "text/html";
11481 paste.html = html;
11482 (_this$delegate10 = this.delegate) === null || _this$delegate10 === void 0 || _this$delegate10.inputControllerWillPaste(paste);
11483 (_this$responder16 = this.responder) === null || _this$responder16 === void 0 || _this$responder16.insertHTML(paste.html);
11484 this.requestRender();
11485 return (_this$delegate11 = this.delegate) === null || _this$delegate11 === void 0 ? void 0 : _this$delegate11.inputControllerDidPaste(paste);
11486 });
11487 return;
11488 }
11489 const href = clipboard.getData("URL");
11490 const html = clipboard.getData("text/html");
11491 const name = clipboard.getData("public.url-name");
11492 if (href) {
11493 var _this$delegate12, _this$responder17, _this$delegate13;
11494 let string;
11495 paste.type = "text/html";
11496 if (name) {
11497 string = squishBreakableWhitespace(name).trim();
11498 } else {
11499 string = href;
11500 }
11501 paste.html = this.createLinkHTML(href, string);
11502 (_this$delegate12 = this.delegate) === null || _this$delegate12 === void 0 || _this$delegate12.inputControllerWillPaste(paste);
11503 this.setInputSummary({
11504 textAdded: string,
11505 didDelete: this.selectionIsExpanded()
11506 });
11507 (_this$responder17 = this.responder) === null || _this$responder17 === void 0 || _this$responder17.insertHTML(paste.html);
11508 this.requestRender();
11509 (_this$delegate13 = this.delegate) === null || _this$delegate13 === void 0 || _this$delegate13.inputControllerDidPaste(paste);
11510 } else if (dataTransferIsPlainText(clipboard)) {
11511 var _this$delegate14, _this$responder18, _this$delegate15;
11512 paste.type = "text/plain";
11513 paste.string = clipboard.getData("text/plain");
11514 (_this$delegate14 = this.delegate) === null || _this$delegate14 === void 0 || _this$delegate14.inputControllerWillPaste(paste);
11515 this.setInputSummary({
11516 textAdded: paste.string,
11517 didDelete: this.selectionIsExpanded()
11518 });
11519 (_this$responder18 = this.responder) === null || _this$responder18 === void 0 || _this$responder18.insertString(paste.string);
11520 this.requestRender();
11521 (_this$delegate15 = this.delegate) === null || _this$delegate15 === void 0 || _this$delegate15.inputControllerDidPaste(paste);
11522 } else if (html) {
11523 var _this$delegate16, _this$responder19, _this$delegate17;
11524 paste.type = "text/html";
11525 paste.html = html;
11526 (_this$delegate16 = this.delegate) === null || _this$delegate16 === void 0 || _this$delegate16.inputControllerWillPaste(paste);
11527 (_this$responder19 = this.responder) === null || _this$responder19 === void 0 || _this$responder19.insertHTML(paste.html);
11528 this.requestRender();
11529 (_this$delegate17 = this.delegate) === null || _this$delegate17 === void 0 || _this$delegate17.inputControllerDidPaste(paste);
11530 } else if (Array.from(clipboard.types).includes("Files")) {
11531 var _clipboard$items, _clipboard$items$getA;
11532 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);
11533 if (file) {
11534 var _this$delegate18, _this$responder20, _this$delegate19;
11535 const extension = extensionForFile(file);
11536 if (!file.name && extension) {
11537 file.name = "pasted-file-".concat(++pastedFileCount, ".").concat(extension);
11538 }
11539 paste.type = "File";
11540 paste.file = file;
11541 (_this$delegate18 = this.delegate) === null || _this$delegate18 === void 0 || _this$delegate18.inputControllerWillAttachFiles();
11542 (_this$responder20 = this.responder) === null || _this$responder20 === void 0 || _this$responder20.insertFile(paste.file);
11543 this.requestRender();
11544 (_this$delegate19 = this.delegate) === null || _this$delegate19 === void 0 || _this$delegate19.inputControllerDidPaste(paste);
11545 }
11546 }
11547 event.preventDefault();
11548 },
11549 compositionstart(event) {
11550 return this.getCompositionInput().start(event.data);
11551 },
11552 compositionupdate(event) {
11553 return this.getCompositionInput().update(event.data);
11554 },
11555 compositionend(event) {
11556 return this.getCompositionInput().end(event.data);
11557 },
11558 beforeinput(event) {
11559 this.inputSummary.didInput = true;
11560 },
11561 input(event) {
11562 this.inputSummary.didInput = true;
11563 return event.stopPropagation();
11564 }
11565 });
11566 _defineProperty(Level0InputController, "keys", {
11567 backspace(event) {
11568 var _this$delegate20;
11569 (_this$delegate20 = this.delegate) === null || _this$delegate20 === void 0 || _this$delegate20.inputControllerWillPerformTyping();
11570 return this.deleteInDirection("backward", event);
11571 },
11572 delete(event) {
11573 var _this$delegate21;
11574 (_this$delegate21 = this.delegate) === null || _this$delegate21 === void 0 || _this$delegate21.inputControllerWillPerformTyping();
11575 return this.deleteInDirection("forward", event);
11576 },
11577 return(event) {
11578 var _this$delegate22, _this$responder21;
11579 this.setInputSummary({
11580 preferDocument: true
11581 });
11582 (_this$delegate22 = this.delegate) === null || _this$delegate22 === void 0 || _this$delegate22.inputControllerWillPerformTyping();
11583 return (_this$responder21 = this.responder) === null || _this$responder21 === void 0 ? void 0 : _this$responder21.insertLineBreak();
11584 },
11585 tab(event) {
11586 var _this$responder22;
11587 if ((_this$responder22 = this.responder) !== null && _this$responder22 !== void 0 && _this$responder22.canIncreaseNestingLevel()) {
11588 var _this$responder23;
11589 (_this$responder23 = this.responder) === null || _this$responder23 === void 0 || _this$responder23.increaseNestingLevel();
11590 this.requestRender();
11591 event.preventDefault();
11592 }
11593 },
11594 left(event) {
11595 if (this.selectionIsInCursorTarget()) {
11596 var _this$responder24;
11597 event.preventDefault();
11598 return (_this$responder24 = this.responder) === null || _this$responder24 === void 0 ? void 0 : _this$responder24.moveCursorInDirection("backward");
11599 }
11600 },
11601 right(event) {
11602 if (this.selectionIsInCursorTarget()) {
11603 var _this$responder25;
11604 event.preventDefault();
11605 return (_this$responder25 = this.responder) === null || _this$responder25 === void 0 ? void 0 : _this$responder25.moveCursorInDirection("forward");
11606 }
11607 },
11608 control: {
11609 d(event) {
11610 var _this$delegate23;
11611 (_this$delegate23 = this.delegate) === null || _this$delegate23 === void 0 || _this$delegate23.inputControllerWillPerformTyping();
11612 return this.deleteInDirection("forward", event);
11613 },
11614 h(event) {
11615 var _this$delegate24;
11616 (_this$delegate24 = this.delegate) === null || _this$delegate24 === void 0 || _this$delegate24.inputControllerWillPerformTyping();
11617 return this.deleteInDirection("backward", event);
11618 },
11619 o(event) {
11620 var _this$delegate25, _this$responder26;
11621 event.preventDefault();
11622 (_this$delegate25 = this.delegate) === null || _this$delegate25 === void 0 || _this$delegate25.inputControllerWillPerformTyping();
11623 (_this$responder26 = this.responder) === null || _this$responder26 === void 0 || _this$responder26.insertString("\n", {
11624 updatePosition: false
11625 });
11626 return this.requestRender();
11627 }
11628 },
11629 shift: {
11630 return(event) {
11631 var _this$delegate26, _this$responder27;
11632 (_this$delegate26 = this.delegate) === null || _this$delegate26 === void 0 || _this$delegate26.inputControllerWillPerformTyping();
11633 (_this$responder27 = this.responder) === null || _this$responder27 === void 0 || _this$responder27.insertString("\n");
11634 this.requestRender();
11635 event.preventDefault();
11636 },
11637 tab(event) {
11638 var _this$responder28;
11639 if ((_this$responder28 = this.responder) !== null && _this$responder28 !== void 0 && _this$responder28.canDecreaseNestingLevel()) {
11640 var _this$responder29;
11641 (_this$responder29 = this.responder) === null || _this$responder29 === void 0 || _this$responder29.decreaseNestingLevel();
11642 this.requestRender();
11643 event.preventDefault();
11644 }
11645 },
11646 left(event) {
11647 if (this.selectionIsInCursorTarget()) {
11648 event.preventDefault();
11649 return this.expandSelectionInDirection("backward");
11650 }
11651 },
11652 right(event) {
11653 if (this.selectionIsInCursorTarget()) {
11654 event.preventDefault();
11655 return this.expandSelectionInDirection("forward");
11656 }
11657 }
11658 },
11659 alt: {
11660 backspace(event) {
11661 var _this$delegate27;
11662 this.setInputSummary({
11663 preferDocument: false
11664 });
11665 return (_this$delegate27 = this.delegate) === null || _this$delegate27 === void 0 ? void 0 : _this$delegate27.inputControllerWillPerformTyping();
11666 }
11667 },
11668 meta: {
11669 backspace(event) {
11670 var _this$delegate28;
11671 this.setInputSummary({
11672 preferDocument: false
11673 });
11674 return (_this$delegate28 = this.delegate) === null || _this$delegate28 === void 0 ? void 0 : _this$delegate28.inputControllerWillPerformTyping();
11675 }
11676 }
11677 });
11678 Level0InputController.proxyMethod("responder?.getSelectedRange");
11679 Level0InputController.proxyMethod("responder?.setSelectedRange");
11680 Level0InputController.proxyMethod("responder?.expandSelectionInDirection");
11681 Level0InputController.proxyMethod("responder?.selectionIsInCursorTarget");
11682 Level0InputController.proxyMethod("responder?.selectionIsExpanded");
11683 const extensionForFile = file => {
11684 var _file$type;
11685 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];
11686 };
11687 const hasStringCodePointAt = !!((_$codePointAt = (_ = " ").codePointAt) !== null && _$codePointAt !== void 0 && _$codePointAt.call(_, 0));
11688 const stringFromKeyEvent = function (event) {
11689 if (event.key && hasStringCodePointAt && event.key.codePointAt(0) === event.keyCode) {
11690 return event.key;
11691 } else {
11692 let code;
11693 if (event.which === null) {
11694 code = event.keyCode;
11695 } else if (event.which !== 0 && event.charCode !== 0) {
11696 code = event.charCode;
11697 }
11698 if (code != null && keyNames[code] !== "escape") {
11699 return UTF16String.fromCodepoints([code]).toString();
11700 }
11701 }
11702 };
11703 const pasteEventIsCrippledSafariHTMLPaste = function (event) {
11704 const paste = event.clipboardData;
11705 if (paste) {
11706 if (paste.types.includes("text/html")) {
11707 // Answer is yes if there's any possibility of Paste and Match Style in Safari,
11708 // which is nearly impossible to detect confidently: https://bugs.webkit.org/show_bug.cgi?id=174165
11709 for (const type of paste.types) {
11710 const hasPasteboardFlavor = /^CorePasteboardFlavorType/.test(type);
11711 const hasReadableDynamicData = /^dyn\./.test(type) && paste.getData(type);
11712 const mightBePasteAndMatchStyle = hasPasteboardFlavor || hasReadableDynamicData;
11713 if (mightBePasteAndMatchStyle) {
11714 return true;
11715 }
11716 }
11717 return false;
11718 } else {
11719 const isExternalHTMLPaste = paste.types.includes("com.apple.webarchive");
11720 const isExternalRichTextPaste = paste.types.includes("com.apple.flat-rtfd");
11721 return isExternalHTMLPaste || isExternalRichTextPaste;
11722 }
11723 }
11724 };
11725 class CompositionInput extends BasicObject {
11726 constructor(inputController) {
11727 super(...arguments);
11728 this.inputController = inputController;
11729 this.responder = this.inputController.responder;
11730 this.delegate = this.inputController.delegate;
11731 this.inputSummary = this.inputController.inputSummary;
11732 this.data = {};
11733 }
11734 start(data) {
11735 this.data.start = data;
11736 if (this.isSignificant()) {
11737 var _this$responder5;
11738 if (this.inputSummary.eventName === "keypress" && this.inputSummary.textAdded) {
11739 var _this$responder4;
11740 (_this$responder4 = this.responder) === null || _this$responder4 === void 0 || _this$responder4.deleteInDirection("left");
11741 }
11742 if (!this.selectionIsExpanded()) {
11743 this.insertPlaceholder();
11744 this.requestRender();
11745 }
11746 this.range = (_this$responder5 = this.responder) === null || _this$responder5 === void 0 ? void 0 : _this$responder5.getSelectedRange();
11747 }
11748 }
11749 update(data) {
11750 this.data.update = data;
11751 if (this.isSignificant()) {
11752 const range = this.selectPlaceholder();
11753 if (range) {
11754 this.forgetPlaceholder();
11755 this.range = range;
11756 }
11757 }
11758 }
11759 end(data) {
11760 this.data.end = data;
11761 if (this.isSignificant()) {
11762 this.forgetPlaceholder();
11763 if (this.canApplyToDocument()) {
11764 var _this$delegate2, _this$responder6, _this$responder7, _this$responder8;
11765 this.setInputSummary({
11766 preferDocument: true,
11767 didInput: false
11768 });
11769 (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || _this$delegate2.inputControllerWillPerformTyping();
11770 (_this$responder6 = this.responder) === null || _this$responder6 === void 0 || _this$responder6.setSelectedRange(this.range);
11771 (_this$responder7 = this.responder) === null || _this$responder7 === void 0 || _this$responder7.insertString(this.data.end);
11772 return (_this$responder8 = this.responder) === null || _this$responder8 === void 0 ? void 0 : _this$responder8.setSelectedRange(this.range[0] + this.data.end.length);
11773 } else if (this.data.start != null || this.data.update != null) {
11774 this.requestReparse();
11775 return this.inputController.reset();
11776 }
11777 } else {
11778 return this.inputController.reset();
11779 }
11780 }
11781 getEndData() {
11782 return this.data.end;
11783 }
11784 isEnded() {
11785 return this.getEndData() != null;
11786 }
11787 isSignificant() {
11788 if (browser.composesExistingText) {
11789 return this.inputSummary.didInput;
11790 } else {
11791 return true;
11792 }
11793 }
11794
11795 // Private
11796
11797 canApplyToDocument() {
11798 var _this$data$start, _this$data$end;
11799 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;
11800 }
11801 }
11802 CompositionInput.proxyMethod("inputController.setInputSummary");
11803 CompositionInput.proxyMethod("inputController.requestRender");
11804 CompositionInput.proxyMethod("inputController.requestReparse");
11805 CompositionInput.proxyMethod("responder?.selectionIsExpanded");
11806 CompositionInput.proxyMethod("responder?.insertPlaceholder");
11807 CompositionInput.proxyMethod("responder?.selectPlaceholder");
11808 CompositionInput.proxyMethod("responder?.forgetPlaceholder");
11809
11810 class Level2InputController extends InputController {
11811 constructor() {
11812 super(...arguments);
11813 this.render = this.render.bind(this);
11814 }
11815 elementDidMutate() {
11816 if (this.scheduledRender) {
11817 if (this.composing) {
11818 var _this$delegate, _this$delegate$inputC;
11819 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);
11820 }
11821 } else {
11822 return this.reparse();
11823 }
11824 }
11825 scheduleRender() {
11826 return this.scheduledRender ? this.scheduledRender : this.scheduledRender = requestAnimationFrame(this.render);
11827 }
11828 render() {
11829 var _this$afterRender;
11830 cancelAnimationFrame(this.scheduledRender);
11831 this.scheduledRender = null;
11832 if (!this.composing) {
11833 var _this$delegate2;
11834 (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || _this$delegate2.render();
11835 }
11836 (_this$afterRender = this.afterRender) === null || _this$afterRender === void 0 || _this$afterRender.call(this);
11837 this.afterRender = null;
11838 }
11839 reparse() {
11840 var _this$delegate3;
11841 return (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 ? void 0 : _this$delegate3.reparse();
11842 }
11843
11844 // Responder helpers
11845
11846 insertString() {
11847 var _this$delegate4;
11848 let string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
11849 let options = arguments.length > 1 ? arguments[1] : undefined;
11850 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillPerformTyping();
11851 return this.withTargetDOMRange(function () {
11852 var _this$responder;
11853 return (_this$responder = this.responder) === null || _this$responder === void 0 ? void 0 : _this$responder.insertString(string, options);
11854 });
11855 }
11856 toggleAttributeIfSupported(attributeName) {
11857 if (getAllAttributeNames().includes(attributeName)) {
11858 var _this$delegate5;
11859 (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.inputControllerWillPerformFormatting(attributeName);
11860 return this.withTargetDOMRange(function () {
11861 var _this$responder2;
11862 return (_this$responder2 = this.responder) === null || _this$responder2 === void 0 ? void 0 : _this$responder2.toggleCurrentAttribute(attributeName);
11863 });
11864 }
11865 }
11866 activateAttributeIfSupported(attributeName, value) {
11867 if (getAllAttributeNames().includes(attributeName)) {
11868 var _this$delegate6;
11869 (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 || _this$delegate6.inputControllerWillPerformFormatting(attributeName);
11870 return this.withTargetDOMRange(function () {
11871 var _this$responder3;
11872 return (_this$responder3 = this.responder) === null || _this$responder3 === void 0 ? void 0 : _this$responder3.setCurrentAttribute(attributeName, value);
11873 });
11874 }
11875 }
11876 deleteInDirection(direction) {
11877 let {
11878 recordUndoEntry
11879 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
11880 recordUndoEntry: true
11881 };
11882 if (recordUndoEntry) {
11883 var _this$delegate7;
11884 (_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || _this$delegate7.inputControllerWillPerformTyping();
11885 }
11886 const perform = () => {
11887 var _this$responder4;
11888 return (_this$responder4 = this.responder) === null || _this$responder4 === void 0 ? void 0 : _this$responder4.deleteInDirection(direction);
11889 };
11890 const domRange = this.getTargetDOMRange({
11891 minLength: this.composing ? 1 : 2
11892 });
11893 if (domRange) {
11894 return this.withTargetDOMRange(domRange, perform);
11895 } else {
11896 return perform();
11897 }
11898 }
11899
11900 // Selection helpers
11901
11902 withTargetDOMRange(domRange, fn) {
11903 if (typeof domRange === "function") {
11904 fn = domRange;
11905 domRange = this.getTargetDOMRange();
11906 }
11907 if (domRange) {
11908 var _this$responder5;
11909 return (_this$responder5 = this.responder) === null || _this$responder5 === void 0 ? void 0 : _this$responder5.withTargetDOMRange(domRange, fn.bind(this));
11910 } else {
11911 selectionChangeObserver.reset();
11912 return fn.call(this);
11913 }
11914 }
11915 getTargetDOMRange() {
11916 var _this$event$getTarget, _this$event;
11917 let {
11918 minLength
11919 } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
11920 minLength: 0
11921 };
11922 const targetRanges = (_this$event$getTarget = (_this$event = this.event).getTargetRanges) === null || _this$event$getTarget === void 0 ? void 0 : _this$event$getTarget.call(_this$event);
11923 if (targetRanges) {
11924 if (targetRanges.length) {
11925 const domRange = staticRangeToRange(targetRanges[0]);
11926 if (minLength === 0 || domRange.toString().length >= minLength) {
11927 return domRange;
11928 }
11929 }
11930 }
11931 }
11932 withEvent(event, fn) {
11933 let result;
11934 this.event = event;
11935 try {
11936 result = fn.call(this);
11937 } finally {
11938 this.event = null;
11939 }
11940 return result;
11941 }
11942 }
11943 _defineProperty(Level2InputController, "events", {
11944 keydown(event) {
11945 if (keyEventIsKeyboardCommand(event)) {
11946 var _this$delegate8;
11947 const command = keyboardCommandFromKeyEvent(event);
11948 if ((_this$delegate8 = this.delegate) !== null && _this$delegate8 !== void 0 && _this$delegate8.inputControllerDidReceiveKeyboardCommand(command)) {
11949 event.preventDefault();
11950 }
11951 } else {
11952 let name = event.key;
11953 if (event.altKey) {
11954 name += "+Alt";
11955 }
11956 if (event.shiftKey) {
11957 name += "+Shift";
11958 }
11959 const handler = this.constructor.keys[name];
11960 if (handler) {
11961 return this.withEvent(event, handler);
11962 }
11963 }
11964 },
11965 // Handle paste event to work around beforeinput.insertFromPaste browser bugs.
11966 // Safe to remove each condition once fixed upstream.
11967 paste(event) {
11968 var _event$clipboardData;
11969 // https://bugs.webkit.org/show_bug.cgi?id=194921
11970 let paste;
11971 const href = (_event$clipboardData = event.clipboardData) === null || _event$clipboardData === void 0 ? void 0 : _event$clipboardData.getData("URL");
11972 if (pasteEventHasFilesOnly(event)) {
11973 event.preventDefault();
11974 return this.attachFiles(event.clipboardData.files);
11975
11976 // https://bugs.chromium.org/p/chromium/issues/detail?id=934448
11977 } else if (pasteEventHasPlainTextOnly(event)) {
11978 var _this$delegate9, _this$responder6, _this$delegate10;
11979 event.preventDefault();
11980 paste = {
11981 type: "text/plain",
11982 string: event.clipboardData.getData("text/plain")
11983 };
11984 (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 || _this$delegate9.inputControllerWillPaste(paste);
11985 (_this$responder6 = this.responder) === null || _this$responder6 === void 0 || _this$responder6.insertString(paste.string);
11986 this.render();
11987 return (_this$delegate10 = this.delegate) === null || _this$delegate10 === void 0 ? void 0 : _this$delegate10.inputControllerDidPaste(paste);
11988
11989 // https://bugs.webkit.org/show_bug.cgi?id=196702
11990 } else if (href) {
11991 var _this$delegate11, _this$responder7, _this$delegate12;
11992 event.preventDefault();
11993 paste = {
11994 type: "text/html",
11995 html: this.createLinkHTML(href)
11996 };
11997 (_this$delegate11 = this.delegate) === null || _this$delegate11 === void 0 || _this$delegate11.inputControllerWillPaste(paste);
11998 (_this$responder7 = this.responder) === null || _this$responder7 === void 0 || _this$responder7.insertHTML(paste.html);
11999 this.render();
12000 return (_this$delegate12 = this.delegate) === null || _this$delegate12 === void 0 ? void 0 : _this$delegate12.inputControllerDidPaste(paste);
12001 }
12002 },
12003 beforeinput(event) {
12004 const handler = this.constructor.inputTypes[event.inputType];
12005 const immmediateRender = shouldRenderInmmediatelyToDealWithIOSDictation(event);
12006 if (handler) {
12007 this.withEvent(event, handler);
12008 if (!immmediateRender) {
12009 this.scheduleRender();
12010 }
12011 }
12012 if (immmediateRender) {
12013 this.render();
12014 }
12015 },
12016 input(event) {
12017 selectionChangeObserver.reset();
12018 },
12019 dragstart(event) {
12020 var _this$responder8;
12021 if ((_this$responder8 = this.responder) !== null && _this$responder8 !== void 0 && _this$responder8.selectionContainsAttachments()) {
12022 var _this$responder9;
12023 event.dataTransfer.setData("application/x-trix-dragging", true);
12024 this.dragging = {
12025 range: (_this$responder9 = this.responder) === null || _this$responder9 === void 0 ? void 0 : _this$responder9.getSelectedRange(),
12026 point: pointFromEvent(event)
12027 };
12028 }
12029 },
12030 dragenter(event) {
12031 if (dragEventHasFiles(event)) {
12032 event.preventDefault();
12033 }
12034 },
12035 dragover(event) {
12036 if (this.dragging) {
12037 event.preventDefault();
12038 const point = pointFromEvent(event);
12039 if (!objectsAreEqual(point, this.dragging.point)) {
12040 var _this$responder10;
12041 this.dragging.point = point;
12042 return (_this$responder10 = this.responder) === null || _this$responder10 === void 0 ? void 0 : _this$responder10.setLocationRangeFromPointRange(point);
12043 }
12044 } else if (dragEventHasFiles(event)) {
12045 event.preventDefault();
12046 }
12047 },
12048 drop(event) {
12049 if (this.dragging) {
12050 var _this$delegate13, _this$responder11;
12051 event.preventDefault();
12052 (_this$delegate13 = this.delegate) === null || _this$delegate13 === void 0 || _this$delegate13.inputControllerWillMoveText();
12053 (_this$responder11 = this.responder) === null || _this$responder11 === void 0 || _this$responder11.moveTextFromRange(this.dragging.range);
12054 this.dragging = null;
12055 return this.scheduleRender();
12056 } else if (dragEventHasFiles(event)) {
12057 var _this$responder12;
12058 event.preventDefault();
12059 const point = pointFromEvent(event);
12060 (_this$responder12 = this.responder) === null || _this$responder12 === void 0 || _this$responder12.setLocationRangeFromPointRange(point);
12061 return this.attachFiles(event.dataTransfer.files);
12062 }
12063 },
12064 dragend() {
12065 if (this.dragging) {
12066 var _this$responder13;
12067 (_this$responder13 = this.responder) === null || _this$responder13 === void 0 || _this$responder13.setSelectedRange(this.dragging.range);
12068 this.dragging = null;
12069 }
12070 },
12071 compositionend(event) {
12072 if (this.composing) {
12073 this.composing = false;
12074 if (!browser$1.recentAndroid) this.scheduleRender();
12075 }
12076 }
12077 });
12078 _defineProperty(Level2InputController, "keys", {
12079 ArrowLeft() {
12080 var _this$responder14;
12081 if ((_this$responder14 = this.responder) !== null && _this$responder14 !== void 0 && _this$responder14.shouldManageMovingCursorInDirection("backward")) {
12082 var _this$responder15;
12083 this.event.preventDefault();
12084 return (_this$responder15 = this.responder) === null || _this$responder15 === void 0 ? void 0 : _this$responder15.moveCursorInDirection("backward");
12085 }
12086 },
12087 ArrowRight() {
12088 var _this$responder16;
12089 if ((_this$responder16 = this.responder) !== null && _this$responder16 !== void 0 && _this$responder16.shouldManageMovingCursorInDirection("forward")) {
12090 var _this$responder17;
12091 this.event.preventDefault();
12092 return (_this$responder17 = this.responder) === null || _this$responder17 === void 0 ? void 0 : _this$responder17.moveCursorInDirection("forward");
12093 }
12094 },
12095 Backspace() {
12096 var _this$responder18;
12097 if ((_this$responder18 = this.responder) !== null && _this$responder18 !== void 0 && _this$responder18.shouldManageDeletingInDirection("backward")) {
12098 var _this$delegate14, _this$responder19;
12099 this.event.preventDefault();
12100 (_this$delegate14 = this.delegate) === null || _this$delegate14 === void 0 || _this$delegate14.inputControllerWillPerformTyping();
12101 (_this$responder19 = this.responder) === null || _this$responder19 === void 0 || _this$responder19.deleteInDirection("backward");
12102 return this.render();
12103 }
12104 },
12105 Tab() {
12106 var _this$responder20;
12107 if ((_this$responder20 = this.responder) !== null && _this$responder20 !== void 0 && _this$responder20.canIncreaseNestingLevel()) {
12108 var _this$responder21;
12109 this.event.preventDefault();
12110 (_this$responder21 = this.responder) === null || _this$responder21 === void 0 || _this$responder21.increaseNestingLevel();
12111 return this.render();
12112 }
12113 },
12114 "Tab+Shift"() {
12115 var _this$responder22;
12116 if ((_this$responder22 = this.responder) !== null && _this$responder22 !== void 0 && _this$responder22.canDecreaseNestingLevel()) {
12117 var _this$responder23;
12118 this.event.preventDefault();
12119 (_this$responder23 = this.responder) === null || _this$responder23 === void 0 || _this$responder23.decreaseNestingLevel();
12120 return this.render();
12121 }
12122 }
12123 });
12124 _defineProperty(Level2InputController, "inputTypes", {
12125 deleteByComposition() {
12126 return this.deleteInDirection("backward", {
12127 recordUndoEntry: false
12128 });
12129 },
12130 deleteByCut() {
12131 return this.deleteInDirection("backward");
12132 },
12133 deleteByDrag() {
12134 this.event.preventDefault();
12135 return this.withTargetDOMRange(function () {
12136 var _this$responder24;
12137 this.deleteByDragRange = (_this$responder24 = this.responder) === null || _this$responder24 === void 0 ? void 0 : _this$responder24.getSelectedRange();
12138 });
12139 },
12140 deleteCompositionText() {
12141 return this.deleteInDirection("backward", {
12142 recordUndoEntry: false
12143 });
12144 },
12145 deleteContent() {
12146 return this.deleteInDirection("backward");
12147 },
12148 deleteContentBackward() {
12149 return this.deleteInDirection("backward");
12150 },
12151 deleteContentForward() {
12152 return this.deleteInDirection("forward");
12153 },
12154 deleteEntireSoftLine() {
12155 return this.deleteInDirection("forward");
12156 },
12157 deleteHardLineBackward() {
12158 return this.deleteInDirection("backward");
12159 },
12160 deleteHardLineForward() {
12161 return this.deleteInDirection("forward");
12162 },
12163 deleteSoftLineBackward() {
12164 return this.deleteInDirection("backward");
12165 },
12166 deleteSoftLineForward() {
12167 return this.deleteInDirection("forward");
12168 },
12169 deleteWordBackward() {
12170 return this.deleteInDirection("backward");
12171 },
12172 deleteWordForward() {
12173 return this.deleteInDirection("forward");
12174 },
12175 formatBackColor() {
12176 return this.activateAttributeIfSupported("backgroundColor", this.event.data);
12177 },
12178 formatBold() {
12179 return this.toggleAttributeIfSupported("bold");
12180 },
12181 formatFontColor() {
12182 return this.activateAttributeIfSupported("color", this.event.data);
12183 },
12184 formatFontName() {
12185 return this.activateAttributeIfSupported("font", this.event.data);
12186 },
12187 formatIndent() {
12188 var _this$responder25;
12189 if ((_this$responder25 = this.responder) !== null && _this$responder25 !== void 0 && _this$responder25.canIncreaseNestingLevel()) {
12190 return this.withTargetDOMRange(function () {
12191 var _this$responder26;
12192 return (_this$responder26 = this.responder) === null || _this$responder26 === void 0 ? void 0 : _this$responder26.increaseNestingLevel();
12193 });
12194 }
12195 },
12196 formatItalic() {
12197 return this.toggleAttributeIfSupported("italic");
12198 },
12199 formatJustifyCenter() {
12200 return this.toggleAttributeIfSupported("justifyCenter");
12201 },
12202 formatJustifyFull() {
12203 return this.toggleAttributeIfSupported("justifyFull");
12204 },
12205 formatJustifyLeft() {
12206 return this.toggleAttributeIfSupported("justifyLeft");
12207 },
12208 formatJustifyRight() {
12209 return this.toggleAttributeIfSupported("justifyRight");
12210 },
12211 formatOutdent() {
12212 var _this$responder27;
12213 if ((_this$responder27 = this.responder) !== null && _this$responder27 !== void 0 && _this$responder27.canDecreaseNestingLevel()) {
12214 return this.withTargetDOMRange(function () {
12215 var _this$responder28;
12216 return (_this$responder28 = this.responder) === null || _this$responder28 === void 0 ? void 0 : _this$responder28.decreaseNestingLevel();
12217 });
12218 }
12219 },
12220 formatRemove() {
12221 this.withTargetDOMRange(function () {
12222 for (const attributeName in (_this$responder29 = this.responder) === null || _this$responder29 === void 0 ? void 0 : _this$responder29.getCurrentAttributes()) {
12223 var _this$responder29, _this$responder30;
12224 (_this$responder30 = this.responder) === null || _this$responder30 === void 0 || _this$responder30.removeCurrentAttribute(attributeName);
12225 }
12226 });
12227 },
12228 formatSetBlockTextDirection() {
12229 return this.activateAttributeIfSupported("blockDir", this.event.data);
12230 },
12231 formatSetInlineTextDirection() {
12232 return this.activateAttributeIfSupported("textDir", this.event.data);
12233 },
12234 formatStrikeThrough() {
12235 return this.toggleAttributeIfSupported("strike");
12236 },
12237 formatSubscript() {
12238 return this.toggleAttributeIfSupported("sub");
12239 },
12240 formatSuperscript() {
12241 return this.toggleAttributeIfSupported("sup");
12242 },
12243 formatUnderline() {
12244 return this.toggleAttributeIfSupported("underline");
12245 },
12246 historyRedo() {
12247 var _this$delegate15;
12248 return (_this$delegate15 = this.delegate) === null || _this$delegate15 === void 0 ? void 0 : _this$delegate15.inputControllerWillPerformRedo();
12249 },
12250 historyUndo() {
12251 var _this$delegate16;
12252 return (_this$delegate16 = this.delegate) === null || _this$delegate16 === void 0 ? void 0 : _this$delegate16.inputControllerWillPerformUndo();
12253 },
12254 insertCompositionText() {
12255 this.composing = true;
12256 return this.insertString(this.event.data);
12257 },
12258 insertFromComposition() {
12259 this.composing = false;
12260 return this.insertString(this.event.data);
12261 },
12262 insertFromDrop() {
12263 const range = this.deleteByDragRange;
12264 if (range) {
12265 var _this$delegate17;
12266 this.deleteByDragRange = null;
12267 (_this$delegate17 = this.delegate) === null || _this$delegate17 === void 0 || _this$delegate17.inputControllerWillMoveText();
12268 return this.withTargetDOMRange(function () {
12269 var _this$responder31;
12270 return (_this$responder31 = this.responder) === null || _this$responder31 === void 0 ? void 0 : _this$responder31.moveTextFromRange(range);
12271 });
12272 }
12273 },
12274 insertFromPaste() {
12275 const {
12276 dataTransfer
12277 } = this.event;
12278 const paste = {
12279 dataTransfer
12280 };
12281 const href = dataTransfer.getData("URL");
12282 const html = dataTransfer.getData("text/html");
12283 if (href) {
12284 var _this$delegate18;
12285 let string;
12286 this.event.preventDefault();
12287 paste.type = "text/html";
12288 const name = dataTransfer.getData("public.url-name");
12289 if (name) {
12290 string = squishBreakableWhitespace(name).trim();
12291 } else {
12292 string = href;
12293 }
12294 paste.html = this.createLinkHTML(href, string);
12295 (_this$delegate18 = this.delegate) === null || _this$delegate18 === void 0 || _this$delegate18.inputControllerWillPaste(paste);
12296 this.withTargetDOMRange(function () {
12297 var _this$responder32;
12298 return (_this$responder32 = this.responder) === null || _this$responder32 === void 0 ? void 0 : _this$responder32.insertHTML(paste.html);
12299 });
12300 this.afterRender = () => {
12301 var _this$delegate19;
12302 return (_this$delegate19 = this.delegate) === null || _this$delegate19 === void 0 ? void 0 : _this$delegate19.inputControllerDidPaste(paste);
12303 };
12304 } else if (dataTransferIsPlainText(dataTransfer)) {
12305 var _this$delegate20;
12306 paste.type = "text/plain";
12307 paste.string = dataTransfer.getData("text/plain");
12308 (_this$delegate20 = this.delegate) === null || _this$delegate20 === void 0 || _this$delegate20.inputControllerWillPaste(paste);
12309 this.withTargetDOMRange(function () {
12310 var _this$responder33;
12311 return (_this$responder33 = this.responder) === null || _this$responder33 === void 0 ? void 0 : _this$responder33.insertString(paste.string);
12312 });
12313 this.afterRender = () => {
12314 var _this$delegate21;
12315 return (_this$delegate21 = this.delegate) === null || _this$delegate21 === void 0 ? void 0 : _this$delegate21.inputControllerDidPaste(paste);
12316 };
12317 } else if (processableFilePaste(this.event)) {
12318 var _this$delegate22;
12319 paste.type = "File";
12320 paste.file = dataTransfer.files[0];
12321 (_this$delegate22 = this.delegate) === null || _this$delegate22 === void 0 || _this$delegate22.inputControllerWillPaste(paste);
12322 this.withTargetDOMRange(function () {
12323 var _this$responder34;
12324 return (_this$responder34 = this.responder) === null || _this$responder34 === void 0 ? void 0 : _this$responder34.insertFile(paste.file);
12325 });
12326 this.afterRender = () => {
12327 var _this$delegate23;
12328 return (_this$delegate23 = this.delegate) === null || _this$delegate23 === void 0 ? void 0 : _this$delegate23.inputControllerDidPaste(paste);
12329 };
12330 } else if (html) {
12331 var _this$delegate24;
12332 this.event.preventDefault();
12333 paste.type = "text/html";
12334 paste.html = html;
12335 (_this$delegate24 = this.delegate) === null || _this$delegate24 === void 0 || _this$delegate24.inputControllerWillPaste(paste);
12336 this.withTargetDOMRange(function () {
12337 var _this$responder35;
12338 return (_this$responder35 = this.responder) === null || _this$responder35 === void 0 ? void 0 : _this$responder35.insertHTML(paste.html);
12339 });
12340 this.afterRender = () => {
12341 var _this$delegate25;
12342 return (_this$delegate25 = this.delegate) === null || _this$delegate25 === void 0 ? void 0 : _this$delegate25.inputControllerDidPaste(paste);
12343 };
12344 }
12345 },
12346 insertFromYank() {
12347 return this.insertString(this.event.data);
12348 },
12349 insertLineBreak() {
12350 return this.insertString("\n");
12351 },
12352 insertLink() {
12353 return this.activateAttributeIfSupported("href", this.event.data);
12354 },
12355 insertOrderedList() {
12356 return this.toggleAttributeIfSupported("number");
12357 },
12358 insertParagraph() {
12359 var _this$delegate26;
12360 (_this$delegate26 = this.delegate) === null || _this$delegate26 === void 0 || _this$delegate26.inputControllerWillPerformTyping();
12361 return this.withTargetDOMRange(function () {
12362 var _this$responder36;
12363 return (_this$responder36 = this.responder) === null || _this$responder36 === void 0 ? void 0 : _this$responder36.insertLineBreak();
12364 });
12365 },
12366 insertReplacementText() {
12367 const replacement = this.event.dataTransfer.getData("text/plain");
12368 const domRange = this.event.getTargetRanges()[0];
12369 this.withTargetDOMRange(domRange, () => {
12370 this.insertString(replacement, {
12371 updatePosition: false
12372 });
12373 });
12374 },
12375 insertText() {
12376 var _this$event$dataTrans;
12377 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")));
12378 },
12379 insertTranspose() {
12380 return this.insertString(this.event.data);
12381 },
12382 insertUnorderedList() {
12383 return this.toggleAttributeIfSupported("bullet");
12384 }
12385 });
12386 const staticRangeToRange = function (staticRange) {
12387 const range = document.createRange();
12388 range.setStart(staticRange.startContainer, staticRange.startOffset);
12389 range.setEnd(staticRange.endContainer, staticRange.endOffset);
12390 return range;
12391 };
12392
12393 // Event helpers
12394
12395 const dragEventHasFiles = event => {
12396 var _event$dataTransfer;
12397 return Array.from(((_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.types) || []).includes("Files");
12398 };
12399 const processableFilePaste = event => {
12400 var _event$dataTransfer$f;
12401 // Paste events that only have files are handled by the paste event handler,
12402 // to work around Safari not supporting beforeinput.insertFromPaste for files.
12403
12404 // MS Office text pastes include a file with a screenshot of the text, but we should
12405 // handle them as text pastes.
12406 return ((_event$dataTransfer$f = event.dataTransfer.files) === null || _event$dataTransfer$f === void 0 ? void 0 : _event$dataTransfer$f[0]) && !pasteEventHasFilesOnly(event) && !dataTransferIsMsOfficePaste(event);
12407 };
12408 const pasteEventHasFilesOnly = function (event) {
12409 const clipboard = event.clipboardData;
12410 if (clipboard) {
12411 const fileTypes = Array.from(clipboard.types).filter(type => type.match(/file/i)); // "Files", "application/x-moz-file"
12412 return fileTypes.length === clipboard.types.length && clipboard.files.length >= 1;
12413 }
12414 };
12415 const pasteEventHasPlainTextOnly = function (event) {
12416 const clipboard = event.clipboardData;
12417 if (clipboard) {
12418 return clipboard.types.includes("text/plain") && clipboard.types.length === 1;
12419 }
12420 };
12421 const keyboardCommandFromKeyEvent = function (event) {
12422 const command = [];
12423 if (event.altKey) {
12424 command.push("alt");
12425 }
12426 if (event.shiftKey) {
12427 command.push("shift");
12428 }
12429 command.push(event.key);
12430 return command;
12431 };
12432 const pointFromEvent = event => ({
12433 x: event.clientX,
12434 y: event.clientY
12435 });
12436
12437 const attributeButtonSelector = "[data-trix-attribute]";
12438 const actionButtonSelector = "[data-trix-action]";
12439 const toolbarButtonSelector = "".concat(attributeButtonSelector, ", ").concat(actionButtonSelector);
12440 const dialogSelector = "[data-trix-dialog]";
12441 const activeDialogSelector = "".concat(dialogSelector, "[data-trix-active]");
12442 const dialogButtonSelector = "".concat(dialogSelector, " [data-trix-method]");
12443 const dialogInputSelector = "".concat(dialogSelector, " [data-trix-input]");
12444 const getInputForDialog = (element, attributeName) => {
12445 if (!attributeName) {
12446 attributeName = getAttributeName(element);
12447 }
12448 return element.querySelector("[data-trix-input][name='".concat(attributeName, "']"));
12449 };
12450 const getActionName = element => element.getAttribute("data-trix-action");
12451 const getAttributeName = element => {
12452 return element.getAttribute("data-trix-attribute") || element.getAttribute("data-trix-dialog-attribute");
12453 };
12454 const getDialogName = element => element.getAttribute("data-trix-dialog");
12455 class ToolbarController extends BasicObject {
12456 constructor(element) {
12457 super(element);
12458 this.didClickActionButton = this.didClickActionButton.bind(this);
12459 this.didClickAttributeButton = this.didClickAttributeButton.bind(this);
12460 this.didClickDialogButton = this.didClickDialogButton.bind(this);
12461 this.didKeyDownDialogInput = this.didKeyDownDialogInput.bind(this);
12462 this.element = element;
12463 this.attributes = {};
12464 this.actions = {};
12465 this.resetDialogInputs();
12466 handleEvent("mousedown", {
12467 onElement: this.element,
12468 matchingSelector: actionButtonSelector,
12469 withCallback: this.didClickActionButton
12470 });
12471 handleEvent("mousedown", {
12472 onElement: this.element,
12473 matchingSelector: attributeButtonSelector,
12474 withCallback: this.didClickAttributeButton
12475 });
12476 handleEvent("click", {
12477 onElement: this.element,
12478 matchingSelector: toolbarButtonSelector,
12479 preventDefault: true
12480 });
12481 handleEvent("click", {
12482 onElement: this.element,
12483 matchingSelector: dialogButtonSelector,
12484 withCallback: this.didClickDialogButton
12485 });
12486 handleEvent("keydown", {
12487 onElement: this.element,
12488 matchingSelector: dialogInputSelector,
12489 withCallback: this.didKeyDownDialogInput
12490 });
12491 }
12492
12493 // Event handlers
12494
12495 didClickActionButton(event, element) {
12496 var _this$delegate;
12497 (_this$delegate = this.delegate) === null || _this$delegate === void 0 || _this$delegate.toolbarDidClickButton();
12498 event.preventDefault();
12499 const actionName = getActionName(element);
12500 if (this.getDialog(actionName)) {
12501 return this.toggleDialog(actionName);
12502 } else {
12503 var _this$delegate2;
12504 return (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 ? void 0 : _this$delegate2.toolbarDidInvokeAction(actionName, element);
12505 }
12506 }
12507 didClickAttributeButton(event, element) {
12508 var _this$delegate3;
12509 (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || _this$delegate3.toolbarDidClickButton();
12510 event.preventDefault();
12511 const attributeName = getAttributeName(element);
12512 if (this.getDialog(attributeName)) {
12513 this.toggleDialog(attributeName);
12514 } else {
12515 var _this$delegate4;
12516 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.toolbarDidToggleAttribute(attributeName);
12517 }
12518 return this.refreshAttributeButtons();
12519 }
12520 didClickDialogButton(event, element) {
12521 const dialogElement = findClosestElementFromNode(element, {
12522 matchingSelector: dialogSelector
12523 });
12524 const method = element.getAttribute("data-trix-method");
12525 return this[method].call(this, dialogElement);
12526 }
12527 didKeyDownDialogInput(event, element) {
12528 if (event.keyCode === 13) {
12529 // Enter key
12530 event.preventDefault();
12531 const attribute = element.getAttribute("name");
12532 const dialog = this.getDialog(attribute);
12533 this.setAttribute(dialog);
12534 }
12535 if (event.keyCode === 27) {
12536 // Escape key
12537 event.preventDefault();
12538 return this.hideDialog();
12539 }
12540 }
12541
12542 // Action buttons
12543
12544 updateActions(actions) {
12545 this.actions = actions;
12546 return this.refreshActionButtons();
12547 }
12548 refreshActionButtons() {
12549 return this.eachActionButton((element, actionName) => {
12550 element.disabled = this.actions[actionName] === false;
12551 });
12552 }
12553 eachActionButton(callback) {
12554 return Array.from(this.element.querySelectorAll(actionButtonSelector)).map(element => callback(element, getActionName(element)));
12555 }
12556
12557 // Attribute buttons
12558
12559 updateAttributes(attributes) {
12560 this.attributes = attributes;
12561 return this.refreshAttributeButtons();
12562 }
12563 refreshAttributeButtons() {
12564 return this.eachAttributeButton((element, attributeName) => {
12565 element.disabled = this.attributes[attributeName] === false;
12566 if (this.attributes[attributeName] || this.dialogIsVisible(attributeName)) {
12567 element.setAttribute("data-trix-active", "");
12568 return element.classList.add("trix-active");
12569 } else {
12570 element.removeAttribute("data-trix-active");
12571 return element.classList.remove("trix-active");
12572 }
12573 });
12574 }
12575 eachAttributeButton(callback) {
12576 return Array.from(this.element.querySelectorAll(attributeButtonSelector)).map(element => callback(element, getAttributeName(element)));
12577 }
12578 applyKeyboardCommand(keys) {
12579 const keyString = JSON.stringify(keys.sort());
12580 for (const button of Array.from(this.element.querySelectorAll("[data-trix-key]"))) {
12581 const buttonKeys = button.getAttribute("data-trix-key").split("+");
12582 const buttonKeyString = JSON.stringify(buttonKeys.sort());
12583 if (buttonKeyString === keyString) {
12584 triggerEvent("mousedown", {
12585 onElement: button
12586 });
12587 return true;
12588 }
12589 }
12590 return false;
12591 }
12592
12593 // Dialogs
12594
12595 dialogIsVisible(dialogName) {
12596 const element = this.getDialog(dialogName);
12597 if (element) {
12598 return element.hasAttribute("data-trix-active");
12599 }
12600 }
12601 toggleDialog(dialogName) {
12602 if (this.dialogIsVisible(dialogName)) {
12603 return this.hideDialog();
12604 } else {
12605 return this.showDialog(dialogName);
12606 }
12607 }
12608 showDialog(dialogName) {
12609 var _this$delegate5, _this$delegate6;
12610 this.hideDialog();
12611 (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.toolbarWillShowDialog();
12612 const element = this.getDialog(dialogName);
12613 element.setAttribute("data-trix-active", "");
12614 element.classList.add("trix-active");
12615 Array.from(element.querySelectorAll("input[disabled]")).forEach(disabledInput => {
12616 disabledInput.removeAttribute("disabled");
12617 });
12618 const attributeName = getAttributeName(element);
12619 if (attributeName) {
12620 const input = getInputForDialog(element, dialogName);
12621 if (input) {
12622 input.value = this.attributes[attributeName] || "";
12623 input.select();
12624 }
12625 }
12626 return (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 ? void 0 : _this$delegate6.toolbarDidShowDialog(dialogName);
12627 }
12628 setAttribute(dialogElement) {
12629 const attributeName = getAttributeName(dialogElement);
12630 const input = getInputForDialog(dialogElement, attributeName);
12631 if (input.willValidate && !input.checkValidity()) {
12632 input.setAttribute("data-trix-validate", "");
12633 input.classList.add("trix-validate");
12634 return input.focus();
12635 } else {
12636 var _this$delegate7;
12637 (_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || _this$delegate7.toolbarDidUpdateAttribute(attributeName, input.value);
12638 return this.hideDialog();
12639 }
12640 }
12641 removeAttribute(dialogElement) {
12642 var _this$delegate8;
12643 const attributeName = getAttributeName(dialogElement);
12644 (_this$delegate8 = this.delegate) === null || _this$delegate8 === void 0 || _this$delegate8.toolbarDidRemoveAttribute(attributeName);
12645 return this.hideDialog();
12646 }
12647 hideDialog() {
12648 const element = this.element.querySelector(activeDialogSelector);
12649 if (element) {
12650 var _this$delegate9;
12651 element.removeAttribute("data-trix-active");
12652 element.classList.remove("trix-active");
12653 this.resetDialogInputs();
12654 return (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 ? void 0 : _this$delegate9.toolbarDidHideDialog(getDialogName(element));
12655 }
12656 }
12657 resetDialogInputs() {
12658 Array.from(this.element.querySelectorAll(dialogInputSelector)).forEach(input => {
12659 input.setAttribute("disabled", "disabled");
12660 input.removeAttribute("data-trix-validate");
12661 input.classList.remove("trix-validate");
12662 });
12663 }
12664 getDialog(dialogName) {
12665 return this.element.querySelector("[data-trix-dialog=".concat(dialogName, "]"));
12666 }
12667 }
12668
12669 const snapshotsAreEqual = (a, b) => rangesAreEqual(a.selectedRange, b.selectedRange) && a.document.isEqualTo(b.document);
12670 class EditorController extends Controller {
12671 constructor(_ref) {
12672 let {
12673 editorElement,
12674 document,
12675 html
12676 } = _ref;
12677 super(...arguments);
12678 this.editorElement = editorElement;
12679 this.selectionManager = new SelectionManager(this.editorElement);
12680 this.selectionManager.delegate = this;
12681 this.composition = new Composition();
12682 this.composition.delegate = this;
12683 this.attachmentManager = new AttachmentManager(this.composition.getAttachments());
12684 this.attachmentManager.delegate = this;
12685 this.inputController = input.getLevel() === 2 ? new Level2InputController(this.editorElement) : new Level0InputController(this.editorElement);
12686 this.inputController.delegate = this;
12687 this.inputController.responder = this.composition;
12688 this.compositionController = new CompositionController(this.editorElement, this.composition);
12689 this.compositionController.delegate = this;
12690 this.toolbarController = new ToolbarController(this.editorElement.toolbarElement);
12691 this.toolbarController.delegate = this;
12692 this.editor = new Editor(this.composition, this.selectionManager, this.editorElement);
12693 if (document) {
12694 this.editor.loadDocument(document);
12695 } else {
12696 this.editor.loadHTML(html);
12697 }
12698 }
12699 registerSelectionManager() {
12700 return selectionChangeObserver.registerSelectionManager(this.selectionManager);
12701 }
12702 unregisterSelectionManager() {
12703 return selectionChangeObserver.unregisterSelectionManager(this.selectionManager);
12704 }
12705 render() {
12706 return this.compositionController.render();
12707 }
12708 reparse() {
12709 return this.composition.replaceHTML(this.editorElement.innerHTML);
12710 }
12711
12712 // Composition delegate
12713
12714 compositionDidChangeDocument(document) {
12715 this.notifyEditorElement("document-change");
12716 if (!this.handlingInput) {
12717 return this.render();
12718 }
12719 }
12720 compositionDidChangeCurrentAttributes(currentAttributes) {
12721 this.currentAttributes = currentAttributes;
12722 this.toolbarController.updateAttributes(this.currentAttributes);
12723 this.updateCurrentActions();
12724 return this.notifyEditorElement("attributes-change", {
12725 attributes: this.currentAttributes
12726 });
12727 }
12728 compositionDidPerformInsertionAtRange(range) {
12729 if (this.pasting) {
12730 this.pastedRange = range;
12731 }
12732 }
12733 compositionShouldAcceptFile(file) {
12734 return this.notifyEditorElement("file-accept", {
12735 file
12736 });
12737 }
12738 compositionDidAddAttachment(attachment) {
12739 const managedAttachment = this.attachmentManager.manageAttachment(attachment);
12740 return this.notifyEditorElement("attachment-add", {
12741 attachment: managedAttachment
12742 });
12743 }
12744 compositionDidEditAttachment(attachment) {
12745 this.compositionController.rerenderViewForObject(attachment);
12746 const managedAttachment = this.attachmentManager.manageAttachment(attachment);
12747 this.notifyEditorElement("attachment-edit", {
12748 attachment: managedAttachment
12749 });
12750 return this.notifyEditorElement("change");
12751 }
12752 compositionDidChangeAttachmentPreviewURL(attachment) {
12753 this.compositionController.invalidateViewForObject(attachment);
12754 return this.notifyEditorElement("change");
12755 }
12756 compositionDidRemoveAttachment(attachment) {
12757 const managedAttachment = this.attachmentManager.unmanageAttachment(attachment);
12758 return this.notifyEditorElement("attachment-remove", {
12759 attachment: managedAttachment
12760 });
12761 }
12762 compositionDidStartEditingAttachment(attachment, options) {
12763 this.attachmentLocationRange = this.composition.document.getLocationRangeOfAttachment(attachment);
12764 this.compositionController.installAttachmentEditorForAttachment(attachment, options);
12765 return this.selectionManager.setLocationRange(this.attachmentLocationRange);
12766 }
12767 compositionDidStopEditingAttachment(attachment) {
12768 this.compositionController.uninstallAttachmentEditor();
12769 this.attachmentLocationRange = null;
12770 }
12771 compositionDidRequestChangingSelectionToLocationRange(locationRange) {
12772 if (this.loadingSnapshot && !this.isFocused()) return;
12773 this.requestedLocationRange = locationRange;
12774 this.compositionRevisionWhenLocationRangeRequested = this.composition.revision;
12775 if (!this.handlingInput) {
12776 return this.render();
12777 }
12778 }
12779 compositionWillLoadSnapshot() {
12780 this.loadingSnapshot = true;
12781 }
12782 compositionDidLoadSnapshot() {
12783 this.compositionController.refreshViewCache();
12784 this.render();
12785 this.loadingSnapshot = false;
12786 }
12787 getSelectionManager() {
12788 return this.selectionManager;
12789 }
12790
12791 // Attachment manager delegate
12792
12793 attachmentManagerDidRequestRemovalOfAttachment(attachment) {
12794 return this.removeAttachment(attachment);
12795 }
12796
12797 // Document controller delegate
12798
12799 compositionControllerWillSyncDocumentView() {
12800 this.inputController.editorWillSyncDocumentView();
12801 this.selectionManager.lock();
12802 return this.selectionManager.clearSelection();
12803 }
12804 compositionControllerDidSyncDocumentView() {
12805 this.inputController.editorDidSyncDocumentView();
12806 this.selectionManager.unlock();
12807 this.updateCurrentActions();
12808 return this.notifyEditorElement("sync");
12809 }
12810 compositionControllerDidRender() {
12811 if (this.requestedLocationRange) {
12812 if (this.compositionRevisionWhenLocationRangeRequested === this.composition.revision) {
12813 this.selectionManager.setLocationRange(this.requestedLocationRange);
12814 }
12815 this.requestedLocationRange = null;
12816 this.compositionRevisionWhenLocationRangeRequested = null;
12817 }
12818 if (this.renderedCompositionRevision !== this.composition.revision) {
12819 this.runEditorFilters();
12820 this.composition.updateCurrentAttributes();
12821 this.notifyEditorElement("render");
12822 }
12823 this.renderedCompositionRevision = this.composition.revision;
12824 }
12825 compositionControllerDidFocus() {
12826 if (this.isFocusedInvisibly()) {
12827 this.setLocationRange({
12828 index: 0,
12829 offset: 0
12830 });
12831 }
12832 this.toolbarController.hideDialog();
12833 return this.notifyEditorElement("focus");
12834 }
12835 compositionControllerDidBlur() {
12836 return this.notifyEditorElement("blur");
12837 }
12838 compositionControllerDidSelectAttachment(attachment, options) {
12839 this.toolbarController.hideDialog();
12840 return this.composition.editAttachment(attachment, options);
12841 }
12842 compositionControllerDidRequestDeselectingAttachment(attachment) {
12843 const locationRange = this.attachmentLocationRange || this.composition.document.getLocationRangeOfAttachment(attachment);
12844 return this.selectionManager.setLocationRange(locationRange[1]);
12845 }
12846 compositionControllerWillUpdateAttachment(attachment) {
12847 return this.editor.recordUndoEntry("Edit Attachment", {
12848 context: attachment.id,
12849 consolidatable: true
12850 });
12851 }
12852 compositionControllerDidRequestRemovalOfAttachment(attachment) {
12853 return this.removeAttachment(attachment);
12854 }
12855
12856 // Input controller delegate
12857
12858 inputControllerWillHandleInput() {
12859 this.handlingInput = true;
12860 this.requestedRender = false;
12861 }
12862 inputControllerDidRequestRender() {
12863 this.requestedRender = true;
12864 }
12865 inputControllerDidHandleInput() {
12866 this.handlingInput = false;
12867 if (this.requestedRender) {
12868 this.requestedRender = false;
12869 return this.render();
12870 }
12871 }
12872 inputControllerDidAllowUnhandledInput() {
12873 return this.notifyEditorElement("change");
12874 }
12875 inputControllerDidRequestReparse() {
12876 return this.reparse();
12877 }
12878 inputControllerWillPerformTyping() {
12879 return this.recordTypingUndoEntry();
12880 }
12881 inputControllerWillPerformFormatting(attributeName) {
12882 return this.recordFormattingUndoEntry(attributeName);
12883 }
12884 inputControllerWillCutText() {
12885 return this.editor.recordUndoEntry("Cut");
12886 }
12887 inputControllerWillPaste(paste) {
12888 this.editor.recordUndoEntry("Paste");
12889 this.pasting = true;
12890 return this.notifyEditorElement("before-paste", {
12891 paste
12892 });
12893 }
12894 inputControllerDidPaste(paste) {
12895 paste.range = this.pastedRange;
12896 this.pastedRange = null;
12897 this.pasting = null;
12898 return this.notifyEditorElement("paste", {
12899 paste
12900 });
12901 }
12902 inputControllerWillMoveText() {
12903 return this.editor.recordUndoEntry("Move");
12904 }
12905 inputControllerWillAttachFiles() {
12906 return this.editor.recordUndoEntry("Drop Files");
12907 }
12908 inputControllerWillPerformUndo() {
12909 return this.editor.undo();
12910 }
12911 inputControllerWillPerformRedo() {
12912 return this.editor.redo();
12913 }
12914 inputControllerDidReceiveKeyboardCommand(keys) {
12915 return this.toolbarController.applyKeyboardCommand(keys);
12916 }
12917 inputControllerDidStartDrag() {
12918 this.locationRangeBeforeDrag = this.selectionManager.getLocationRange();
12919 }
12920 inputControllerDidReceiveDragOverPoint(point) {
12921 return this.selectionManager.setLocationRangeFromPointRange(point);
12922 }
12923 inputControllerDidCancelDrag() {
12924 this.selectionManager.setLocationRange(this.locationRangeBeforeDrag);
12925 this.locationRangeBeforeDrag = null;
12926 }
12927
12928 // Selection manager delegate
12929
12930 locationRangeDidChange(locationRange) {
12931 this.composition.updateCurrentAttributes();
12932 this.updateCurrentActions();
12933 if (this.attachmentLocationRange && !rangesAreEqual(this.attachmentLocationRange, locationRange)) {
12934 this.composition.stopEditingAttachment();
12935 }
12936 return this.notifyEditorElement("selection-change");
12937 }
12938
12939 // Toolbar controller delegate
12940
12941 toolbarDidClickButton() {
12942 if (!this.getLocationRange()) {
12943 return this.setLocationRange({
12944 index: 0,
12945 offset: 0
12946 });
12947 }
12948 }
12949 toolbarDidInvokeAction(actionName, invokingElement) {
12950 return this.invokeAction(actionName, invokingElement);
12951 }
12952 toolbarDidToggleAttribute(attributeName) {
12953 this.recordFormattingUndoEntry(attributeName);
12954 this.composition.toggleCurrentAttribute(attributeName);
12955 this.render();
12956 if (!this.selectionFrozen) {
12957 return this.editorElement.focus();
12958 }
12959 }
12960 toolbarDidUpdateAttribute(attributeName, value) {
12961 this.recordFormattingUndoEntry(attributeName);
12962 this.composition.setCurrentAttribute(attributeName, value);
12963 this.render();
12964 if (!this.selectionFrozen) {
12965 return this.editorElement.focus();
12966 }
12967 }
12968 toolbarDidRemoveAttribute(attributeName) {
12969 this.recordFormattingUndoEntry(attributeName);
12970 this.composition.removeCurrentAttribute(attributeName);
12971 this.render();
12972 if (!this.selectionFrozen) {
12973 return this.editorElement.focus();
12974 }
12975 }
12976 toolbarWillShowDialog(dialogElement) {
12977 this.composition.expandSelectionForEditing();
12978 return this.freezeSelection();
12979 }
12980 toolbarDidShowDialog(dialogName) {
12981 return this.notifyEditorElement("toolbar-dialog-show", {
12982 dialogName
12983 });
12984 }
12985 toolbarDidHideDialog(dialogName) {
12986 this.thawSelection();
12987 this.editorElement.focus();
12988 return this.notifyEditorElement("toolbar-dialog-hide", {
12989 dialogName
12990 });
12991 }
12992
12993 // Selection
12994
12995 freezeSelection() {
12996 if (!this.selectionFrozen) {
12997 this.selectionManager.lock();
12998 this.composition.freezeSelection();
12999 this.selectionFrozen = true;
13000 return this.render();
13001 }
13002 }
13003 thawSelection() {
13004 if (this.selectionFrozen) {
13005 this.composition.thawSelection();
13006 this.selectionManager.unlock();
13007 this.selectionFrozen = false;
13008 return this.render();
13009 }
13010 }
13011 canInvokeAction(actionName) {
13012 if (this.actionIsExternal(actionName)) {
13013 return true;
13014 } else {
13015 var _this$actions$actionN;
13016 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));
13017 }
13018 }
13019 invokeAction(actionName, invokingElement) {
13020 if (this.actionIsExternal(actionName)) {
13021 return this.notifyEditorElement("action-invoke", {
13022 actionName,
13023 invokingElement
13024 });
13025 } else {
13026 var _this$actions$actionN2;
13027 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);
13028 }
13029 }
13030 actionIsExternal(actionName) {
13031 return /^x-./.test(actionName);
13032 }
13033 getCurrentActions() {
13034 const result = {};
13035 for (const actionName in this.actions) {
13036 result[actionName] = this.canInvokeAction(actionName);
13037 }
13038 return result;
13039 }
13040 updateCurrentActions() {
13041 const currentActions = this.getCurrentActions();
13042 if (!objectsAreEqual(currentActions, this.currentActions)) {
13043 this.currentActions = currentActions;
13044 this.toolbarController.updateActions(this.currentActions);
13045 return this.notifyEditorElement("actions-change", {
13046 actions: this.currentActions
13047 });
13048 }
13049 }
13050
13051 // Editor filters
13052
13053 runEditorFilters() {
13054 let snapshot = this.composition.getSnapshot();
13055 Array.from(this.editor.filters).forEach(filter => {
13056 const {
13057 document,
13058 selectedRange
13059 } = snapshot;
13060 snapshot = filter.call(this.editor, snapshot) || {};
13061 if (!snapshot.document) {
13062 snapshot.document = document;
13063 }
13064 if (!snapshot.selectedRange) {
13065 snapshot.selectedRange = selectedRange;
13066 }
13067 });
13068 if (!snapshotsAreEqual(snapshot, this.composition.getSnapshot())) {
13069 return this.composition.loadSnapshot(snapshot);
13070 }
13071 }
13072
13073 // Private
13074
13075 updateInputElement() {
13076 const element = this.compositionController.getSerializableElement();
13077 const value = serializeToContentType(element, "text/html");
13078 return this.editorElement.setFormValue(value);
13079 }
13080 notifyEditorElement(message, data) {
13081 switch (message) {
13082 case "document-change":
13083 this.documentChangedSinceLastRender = true;
13084 break;
13085 case "render":
13086 if (this.documentChangedSinceLastRender) {
13087 this.documentChangedSinceLastRender = false;
13088 this.notifyEditorElement("change");
13089 }
13090 break;
13091 case "change":
13092 case "attachment-add":
13093 case "attachment-edit":
13094 case "attachment-remove":
13095 this.updateInputElement();
13096 break;
13097 }
13098 return this.editorElement.notify(message, data);
13099 }
13100 removeAttachment(attachment) {
13101 this.editor.recordUndoEntry("Delete Attachment");
13102 this.composition.removeAttachment(attachment);
13103 return this.render();
13104 }
13105 recordFormattingUndoEntry(attributeName) {
13106 const blockConfig = getBlockConfig(attributeName);
13107 const locationRange = this.selectionManager.getLocationRange();
13108 if (blockConfig || !rangeIsCollapsed(locationRange)) {
13109 return this.editor.recordUndoEntry("Formatting", {
13110 context: this.getUndoContext(),
13111 consolidatable: true
13112 });
13113 }
13114 }
13115 recordTypingUndoEntry() {
13116 return this.editor.recordUndoEntry("Typing", {
13117 context: this.getUndoContext(this.currentAttributes),
13118 consolidatable: true
13119 });
13120 }
13121 getUndoContext() {
13122 for (var _len = arguments.length, context = new Array(_len), _key = 0; _key < _len; _key++) {
13123 context[_key] = arguments[_key];
13124 }
13125 return [this.getLocationContext(), this.getTimeContext(), ...Array.from(context)];
13126 }
13127 getLocationContext() {
13128 const locationRange = this.selectionManager.getLocationRange();
13129 if (rangeIsCollapsed(locationRange)) {
13130 return locationRange[0].index;
13131 } else {
13132 return locationRange;
13133 }
13134 }
13135 getTimeContext() {
13136 if (undo.interval > 0) {
13137 return Math.floor(new Date().getTime() / undo.interval);
13138 } else {
13139 return 0;
13140 }
13141 }
13142 isFocused() {
13143 var _this$editorElement$o;
13144 return this.editorElement === ((_this$editorElement$o = this.editorElement.ownerDocument) === null || _this$editorElement$o === void 0 ? void 0 : _this$editorElement$o.activeElement);
13145 }
13146
13147 // Detect "Cursor disappears sporadically" Firefox bug.
13148 // - https://bugzilla.mozilla.org/show_bug.cgi?id=226301
13149 isFocusedInvisibly() {
13150 return this.isFocused() && !this.getLocationRange();
13151 }
13152 get actions() {
13153 return this.constructor.actions;
13154 }
13155 }
13156 _defineProperty(EditorController, "actions", {
13157 undo: {
13158 test() {
13159 return this.editor.canUndo();
13160 },
13161 perform() {
13162 return this.editor.undo();
13163 }
13164 },
13165 redo: {
13166 test() {
13167 return this.editor.canRedo();
13168 },
13169 perform() {
13170 return this.editor.redo();
13171 }
13172 },
13173 link: {
13174 test() {
13175 return this.editor.canActivateAttribute("href");
13176 }
13177 },
13178 increaseNestingLevel: {
13179 test() {
13180 return this.editor.canIncreaseNestingLevel();
13181 },
13182 perform() {
13183 return this.editor.increaseNestingLevel() && this.render();
13184 }
13185 },
13186 decreaseNestingLevel: {
13187 test() {
13188 return this.editor.canDecreaseNestingLevel();
13189 },
13190 perform() {
13191 return this.editor.decreaseNestingLevel() && this.render();
13192 }
13193 },
13194 attachFiles: {
13195 test() {
13196 return true;
13197 },
13198 perform() {
13199 return input.pickFiles(this.editor.insertFiles);
13200 }
13201 }
13202 });
13203 EditorController.proxyMethod("getSelectionManager().setLocationRange");
13204 EditorController.proxyMethod("getSelectionManager().getLocationRange");
13205
13206 var controllers = /*#__PURE__*/Object.freeze({
13207 __proto__: null,
13208 AttachmentEditorController: AttachmentEditorController,
13209 CompositionController: CompositionController,
13210 Controller: Controller,
13211 EditorController: EditorController,
13212 InputController: InputController,
13213 Level0InputController: Level0InputController,
13214 Level2InputController: Level2InputController,
13215 ToolbarController: ToolbarController
13216 });
13217
13218 var observers = /*#__PURE__*/Object.freeze({
13219 __proto__: null,
13220 MutationObserver: MutationObserver,
13221 SelectionChangeObserver: SelectionChangeObserver
13222 });
13223
13224 var operations = /*#__PURE__*/Object.freeze({
13225 __proto__: null,
13226 FileVerificationOperation: FileVerificationOperation,
13227 ImagePreloadOperation: ImagePreloadOperation
13228 });
13229
13230 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}");
13231 class TrixToolbarElement extends HTMLElement {
13232 // Element lifecycle
13233
13234 connectedCallback() {
13235 if (this.innerHTML === "") {
13236 this.innerHTML = toolbar.getDefaultHTML();
13237 }
13238 }
13239 }
13240
13241 let id = 0;
13242
13243 // Contenteditable support helpers
13244
13245 const autofocus = function (element) {
13246 if (!document.querySelector(":focus")) {
13247 if (element.hasAttribute("autofocus") && document.querySelector("[autofocus]") === element) {
13248 return element.focus();
13249 }
13250 }
13251 };
13252 const makeEditable = function (element) {
13253 if (element.hasAttribute("contenteditable")) {
13254 return;
13255 }
13256 element.setAttribute("contenteditable", "");
13257 return handleEventOnce("focus", {
13258 onElement: element,
13259 withCallback() {
13260 return configureContentEditable(element);
13261 }
13262 });
13263 };
13264 const configureContentEditable = function (element) {
13265 disableObjectResizing(element);
13266 return setDefaultParagraphSeparator(element);
13267 };
13268 const disableObjectResizing = function (element) {
13269 var _document$queryComman, _document;
13270 if ((_document$queryComman = (_document = document).queryCommandSupported) !== null && _document$queryComman !== void 0 && _document$queryComman.call(_document, "enableObjectResizing")) {
13271 document.execCommand("enableObjectResizing", false, false);
13272 return handleEvent("mscontrolselect", {
13273 onElement: element,
13274 preventDefault: true
13275 });
13276 }
13277 };
13278 const setDefaultParagraphSeparator = function (element) {
13279 var _document$queryComman2, _document2;
13280 if ((_document$queryComman2 = (_document2 = document).queryCommandSupported) !== null && _document$queryComman2 !== void 0 && _document$queryComman2.call(_document2, "DefaultParagraphSeparator")) {
13281 const {
13282 tagName
13283 } = attributes.default;
13284 if (["div", "p"].includes(tagName)) {
13285 return document.execCommand("DefaultParagraphSeparator", false, tagName);
13286 }
13287 }
13288 };
13289
13290 // Accessibility helpers
13291
13292 const addAccessibilityRole = function (element) {
13293 if (element.hasAttribute("role")) {
13294 return;
13295 }
13296 return element.setAttribute("role", "textbox");
13297 };
13298 const ensureAriaLabel = function (element) {
13299 if (element.hasAttribute("aria-label") || element.hasAttribute("aria-labelledby")) {
13300 return;
13301 }
13302 const update = function () {
13303 const texts = Array.from(element.labels).map(label => {
13304 if (!label.contains(element)) return label.textContent;
13305 }).filter(text => text);
13306 const text = texts.join(" ");
13307 if (text) {
13308 return element.setAttribute("aria-label", text);
13309 } else {
13310 return element.removeAttribute("aria-label");
13311 }
13312 };
13313 update();
13314 return handleEvent("focus", {
13315 onElement: element,
13316 withCallback: update
13317 });
13318 };
13319
13320 // Style
13321
13322 const cursorTargetStyles = function () {
13323 if (browser$1.forcesObjectResizing) {
13324 return {
13325 display: "inline",
13326 width: "auto"
13327 };
13328 } else {
13329 return {
13330 display: "inline-block",
13331 width: "1px"
13332 };
13333 }
13334 }();
13335 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}"));
13336 var _internals = /*#__PURE__*/new WeakMap();
13337 var _validate = /*#__PURE__*/new WeakSet();
13338 class ElementInternalsDelegate {
13339 constructor(element) {
13340 _classPrivateMethodInitSpec(this, _validate);
13341 _classPrivateFieldInitSpec(this, _internals, {
13342 writable: true,
13343 value: void 0
13344 });
13345 this.element = element;
13346 _classPrivateFieldSet(this, _internals, element.attachInternals());
13347 }
13348 connectedCallback() {
13349 _classPrivateMethodGet(this, _validate, _validate2).call(this);
13350 }
13351 disconnectedCallback() {}
13352 get labels() {
13353 return _classPrivateFieldGet(this, _internals).labels;
13354 }
13355 get disabled() {
13356 var _this$element$inputEl;
13357 return (_this$element$inputEl = this.element.inputElement) === null || _this$element$inputEl === void 0 ? void 0 : _this$element$inputEl.disabled;
13358 }
13359 set disabled(value) {
13360 this.element.toggleAttribute("disabled", value);
13361 }
13362 get required() {
13363 return this.element.hasAttribute("required");
13364 }
13365 set required(value) {
13366 this.element.toggleAttribute("required", value);
13367 _classPrivateMethodGet(this, _validate, _validate2).call(this);
13368 }
13369 get validity() {
13370 return _classPrivateFieldGet(this, _internals).validity;
13371 }
13372 get validationMessage() {
13373 return _classPrivateFieldGet(this, _internals).validationMessage;
13374 }
13375 get willValidate() {
13376 return _classPrivateFieldGet(this, _internals).willValidate;
13377 }
13378 setFormValue(value) {
13379 _classPrivateMethodGet(this, _validate, _validate2).call(this);
13380 }
13381 checkValidity() {
13382 return _classPrivateFieldGet(this, _internals).checkValidity();
13383 }
13384 reportValidity() {
13385 return _classPrivateFieldGet(this, _internals).reportValidity();
13386 }
13387 setCustomValidity(validationMessage) {
13388 _classPrivateMethodGet(this, _validate, _validate2).call(this, validationMessage);
13389 }
13390 }
13391 function _validate2() {
13392 let customValidationMessage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
13393 const {
13394 required,
13395 value
13396 } = this.element;
13397 const valueMissing = required && !value;
13398 const customError = !!customValidationMessage;
13399 const input = makeElement("input", {
13400 required
13401 });
13402 const validationMessage = customValidationMessage || input.validationMessage;
13403 _classPrivateFieldGet(this, _internals).setValidity({
13404 valueMissing,
13405 customError
13406 }, validationMessage);
13407 }
13408 var _focusHandler = /*#__PURE__*/new WeakMap();
13409 var _resetBubbled = /*#__PURE__*/new WeakMap();
13410 var _clickBubbled = /*#__PURE__*/new WeakMap();
13411 class LegacyDelegate {
13412 constructor(element) {
13413 _classPrivateFieldInitSpec(this, _focusHandler, {
13414 writable: true,
13415 value: void 0
13416 });
13417 _classPrivateFieldInitSpec(this, _resetBubbled, {
13418 writable: true,
13419 value: event => {
13420 if (event.defaultPrevented) return;
13421 if (event.target !== this.element.form) return;
13422 this.element.reset();
13423 }
13424 });
13425 _classPrivateFieldInitSpec(this, _clickBubbled, {
13426 writable: true,
13427 value: event => {
13428 if (event.defaultPrevented) return;
13429 if (this.element.contains(event.target)) return;
13430 const label = findClosestElementFromNode(event.target, {
13431 matchingSelector: "label"
13432 });
13433 if (!label) return;
13434 if (!Array.from(this.labels).includes(label)) return;
13435 this.element.focus();
13436 }
13437 });
13438 this.element = element;
13439 }
13440 connectedCallback() {
13441 _classPrivateFieldSet(this, _focusHandler, ensureAriaLabel(this.element));
13442 window.addEventListener("reset", _classPrivateFieldGet(this, _resetBubbled), false);
13443 window.addEventListener("click", _classPrivateFieldGet(this, _clickBubbled), false);
13444 }
13445 disconnectedCallback() {
13446 var _classPrivateFieldGet2;
13447 (_classPrivateFieldGet2 = _classPrivateFieldGet(this, _focusHandler)) === null || _classPrivateFieldGet2 === void 0 || _classPrivateFieldGet2.destroy();
13448 window.removeEventListener("reset", _classPrivateFieldGet(this, _resetBubbled), false);
13449 window.removeEventListener("click", _classPrivateFieldGet(this, _clickBubbled), false);
13450 }
13451 get labels() {
13452 const labels = [];
13453 if (this.element.id && this.element.ownerDocument) {
13454 labels.push(...Array.from(this.element.ownerDocument.querySelectorAll("label[for='".concat(this.element.id, "']")) || []));
13455 }
13456 const label = findClosestElementFromNode(this.element, {
13457 matchingSelector: "label"
13458 });
13459 if (label) {
13460 if ([this.element, null].includes(label.control)) {
13461 labels.push(label);
13462 }
13463 }
13464 return labels;
13465 }
13466 get disabled() {
13467 console.warn("This browser does not support the [disabled] attribute for trix-editor elements.");
13468 return false;
13469 }
13470 set disabled(value) {
13471 console.warn("This browser does not support the [disabled] attribute for trix-editor elements.");
13472 }
13473 get required() {
13474 console.warn("This browser does not support the [required] attribute for trix-editor elements.");
13475 return false;
13476 }
13477 set required(value) {
13478 console.warn("This browser does not support the [required] attribute for trix-editor elements.");
13479 }
13480 get validity() {
13481 console.warn("This browser does not support the validity property for trix-editor elements.");
13482 return null;
13483 }
13484 get validationMessage() {
13485 console.warn("This browser does not support the validationMessage property for trix-editor elements.");
13486 return "";
13487 }
13488 get willValidate() {
13489 console.warn("This browser does not support the willValidate property for trix-editor elements.");
13490 return false;
13491 }
13492 setFormValue(value) {}
13493 checkValidity() {
13494 console.warn("This browser does not support checkValidity() for trix-editor elements.");
13495 return true;
13496 }
13497 reportValidity() {
13498 console.warn("This browser does not support reportValidity() for trix-editor elements.");
13499 return true;
13500 }
13501 setCustomValidity(validationMessage) {
13502 console.warn("This browser does not support setCustomValidity(validationMessage) for trix-editor elements.");
13503 }
13504 }
13505 var _delegate = /*#__PURE__*/new WeakMap();
13506 class TrixEditorElement extends HTMLElement {
13507 constructor() {
13508 super();
13509 _classPrivateFieldInitSpec(this, _delegate, {
13510 writable: true,
13511 value: void 0
13512 });
13513 _classPrivateFieldSet(this, _delegate, this.constructor.formAssociated ? new ElementInternalsDelegate(this) : new LegacyDelegate(this));
13514 }
13515
13516 // Properties
13517
13518 get trixId() {
13519 if (this.hasAttribute("trix-id")) {
13520 return this.getAttribute("trix-id");
13521 } else {
13522 this.setAttribute("trix-id", ++id);
13523 return this.trixId;
13524 }
13525 }
13526 get labels() {
13527 return _classPrivateFieldGet(this, _delegate).labels;
13528 }
13529 get disabled() {
13530 return _classPrivateFieldGet(this, _delegate).disabled;
13531 }
13532 set disabled(value) {
13533 _classPrivateFieldGet(this, _delegate).disabled = value;
13534 }
13535 get required() {
13536 return _classPrivateFieldGet(this, _delegate).required;
13537 }
13538 set required(value) {
13539 _classPrivateFieldGet(this, _delegate).required = value;
13540 }
13541 get validity() {
13542 return _classPrivateFieldGet(this, _delegate).validity;
13543 }
13544 get validationMessage() {
13545 return _classPrivateFieldGet(this, _delegate).validationMessage;
13546 }
13547 get willValidate() {
13548 return _classPrivateFieldGet(this, _delegate).willValidate;
13549 }
13550 get type() {
13551 return this.localName;
13552 }
13553 get toolbarElement() {
13554 if (this.hasAttribute("toolbar")) {
13555 var _this$ownerDocument;
13556 return (_this$ownerDocument = this.ownerDocument) === null || _this$ownerDocument === void 0 ? void 0 : _this$ownerDocument.getElementById(this.getAttribute("toolbar"));
13557 } else if (this.parentNode) {
13558 const toolbarId = "trix-toolbar-".concat(this.trixId);
13559 this.setAttribute("toolbar", toolbarId);
13560 const element = makeElement("trix-toolbar", {
13561 id: toolbarId
13562 });
13563 this.parentNode.insertBefore(element, this);
13564 return element;
13565 } else {
13566 return undefined;
13567 }
13568 }
13569 get form() {
13570 var _this$inputElement;
13571 return (_this$inputElement = this.inputElement) === null || _this$inputElement === void 0 ? void 0 : _this$inputElement.form;
13572 }
13573 get inputElement() {
13574 if (this.hasAttribute("input")) {
13575 var _this$ownerDocument2;
13576 return (_this$ownerDocument2 = this.ownerDocument) === null || _this$ownerDocument2 === void 0 ? void 0 : _this$ownerDocument2.getElementById(this.getAttribute("input"));
13577 } else if (this.parentNode) {
13578 const inputId = "trix-input-".concat(this.trixId);
13579 this.setAttribute("input", inputId);
13580 const element = makeElement("input", {
13581 type: "hidden",
13582 id: inputId
13583 });
13584 this.parentNode.insertBefore(element, this.nextElementSibling);
13585 return element;
13586 } else {
13587 return undefined;
13588 }
13589 }
13590 get editor() {
13591 var _this$editorControlle;
13592 return (_this$editorControlle = this.editorController) === null || _this$editorControlle === void 0 ? void 0 : _this$editorControlle.editor;
13593 }
13594 get name() {
13595 var _this$inputElement2;
13596 return (_this$inputElement2 = this.inputElement) === null || _this$inputElement2 === void 0 ? void 0 : _this$inputElement2.name;
13597 }
13598 get value() {
13599 var _this$inputElement3;
13600 return (_this$inputElement3 = this.inputElement) === null || _this$inputElement3 === void 0 ? void 0 : _this$inputElement3.value;
13601 }
13602 set value(defaultValue) {
13603 var _this$editor;
13604 this.defaultValue = defaultValue;
13605 (_this$editor = this.editor) === null || _this$editor === void 0 || _this$editor.loadHTML(this.defaultValue);
13606 }
13607
13608 // Controller delegate methods
13609
13610 notify(message, data) {
13611 if (this.editorController) {
13612 return triggerEvent("trix-".concat(message), {
13613 onElement: this,
13614 attributes: data
13615 });
13616 }
13617 }
13618 setFormValue(value) {
13619 if (this.inputElement) {
13620 this.inputElement.value = value;
13621 _classPrivateFieldGet(this, _delegate).setFormValue(value);
13622 }
13623 }
13624
13625 // Element lifecycle
13626
13627 connectedCallback() {
13628 if (!this.hasAttribute("data-trix-internal")) {
13629 makeEditable(this);
13630 addAccessibilityRole(this);
13631 if (!this.editorController) {
13632 triggerEvent("trix-before-initialize", {
13633 onElement: this
13634 });
13635 this.editorController = new EditorController({
13636 editorElement: this,
13637 html: this.defaultValue = this.value
13638 });
13639 requestAnimationFrame(() => triggerEvent("trix-initialize", {
13640 onElement: this
13641 }));
13642 }
13643 this.editorController.registerSelectionManager();
13644 _classPrivateFieldGet(this, _delegate).connectedCallback();
13645 autofocus(this);
13646 }
13647 }
13648 disconnectedCallback() {
13649 var _this$editorControlle2;
13650 (_this$editorControlle2 = this.editorController) === null || _this$editorControlle2 === void 0 || _this$editorControlle2.unregisterSelectionManager();
13651 _classPrivateFieldGet(this, _delegate).disconnectedCallback();
13652 }
13653
13654 // Form support
13655
13656 checkValidity() {
13657 return _classPrivateFieldGet(this, _delegate).checkValidity();
13658 }
13659 reportValidity() {
13660 return _classPrivateFieldGet(this, _delegate).reportValidity();
13661 }
13662 setCustomValidity(validationMessage) {
13663 _classPrivateFieldGet(this, _delegate).setCustomValidity(validationMessage);
13664 }
13665 formDisabledCallback(disabled) {
13666 if (this.inputElement) {
13667 this.inputElement.disabled = disabled;
13668 }
13669 this.toggleAttribute("contenteditable", !disabled);
13670 }
13671 formResetCallback() {
13672 this.reset();
13673 }
13674 reset() {
13675 this.value = this.defaultValue;
13676 }
13677 }
13678 _defineProperty(TrixEditorElement, "formAssociated", "ElementInternals" in window);
13679
13680 var elements = /*#__PURE__*/Object.freeze({
13681 __proto__: null,
13682 TrixEditorElement: TrixEditorElement,
13683 TrixToolbarElement: TrixToolbarElement
13684 });
13685
13686 var filters = /*#__PURE__*/Object.freeze({
13687 __proto__: null,
13688 Filter: Filter,
13689 attachmentGalleryFilter: attachmentGalleryFilter
13690 });
13691
13692 const Trix = {
13693 VERSION: version,
13694 config,
13695 core,
13696 models,
13697 views,
13698 controllers,
13699 observers,
13700 operations,
13701 elements,
13702 filters
13703 };
13704
13705 // Expose models under the Trix constant for compatibility with v1
13706 Object.assign(Trix, models);
13707 function start() {
13708 if (!customElements.get("trix-toolbar")) {
13709 customElements.define("trix-toolbar", TrixToolbarElement);
13710 }
13711 if (!customElements.get("trix-editor")) {
13712 customElements.define("trix-editor", TrixEditorElement);
13713 }
13714 }
13715 window.Trix = Trix;
13716 setTimeout(start, 0);
13717
13718 return Trix;
13719
13720}));