summaryrefslogtreecommitdiff
path: root/public/assets/trix-676299911f4cbd15d35b0e12904a12ed1d7cff634502b9bff8518aecace5a9a7.js
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-06-27 16:58:53 +0200
committererdgeist <erdgeist@erdgeist.org>2026-06-27 16:58:53 +0200
commit420506e58fdfc84f1a5bede0a01dedf0af3bb4f3 (patch)
tree57726b40e8aa9ccf80f874f39d3facefc0331420 /public/assets/trix-676299911f4cbd15d35b0e12904a12ed1d7cff634502b9bff8518aecace5a9a7.js
parent241d5e91b2b6716e2861cc77d319c3d3568343a8 (diff)
Stage 7: Rails 7.2 → 8.1 on Ruby 3.2.11
- Bump Rails to 8.1.3 (Ruby unchanged at 3.2.11, new gemset rails8-upgrade) - config.load_defaults 8.1; merge app:update diffs for all environment files - Remove routing-filter 0.7.0; replace with native scope '(:locale)' in routes.rb and default_url_options in ApplicationController - Delete config/initializers/routing_filter_rails71_patch.rb - Replace vendored TinyMCE 3.x (~200 files) with tinymce-rails ~> 8.3; migrate admin_interface.js from jQuery .tinymce()/advanced theme to tinymce.init(); add config/tinymce.yml; note: TinyMCE 7+ is GPL - rails-i18n ~> 8.0 added explicitly (previously indirect dependency) - awesome_nested_set, acts-as-taggable-on pinned to git main/master (gemspec activerecord < 8.1 ceiling; no functional incompatibility; repin to version once upstream releases updated gemspecs) - globalize ~> 7.0, libxml-ruby ~> 5.0, nokogiri ~> 1.18, pg ~> 1.5 - sass-rails, coffee-rails, uglifier moved from :assets group to main (Sprockets 4 convention; :assets group no longer meaningful) - Node: head, draft, lock_owner marked belongs_to optional: true - Page: node, user, editor marked belongs_to optional: true - Static assets in public/images/ and public/javascripts/ referenced via plain HTML tags; Rails 8 load_defaults raises on pipeline helpers for undeclared assets - sessions_controller_test.rb: remove stale require and dead rescue_action - users_controller_test.rb: assert button[type=submit] not input[type=submit] (Rails 8 button_to renders <button> not <input>) - test_helper.rb: node.reload after children.create! (awesome_nested_set 3.9.0 does not refresh parent in memory after callback) - 129 runs, 339 assertions, 3 failures, 0 errors — identical baseline to 7.2
Diffstat (limited to 'public/assets/trix-676299911f4cbd15d35b0e12904a12ed1d7cff634502b9bff8518aecace5a9a7.js')
-rw-r--r--public/assets/trix-676299911f4cbd15d35b0e12904a12ed1d7cff634502b9bff8518aecace5a9a7.js14001
1 files changed, 14001 insertions, 0 deletions
diff --git a/public/assets/trix-676299911f4cbd15d35b0e12904a12ed1d7cff634502b9bff8518aecace5a9a7.js b/public/assets/trix-676299911f4cbd15d35b0e12904a12ed1d7cff634502b9bff8518aecace5a9a7.js
new file mode 100644
index 00000000..8d831cd0
--- /dev/null
+++ b/public/assets/trix-676299911f4cbd15d35b0e12904a12ed1d7cff634502b9bff8518aecace5a9a7.js
@@ -0,0 +1,14001 @@
1/*
2Trix 2.1.19
3Copyright © 2026 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.19";
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 "@web/test-runner": "^0.20.2",
47 "@web/test-runner-playwright": "^0.11.1",
48 "@web/test-runner-webdriver": "^0.9.0",
49 "babel-eslint": "^10.1.0",
50 chokidar: "^4.0.2",
51 concurrently: "^7.4.0",
52 eslint: "^7.32.0",
53 esm: "^3.2.25",
54 idiomorph: "^0.7.3",
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 sass: "^1.83.0",
61 "source-map": "^0.7.6",
62 svgo: "^2.8.0",
63 webdriverio: "^7.19.5"
64 };
65 var resolutions = {
66 webdriverio: "^7.19.5"
67 };
68 var scripts = {
69 "build-css": "bin/sass-build assets/trix.scss dist/trix.css action_text-trix/app/assets/stylesheets/trix.css",
70 "build-js": "rollup -c",
71 "build-assets": "cp -f assets/*.html dist/",
72 "build-ruby": "rake -C action_text-trix sync",
73 build: "yarn run build-js && yarn run build-css && yarn run build-assets && yarn run build-ruby",
74 watch: "rollup -c -w",
75 lint: "eslint .",
76 pretest: "yarn run lint && yarn run build",
77 test: "web-test-runner",
78 "test:watch": "web-test-runner --watch",
79 version: "yarn build && git add action_text-trix",
80 prerelease: "yarn version && yarn test",
81 "release-npm": "npm adduser && npm publish",
82 "release-ruby": "rake -C action_text-trix release",
83 release: "yarn run release-npm && yarn run release-ruby",
84 postrelease: "git push && git push --tags",
85 dev: "web-dev-server --app-index index.html --root-dir dist --node-resolve --open",
86 start: "yarn build-assets && concurrently --kill-others --names js,css,dev-server 'yarn watch' 'yarn build-css --watch' 'yarn dev'"
87 };
88 var dependencies = {
89 dompurify: "^3.2.5"
90 };
91 var engines = {
92 node: ">= 18"
93 };
94 var _package = {
95 name: name,
96 version: version,
97 description: description,
98 main: main,
99 module: module,
100 style: style,
101 files: files,
102 repository: repository,
103 keywords: keywords,
104 author: author,
105 license: license,
106 bugs: bugs,
107 homepage: homepage,
108 devDependencies: devDependencies,
109 resolutions: resolutions,
110 scripts: scripts,
111 dependencies: dependencies,
112 engines: engines
113 };
114
115 const attachmentSelector = "[data-trix-attachment]";
116 const attachments = {
117 preview: {
118 presentation: "gallery",
119 caption: {
120 name: true,
121 size: true
122 }
123 },
124 file: {
125 caption: {
126 size: true
127 }
128 }
129 };
130
131 const attributes = {
132 default: {
133 tagName: "div",
134 parse: false
135 },
136 quote: {
137 tagName: "blockquote",
138 nestable: true
139 },
140 heading1: {
141 tagName: "h1",
142 terminal: true,
143 breakOnReturn: true,
144 group: false
145 },
146 code: {
147 tagName: "pre",
148 terminal: true,
149 htmlAttributes: ["language"],
150 text: {
151 plaintext: true
152 }
153 },
154 bulletList: {
155 tagName: "ul",
156 parse: false
157 },
158 bullet: {
159 tagName: "li",
160 listAttribute: "bulletList",
161 group: false,
162 nestable: true,
163 test(element) {
164 return tagName$1(element.parentNode) === attributes[this.listAttribute].tagName;
165 }
166 },
167 numberList: {
168 tagName: "ol",
169 parse: false
170 },
171 number: {
172 tagName: "li",
173 listAttribute: "numberList",
174 group: false,
175 nestable: true,
176 test(element) {
177 return tagName$1(element.parentNode) === attributes[this.listAttribute].tagName;
178 }
179 },
180 attachmentGallery: {
181 tagName: "div",
182 exclusive: true,
183 terminal: true,
184 parse: false,
185 group: false
186 }
187 };
188 const tagName$1 = element => {
189 var _element$tagName;
190 return element === null || element === void 0 || (_element$tagName = element.tagName) === null || _element$tagName === void 0 ? void 0 : _element$tagName.toLowerCase();
191 };
192
193 const androidVersionMatch = navigator.userAgent.match(/android\s([0-9]+.*Chrome)/i);
194 const androidVersion = androidVersionMatch && parseInt(androidVersionMatch[1]);
195 var browser$1 = {
196 // Android emits composition events when moving the cursor through existing text
197 // Introduced in Chrome 65: https://bugs.chromium.org/p/chromium/issues/detail?id=764439#c9
198 composesExistingText: /Android.*Chrome/.test(navigator.userAgent),
199 // Android 13, especially on Samsung keyboards, emits extra compositionend and beforeinput events
200 // that can make the input handler lose the current selection or enter an infinite input -> render -> input
201 // loop.
202 recentAndroid: androidVersion && androidVersion > 12,
203 samsungAndroid: androidVersion && navigator.userAgent.match(/Android.*SM-/),
204 // IE 11 activates resizing handles on editable elements that have "layout"
205 forcesObjectResizing: /Trident.*rv:11/.test(navigator.userAgent),
206 // https://www.w3.org/TR/input-events-1/ + https://www.w3.org/TR/input-events-2/
207 supportsInputEvents: typeof InputEvent !== "undefined" && ["data", "getTargetRanges", "inputType"].every(prop => prop in InputEvent.prototype)
208 };
209
210 var css$3 = {
211 attachment: "attachment",
212 attachmentCaption: "attachment__caption",
213 attachmentCaptionEditor: "attachment__caption-editor",
214 attachmentMetadata: "attachment__metadata",
215 attachmentMetadataContainer: "attachment__metadata-container",
216 attachmentName: "attachment__name",
217 attachmentProgress: "attachment__progress",
218 attachmentSize: "attachment__size",
219 attachmentToolbar: "attachment__toolbar",
220 attachmentGallery: "attachment-gallery"
221 };
222
223 var dompurify = {
224 ADD_ATTR: ["language"],
225 SAFE_FOR_XML: false,
226 RETURN_DOM: true
227 };
228
229 var lang$1 = {
230 attachFiles: "Attach Files",
231 bold: "Bold",
232 bullets: "Bullets",
233 byte: "Byte",
234 bytes: "Bytes",
235 captionPlaceholder: "Add a caption…",
236 code: "Code",
237 heading1: "Heading",
238 indent: "Increase Level",
239 italic: "Italic",
240 link: "Link",
241 numbers: "Numbers",
242 outdent: "Decrease Level",
243 quote: "Quote",
244 redo: "Redo",
245 remove: "Remove",
246 strike: "Strikethrough",
247 undo: "Undo",
248 unlink: "Unlink",
249 url: "URL",
250 urlPlaceholder: "Enter a URL…",
251 GB: "GB",
252 KB: "KB",
253 MB: "MB",
254 PB: "PB",
255 TB: "TB"
256 };
257
258 /* eslint-disable
259 no-case-declarations,
260 */
261 const sizes = [lang$1.bytes, lang$1.KB, lang$1.MB, lang$1.GB, lang$1.TB, lang$1.PB];
262 var file_size_formatting = {
263 prefix: "IEC",
264 precision: 2,
265 formatter(number) {
266 switch (number) {
267 case 0:
268 return "0 ".concat(lang$1.bytes);
269 case 1:
270 return "1 ".concat(lang$1.byte);
271 default:
272 let base;
273 if (this.prefix === "SI") {
274 base = 1000;
275 } else if (this.prefix === "IEC") {
276 base = 1024;
277 }
278 const exp = Math.floor(Math.log(number) / Math.log(base));
279 const humanSize = number / Math.pow(base, exp);
280 const string = humanSize.toFixed(this.precision);
281 const withoutInsignificantZeros = string.replace(/0*$/, "").replace(/\.$/, "");
282 return "".concat(withoutInsignificantZeros, " ").concat(sizes[exp]);
283 }
284 }
285 };
286
287 const ZERO_WIDTH_SPACE = "\uFEFF";
288 const NON_BREAKING_SPACE = "\u00A0";
289 const OBJECT_REPLACEMENT_CHARACTER = "\uFFFC";
290
291 const extend = function (properties) {
292 for (const key in properties) {
293 const value = properties[key];
294 this[key] = value;
295 }
296 return this;
297 };
298
299 const html$2 = document.documentElement;
300 const match = html$2.matches;
301 const handleEvent = function (eventName) {
302 let {
303 onElement,
304 matchingSelector,
305 withCallback,
306 inPhase,
307 preventDefault,
308 times
309 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
310 const element = onElement ? onElement : html$2;
311 const selector = matchingSelector;
312 const useCapture = inPhase === "capturing";
313 const handler = function (event) {
314 if (times != null && --times === 0) {
315 handler.destroy();
316 }
317 const target = findClosestElementFromNode(event.target, {
318 matchingSelector: selector
319 });
320 if (target != null) {
321 withCallback === null || withCallback === void 0 || withCallback.call(target, event, target);
322 if (preventDefault) {
323 event.preventDefault();
324 }
325 }
326 };
327 handler.destroy = () => element.removeEventListener(eventName, handler, useCapture);
328 element.addEventListener(eventName, handler, useCapture);
329 return handler;
330 };
331 const handleEventOnce = function (eventName) {
332 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
333 options.times = 1;
334 return handleEvent(eventName, options);
335 };
336 const createEvent = function (eventName) {
337 let {
338 bubbles,
339 cancelable,
340 attributes
341 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
342 bubbles = bubbles !== false;
343 cancelable = cancelable !== false;
344 const event = document.createEvent("Events");
345 event.initEvent(eventName, bubbles, cancelable);
346 if (attributes != null) {
347 extend.call(event, attributes);
348 }
349 return event;
350 };
351 const triggerEvent = function (eventName) {
352 let {
353 onElement,
354 bubbles,
355 cancelable,
356 attributes
357 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
358 const element = onElement != null ? onElement : html$2;
359 const event = createEvent(eventName, {
360 bubbles,
361 cancelable,
362 attributes
363 });
364 return element.dispatchEvent(event);
365 };
366 const elementMatchesSelector = function (element, selector) {
367 if ((element === null || element === void 0 ? void 0 : element.nodeType) === 1) {
368 return match.call(element, selector);
369 }
370 };
371 const findClosestElementFromNode = function (node) {
372 let {
373 matchingSelector,
374 untilNode
375 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
376 while (node && node.nodeType !== Node.ELEMENT_NODE) {
377 node = node.parentNode;
378 }
379 if (node == null) {
380 return;
381 }
382 if (matchingSelector != null) {
383 if (node.closest && untilNode == null) {
384 return node.closest(matchingSelector);
385 } else {
386 while (node && node !== untilNode) {
387 if (elementMatchesSelector(node, matchingSelector)) {
388 return node;
389 }
390 node = node.parentNode;
391 }
392 }
393 } else {
394 return node;
395 }
396 };
397 const findInnerElement = function (element) {
398 while ((_element = element) !== null && _element !== void 0 && _element.firstElementChild) {
399 var _element;
400 element = element.firstElementChild;
401 }
402 return element;
403 };
404 const innerElementIsActive = element => document.activeElement !== element && elementContainsNode(element, document.activeElement);
405 const elementContainsNode = function (element, node) {
406 if (!element || !node) {
407 return;
408 }
409 while (node) {
410 if (node === element) {
411 return true;
412 }
413 node = node.parentNode;
414 }
415 };
416 const findNodeFromContainerAndOffset = function (container, offset) {
417 if (!container) {
418 return;
419 }
420 if (container.nodeType === Node.TEXT_NODE) {
421 return container;
422 } else if (offset === 0) {
423 return container.firstChild != null ? container.firstChild : container;
424 } else {
425 return container.childNodes.item(offset - 1);
426 }
427 };
428 const findElementFromContainerAndOffset = function (container, offset) {
429 const node = findNodeFromContainerAndOffset(container, offset);
430 return findClosestElementFromNode(node);
431 };
432 const findChildIndexOfNode = function (node) {
433 var _node;
434 if (!((_node = node) !== null && _node !== void 0 && _node.parentNode)) {
435 return;
436 }
437 let childIndex = 0;
438 node = node.previousSibling;
439 while (node) {
440 childIndex++;
441 node = node.previousSibling;
442 }
443 return childIndex;
444 };
445 const removeNode = node => {
446 var _node$parentNode;
447 return node === null || node === void 0 || (_node$parentNode = node.parentNode) === null || _node$parentNode === void 0 ? void 0 : _node$parentNode.removeChild(node);
448 };
449 const walkTree = function (tree) {
450 let {
451 onlyNodesOfType,
452 usingFilter,
453 expandEntityReferences
454 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
455 const whatToShow = (() => {
456 switch (onlyNodesOfType) {
457 case "element":
458 return NodeFilter.SHOW_ELEMENT;
459 case "text":
460 return NodeFilter.SHOW_TEXT;
461 case "comment":
462 return NodeFilter.SHOW_COMMENT;
463 default:
464 return NodeFilter.SHOW_ALL;
465 }
466 })();
467 return document.createTreeWalker(tree, whatToShow, usingFilter != null ? usingFilter : null, expandEntityReferences === true);
468 };
469 const tagName = element => {
470 var _element$tagName;
471 return element === null || element === void 0 || (_element$tagName = element.tagName) === null || _element$tagName === void 0 ? void 0 : _element$tagName.toLowerCase();
472 };
473 const makeElement = function (tag) {
474 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
475 let key, value;
476 if (typeof tag === "object") {
477 options = tag;
478 tag = options.tagName;
479 } else {
480 options = {
481 attributes: options
482 };
483 }
484 const element = document.createElement(tag);
485 if (options.editable != null) {
486 if (options.attributes == null) {
487 options.attributes = {};
488 }
489 options.attributes.contenteditable = options.editable;
490 }
491 if (options.attributes) {
492 for (key in options.attributes) {
493 value = options.attributes[key];
494 element.setAttribute(key, value);
495 }
496 }
497 if (options.style) {
498 for (key in options.style) {
499 value = options.style[key];
500 element.style[key] = value;
501 }
502 }
503 if (options.data) {
504 for (key in options.data) {
505 value = options.data[key];
506 element.dataset[key] = value;
507 }
508 }
509 if (options.className) {
510 options.className.split(" ").forEach(className => {
511 element.classList.add(className);
512 });
513 }
514 if (options.textContent) {
515 element.textContent = options.textContent;
516 }
517 if (options.childNodes) {
518 [].concat(options.childNodes).forEach(childNode => {
519 element.appendChild(childNode);
520 });
521 }
522 return element;
523 };
524 let blockTagNames = undefined;
525 const getBlockTagNames = function () {
526 if (blockTagNames != null) {
527 return blockTagNames;
528 }
529 blockTagNames = [];
530 for (const key in attributes) {
531 const attributes$1 = attributes[key];
532 if (attributes$1.tagName) {
533 blockTagNames.push(attributes$1.tagName);
534 }
535 }
536 return blockTagNames;
537 };
538 const nodeIsBlockContainer = node => nodeIsBlockStartComment(node === null || node === void 0 ? void 0 : node.firstChild);
539 const nodeProbablyIsBlockContainer = function (node) {
540 return getBlockTagNames().includes(tagName(node)) && !getBlockTagNames().includes(tagName(node.firstChild));
541 };
542 const nodeIsBlockStart = function (node) {
543 let {
544 strict
545 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
546 strict: true
547 };
548 if (strict) {
549 return nodeIsBlockStartComment(node);
550 } else {
551 return nodeIsBlockStartComment(node) || !nodeIsBlockStartComment(node.firstChild) && nodeProbablyIsBlockContainer(node);
552 }
553 };
554 const nodeIsBlockStartComment = node => nodeIsCommentNode(node) && (node === null || node === void 0 ? void 0 : node.data) === "block";
555 const nodeIsCommentNode = node => (node === null || node === void 0 ? void 0 : node.nodeType) === Node.COMMENT_NODE;
556 const nodeIsCursorTarget = function (node) {
557 let {
558 name
559 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
560 if (!node) {
561 return;
562 }
563 if (nodeIsTextNode(node)) {
564 if (node.data === ZERO_WIDTH_SPACE) {
565 if (name) {
566 return node.parentNode.dataset.trixCursorTarget === name;
567 } else {
568 return true;
569 }
570 }
571 } else {
572 return nodeIsCursorTarget(node.firstChild);
573 }
574 };
575 const nodeIsAttachmentElement = node => elementMatchesSelector(node, attachmentSelector);
576 const nodeIsEmptyTextNode = node => nodeIsTextNode(node) && (node === null || node === void 0 ? void 0 : node.data) === "";
577 const nodeIsTextNode = node => (node === null || node === void 0 ? void 0 : node.nodeType) === Node.TEXT_NODE;
578
579 const input = {
580 level2Enabled: true,
581 getLevel() {
582 if (this.level2Enabled && browser$1.supportsInputEvents) {
583 return 2;
584 } else {
585 return 0;
586 }
587 },
588 pickFiles(callback) {
589 const input = makeElement("input", {
590 type: "file",
591 multiple: true,
592 hidden: true,
593 id: this.fileInputId
594 });
595 input.addEventListener("change", () => {
596 callback(input.files);
597 removeNode(input);
598 });
599 removeNode(document.getElementById(this.fileInputId));
600 document.body.appendChild(input);
601 input.click();
602 }
603 };
604
605 var key_names = {
606 8: "backspace",
607 9: "tab",
608 13: "return",
609 27: "escape",
610 37: "left",
611 39: "right",
612 46: "delete",
613 68: "d",
614 72: "h",
615 79: "o"
616 };
617
618 var parser = {
619 removeBlankTableCells: false,
620 tableCellSeparator: " | ",
621 tableRowSeparator: "\n"
622 };
623
624 var text_attributes = {
625 bold: {
626 tagName: "strong",
627 inheritable: true,
628 parser(element) {
629 const style = window.getComputedStyle(element);
630 return style.fontWeight === "bold" || style.fontWeight >= 600;
631 }
632 },
633 italic: {
634 tagName: "em",
635 inheritable: true,
636 parser(element) {
637 const style = window.getComputedStyle(element);
638 return style.fontStyle === "italic";
639 }
640 },
641 href: {
642 groupTagName: "a",
643 parser(element) {
644 const matchingSelector = "a:not(".concat(attachmentSelector, ")");
645 const link = element.closest(matchingSelector);
646 if (link) {
647 return link.getAttribute("href");
648 }
649 }
650 },
651 strike: {
652 tagName: "del",
653 inheritable: true
654 },
655 frozen: {
656 style: {
657 backgroundColor: "highlight"
658 }
659 }
660 };
661
662 var toolbar = {
663 getDefaultHTML() {
664 return "<div class=\"trix-button-row\">\n <span class=\"trix-button-group trix-button-group--text-tools\" data-trix-button-group=\"text-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-bold\" data-trix-attribute=\"bold\" data-trix-key=\"b\" title=\"".concat(lang$1.bold, "\" tabindex=\"-1\">").concat(lang$1.bold, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-italic\" data-trix-attribute=\"italic\" data-trix-key=\"i\" title=\"").concat(lang$1.italic, "\" tabindex=\"-1\">").concat(lang$1.italic, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-strike\" data-trix-attribute=\"strike\" title=\"").concat(lang$1.strike, "\" tabindex=\"-1\">").concat(lang$1.strike, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-link\" data-trix-attribute=\"href\" data-trix-action=\"link\" data-trix-key=\"k\" title=\"").concat(lang$1.link, "\" tabindex=\"-1\">").concat(lang$1.link, "</button>\n </span>\n\n <span class=\"trix-button-group trix-button-group--block-tools\" data-trix-button-group=\"block-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-heading-1\" data-trix-attribute=\"heading1\" title=\"").concat(lang$1.heading1, "\" tabindex=\"-1\">").concat(lang$1.heading1, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-quote\" data-trix-attribute=\"quote\" title=\"").concat(lang$1.quote, "\" tabindex=\"-1\">").concat(lang$1.quote, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-code\" data-trix-attribute=\"code\" title=\"").concat(lang$1.code, "\" tabindex=\"-1\">").concat(lang$1.code, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-bullet-list\" data-trix-attribute=\"bullet\" title=\"").concat(lang$1.bullets, "\" tabindex=\"-1\">").concat(lang$1.bullets, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-number-list\" data-trix-attribute=\"number\" title=\"").concat(lang$1.numbers, "\" tabindex=\"-1\">").concat(lang$1.numbers, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-decrease-nesting-level\" data-trix-action=\"decreaseNestingLevel\" title=\"").concat(lang$1.outdent, "\" tabindex=\"-1\">").concat(lang$1.outdent, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-increase-nesting-level\" data-trix-action=\"increaseNestingLevel\" title=\"").concat(lang$1.indent, "\" tabindex=\"-1\">").concat(lang$1.indent, "</button>\n </span>\n\n <span class=\"trix-button-group trix-button-group--file-tools\" data-trix-button-group=\"file-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-attach\" data-trix-action=\"attachFiles\" title=\"").concat(lang$1.attachFiles, "\" tabindex=\"-1\">").concat(lang$1.attachFiles, "</button>\n </span>\n\n <span class=\"trix-button-group-spacer\"></span>\n\n <span class=\"trix-button-group trix-button-group--history-tools\" data-trix-button-group=\"history-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-undo\" data-trix-action=\"undo\" data-trix-key=\"z\" title=\"").concat(lang$1.undo, "\" tabindex=\"-1\">").concat(lang$1.undo, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-redo\" data-trix-action=\"redo\" data-trix-key=\"shift+z\" title=\"").concat(lang$1.redo, "\" tabindex=\"-1\">").concat(lang$1.redo, "</button>\n </span>\n </div>\n\n <div class=\"trix-dialogs\" data-trix-dialogs>\n <div class=\"trix-dialog trix-dialog--link\" data-trix-dialog=\"href\" data-trix-dialog-attribute=\"href\">\n <div class=\"trix-dialog__link-fields\">\n <input type=\"url\" name=\"href\" class=\"trix-input trix-input--dialog\" placeholder=\"").concat(lang$1.urlPlaceholder, "\" aria-label=\"").concat(lang$1.url, "\" data-trix-validate-href required data-trix-input>\n <div class=\"trix-button-group\">\n <input type=\"button\" class=\"trix-button trix-button--dialog\" value=\"").concat(lang$1.link, "\" data-trix-method=\"setAttribute\">\n <input type=\"button\" class=\"trix-button trix-button--dialog\" value=\"").concat(lang$1.unlink, "\" data-trix-method=\"removeAttribute\">\n </div>\n </div>\n </div>\n </div>");
665 }
666 };
667
668 const undo = {
669 interval: 5000
670 };
671
672 var config = /*#__PURE__*/Object.freeze({
673 __proto__: null,
674 attachments: attachments,
675 blockAttributes: attributes,
676 browser: browser$1,
677 css: css$3,
678 dompurify: dompurify,
679 fileSize: file_size_formatting,
680 input: input,
681 keyNames: key_names,
682 lang: lang$1,
683 parser: parser,
684 textAttributes: text_attributes,
685 toolbar: toolbar,
686 undo: undo
687 });
688
689 class BasicObject {
690 static proxyMethod(expression) {
691 const {
692 name,
693 toMethod,
694 toProperty,
695 optional
696 } = parseProxyMethodExpression(expression);
697 this.prototype[name] = function () {
698 let subject;
699 let object;
700 if (toMethod) {
701 if (optional) {
702 var _this$toMethod;
703 object = (_this$toMethod = this[toMethod]) === null || _this$toMethod === void 0 ? void 0 : _this$toMethod.call(this);
704 } else {
705 object = this[toMethod]();
706 }
707 } else if (toProperty) {
708 object = this[toProperty];
709 }
710 if (optional) {
711 var _object;
712 subject = (_object = object) === null || _object === void 0 ? void 0 : _object[name];
713 if (subject) {
714 return apply$1.call(subject, object, arguments);
715 }
716 } else {
717 subject = object[name];
718 return apply$1.call(subject, object, arguments);
719 }
720 };
721 }
722 }
723 const parseProxyMethodExpression = function (expression) {
724 const match = expression.match(proxyMethodExpressionPattern);
725 if (!match) {
726 throw new Error("can't parse @proxyMethod expression: ".concat(expression));
727 }
728 const args = {
729 name: match[4]
730 };
731 if (match[2] != null) {
732 args.toMethod = match[1];
733 } else {
734 args.toProperty = match[1];
735 }
736 if (match[3] != null) {
737 args.optional = true;
738 }
739 return args;
740 };
741 const {
742 apply: apply$1
743 } = Function.prototype;
744 const proxyMethodExpressionPattern = new RegExp("\
745^\
746(.+?)\
747(\\(\\))?\
748(\\?)?\
749\\.\
750(.+?)\
751$\
752");
753
754 var _Array$from, _$codePointAt$1, _$1, _String$fromCodePoint;
755 class UTF16String extends BasicObject {
756 static box() {
757 let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
758 if (value instanceof this) {
759 return value;
760 } else {
761 return this.fromUCS2String(value === null || value === void 0 ? void 0 : value.toString());
762 }
763 }
764 static fromUCS2String(ucs2String) {
765 return new this(ucs2String, ucs2decode(ucs2String));
766 }
767 static fromCodepoints(codepoints) {
768 return new this(ucs2encode(codepoints), codepoints);
769 }
770 constructor(ucs2String, codepoints) {
771 super(...arguments);
772 this.ucs2String = ucs2String;
773 this.codepoints = codepoints;
774 this.length = this.codepoints.length;
775 this.ucs2Length = this.ucs2String.length;
776 }
777 offsetToUCS2Offset(offset) {
778 return ucs2encode(this.codepoints.slice(0, Math.max(0, offset))).length;
779 }
780 offsetFromUCS2Offset(ucs2Offset) {
781 return ucs2decode(this.ucs2String.slice(0, Math.max(0, ucs2Offset))).length;
782 }
783 slice() {
784 return this.constructor.fromCodepoints(this.codepoints.slice(...arguments));
785 }
786 charAt(offset) {
787 return this.slice(offset, offset + 1);
788 }
789 isEqualTo(value) {
790 return this.constructor.box(value).ucs2String === this.ucs2String;
791 }
792 toJSON() {
793 return this.ucs2String;
794 }
795 getCacheKey() {
796 return this.ucs2String;
797 }
798 toString() {
799 return this.ucs2String;
800 }
801 }
802 const hasArrayFrom = ((_Array$from = Array.from) === null || _Array$from === void 0 ? void 0 : _Array$from.call(Array, "\ud83d\udc7c").length) === 1;
803 const hasStringCodePointAt$1 = ((_$codePointAt$1 = (_$1 = " ").codePointAt) === null || _$codePointAt$1 === void 0 ? void 0 : _$codePointAt$1.call(_$1, 0)) != null;
804 const hasStringFromCodePoint = ((_String$fromCodePoint = String.fromCodePoint) === null || _String$fromCodePoint === void 0 ? void 0 : _String$fromCodePoint.call(String, 32, 128124)) === " \ud83d\udc7c";
805
806 // UCS-2 conversion helpers ported from Mathias Bynens' Punycode.js:
807 // https://github.com/bestiejs/punycode.js#punycodeucs2
808
809 let ucs2decode, ucs2encode;
810
811 // Creates an array containing the numeric code points of each Unicode
812 // character in the string. While JavaScript uses UCS-2 internally,
813 // this function will convert a pair of surrogate halves (each of which
814 // UCS-2 exposes as separate characters) into a single code point,
815 // matching UTF-16.
816 if (hasArrayFrom && hasStringCodePointAt$1) {
817 ucs2decode = string => Array.from(string).map(char => char.codePointAt(0));
818 } else {
819 ucs2decode = function (string) {
820 const output = [];
821 let counter = 0;
822 const {
823 length
824 } = string;
825 while (counter < length) {
826 let value = string.charCodeAt(counter++);
827 if (0xd800 <= value && value <= 0xdbff && counter < length) {
828 // high surrogate, and there is a next character
829 const extra = string.charCodeAt(counter++);
830 if ((extra & 0xfc00) === 0xdc00) {
831 // low surrogate
832 value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
833 } else {
834 // unmatched surrogate; only append this code unit, in case the
835 // next code unit is the high surrogate of a surrogate pair
836 counter--;
837 }
838 }
839 output.push(value);
840 }
841 return output;
842 };
843 }
844
845 // Creates a string based on an array of numeric code points.
846 if (hasStringFromCodePoint) {
847 ucs2encode = array => String.fromCodePoint(...Array.from(array || []));
848 } else {
849 ucs2encode = function (array) {
850 const characters = (() => {
851 const result = [];
852 Array.from(array).forEach(value => {
853 let output = "";
854 if (value > 0xffff) {
855 value -= 0x10000;
856 output += String.fromCharCode(value >>> 10 & 0x3ff | 0xd800);
857 value = 0xdc00 | value & 0x3ff;
858 }
859 result.push(output + String.fromCharCode(value));
860 });
861 return result;
862 })();
863 return characters.join("");
864 };
865 }
866
867 let id$2 = 0;
868 class TrixObject extends BasicObject {
869 static fromJSONString(jsonString) {
870 return this.fromJSON(JSON.parse(jsonString));
871 }
872 constructor() {
873 super(...arguments);
874 this.id = ++id$2;
875 }
876 hasSameConstructorAs(object) {
877 return this.constructor === (object === null || object === void 0 ? void 0 : object.constructor);
878 }
879 isEqualTo(object) {
880 return this === object;
881 }
882 inspect() {
883 const parts = [];
884 const contents = this.contentsForInspection() || {};
885 for (const key in contents) {
886 const value = contents[key];
887 parts.push("".concat(key, "=").concat(value));
888 }
889 return "#<".concat(this.constructor.name, ":").concat(this.id).concat(parts.length ? " ".concat(parts.join(", ")) : "", ">");
890 }
891 contentsForInspection() {}
892 toJSONString() {
893 return JSON.stringify(this);
894 }
895 toUTF16String() {
896 return UTF16String.box(this);
897 }
898 getCacheKey() {
899 return this.id.toString();
900 }
901 }
902
903 /* eslint-disable
904 id-length,
905 */
906 const arraysAreEqual = function () {
907 let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
908 let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
909 if (a.length !== b.length) {
910 return false;
911 }
912 for (let index = 0; index < a.length; index++) {
913 const value = a[index];
914 if (value !== b[index]) {
915 return false;
916 }
917 }
918 return true;
919 };
920 const arrayStartsWith = function () {
921 let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
922 let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
923 return arraysAreEqual(a.slice(0, b.length), b);
924 };
925 const spliceArray = function (array) {
926 const result = array.slice(0);
927 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
928 args[_key - 1] = arguments[_key];
929 }
930 result.splice(...args);
931 return result;
932 };
933 const summarizeArrayChange = function () {
934 let oldArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
935 let newArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
936 const added = [];
937 const removed = [];
938 const existingValues = new Set();
939 oldArray.forEach(value => {
940 existingValues.add(value);
941 });
942 const currentValues = new Set();
943 newArray.forEach(value => {
944 currentValues.add(value);
945 if (!existingValues.has(value)) {
946 added.push(value);
947 }
948 });
949 oldArray.forEach(value => {
950 if (!currentValues.has(value)) {
951 removed.push(value);
952 }
953 });
954 return {
955 added,
956 removed
957 };
958 };
959
960 // https://github.com/mathiasbynens/unicode-2.1.8/blob/master/Bidi_Class/Right_To_Left/regex.js
961 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]/;
962 const getDirection = function () {
963 const input = makeElement("input", {
964 dir: "auto",
965 name: "x",
966 dirName: "x.dir"
967 });
968 const textArea = makeElement("textarea", {
969 dir: "auto",
970 name: "y",
971 dirName: "y.dir"
972 });
973 const form = makeElement("form");
974 form.appendChild(input);
975 form.appendChild(textArea);
976 const supportsDirName = function () {
977 try {
978 return new FormData(form).has(textArea.dirName);
979 } catch (error) {
980 return false;
981 }
982 }();
983 const supportsDirSelector = function () {
984 try {
985 return input.matches(":dir(ltr),:dir(rtl)");
986 } catch (error) {
987 return false;
988 }
989 }();
990 if (supportsDirName) {
991 return function (string) {
992 textArea.value = string;
993 return new FormData(form).get(textArea.dirName);
994 };
995 } else if (supportsDirSelector) {
996 return function (string) {
997 input.value = string;
998 if (input.matches(":dir(rtl)")) {
999 return "rtl";
1000 } else {
1001 return "ltr";
1002 }
1003 };
1004 } else {
1005 return function (string) {
1006 const char = string.trim().charAt(0);
1007 if (RTL_PATTERN.test(char)) {
1008 return "rtl";
1009 } else {
1010 return "ltr";
1011 }
1012 };
1013 }
1014 }();
1015
1016 let allAttributeNames = null;
1017 let blockAttributeNames = null;
1018 let textAttributeNames = null;
1019 let listAttributeNames = null;
1020 const getAllAttributeNames = () => {
1021 if (!allAttributeNames) {
1022 allAttributeNames = getTextAttributeNames().concat(getBlockAttributeNames());
1023 }
1024 return allAttributeNames;
1025 };
1026 const getBlockConfig = attributeName => attributes[attributeName];
1027 const getBlockAttributeNames = () => {
1028 if (!blockAttributeNames) {
1029 blockAttributeNames = Object.keys(attributes);
1030 }
1031 return blockAttributeNames;
1032 };
1033 const getTextConfig = attributeName => text_attributes[attributeName];
1034 const getTextAttributeNames = () => {
1035 if (!textAttributeNames) {
1036 textAttributeNames = Object.keys(text_attributes);
1037 }
1038 return textAttributeNames;
1039 };
1040 const getListAttributeNames = () => {
1041 if (!listAttributeNames) {
1042 listAttributeNames = [];
1043 for (const key in attributes) {
1044 const {
1045 listAttribute
1046 } = attributes[key];
1047 if (listAttribute != null) {
1048 listAttributeNames.push(listAttribute);
1049 }
1050 }
1051 }
1052 return listAttributeNames;
1053 };
1054
1055 /* eslint-disable
1056 */
1057 const installDefaultCSSForTagName = function (tagName, defaultCSS) {
1058 const styleElement = insertStyleElementForTagName(tagName);
1059 styleElement.textContent = defaultCSS.replace(/%t/g, tagName);
1060 };
1061 const insertStyleElementForTagName = function (tagName) {
1062 const element = document.createElement("style");
1063 element.setAttribute("type", "text/css");
1064 element.setAttribute("data-tag-name", tagName.toLowerCase());
1065 const nonce = getCSPNonce();
1066 if (nonce) {
1067 element.setAttribute("nonce", nonce);
1068 }
1069 document.head.insertBefore(element, document.head.firstChild);
1070 return element;
1071 };
1072 const getCSPNonce = function () {
1073 const element = getMetaElement("trix-csp-nonce") || getMetaElement("csp-nonce");
1074 if (element) {
1075 const {
1076 nonce,
1077 content
1078 } = element;
1079 return nonce == "" ? content : nonce;
1080 }
1081 };
1082 const getMetaElement = name => document.head.querySelector("meta[name=".concat(name, "]"));
1083
1084 const testTransferData = {
1085 "application/x-trix-feature-detection": "test"
1086 };
1087 const dataTransferIsPlainText = function (dataTransfer) {
1088 const text = dataTransfer.getData("text/plain");
1089 const html = dataTransfer.getData("text/html");
1090 if (text && html) {
1091 const {
1092 body
1093 } = new DOMParser().parseFromString(html, "text/html");
1094 if (body.textContent === text) {
1095 return !body.querySelector("*");
1096 }
1097 } else {
1098 return text === null || text === void 0 ? void 0 : text.length;
1099 }
1100 };
1101 const dataTransferIsMsOfficePaste = _ref => {
1102 let {
1103 dataTransfer
1104 } = _ref;
1105 return dataTransfer.types.includes("Files") && dataTransfer.types.includes("text/html") && dataTransfer.getData("text/html").includes("urn:schemas-microsoft-com:office:office");
1106 };
1107 const dataTransferIsWritable = function (dataTransfer) {
1108 if (!(dataTransfer !== null && dataTransfer !== void 0 && dataTransfer.setData)) return false;
1109 for (const key in testTransferData) {
1110 const value = testTransferData[key];
1111 try {
1112 dataTransfer.setData(key, value);
1113 if (!dataTransfer.getData(key) === value) return false;
1114 } catch (error) {
1115 return false;
1116 }
1117 }
1118 return true;
1119 };
1120 const keyEventIsKeyboardCommand = function () {
1121 if (/Mac|^iP/.test(navigator.platform)) {
1122 return event => event.metaKey;
1123 } else {
1124 return event => event.ctrlKey;
1125 }
1126 }();
1127 function shouldRenderInmmediatelyToDealWithIOSDictation(inputEvent) {
1128 if (/iPhone|iPad/.test(navigator.userAgent)) {
1129 // Handle garbled content and duplicated newlines when using dictation on iOS 18+. Upon dictation completion, iOS sends
1130 // the list of insertText / insertParagraph events in a quick sequence. If we don't render
1131 // the editor synchronously, the internal range fails to update and results in garbled content or duplicated newlines.
1132 //
1133 // This workaround is necessary because iOS doesn't send composing events as expected while dictating:
1134 // https://bugs.webkit.org/show_bug.cgi?id=261764
1135 return !inputEvent.inputType || inputEvent.inputType === "insertParagraph";
1136 } else {
1137 return false;
1138 }
1139 }
1140
1141 const defer = fn => setTimeout(fn, 1);
1142
1143 /* eslint-disable
1144 id-length,
1145 */
1146 const copyObject = function () {
1147 let object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1148 const result = {};
1149 for (const key in object) {
1150 const value = object[key];
1151 result[key] = value;
1152 }
1153 return result;
1154 };
1155 const objectsAreEqual = function () {
1156 let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1157 let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1158 if (Object.keys(a).length !== Object.keys(b).length) {
1159 return false;
1160 }
1161 for (const key in a) {
1162 const value = a[key];
1163 if (value !== b[key]) {
1164 return false;
1165 }
1166 }
1167 return true;
1168 };
1169
1170 const normalizeRange = function (range) {
1171 if (range == null) return;
1172 if (!Array.isArray(range)) {
1173 range = [range, range];
1174 }
1175 return [copyValue(range[0]), copyValue(range[1] != null ? range[1] : range[0])];
1176 };
1177 const rangeIsCollapsed = function (range) {
1178 if (range == null) return;
1179 const [start, end] = normalizeRange(range);
1180 return rangeValuesAreEqual(start, end);
1181 };
1182 const rangesAreEqual = function (leftRange, rightRange) {
1183 if (leftRange == null || rightRange == null) return;
1184 const [leftStart, leftEnd] = normalizeRange(leftRange);
1185 const [rightStart, rightEnd] = normalizeRange(rightRange);
1186 return rangeValuesAreEqual(leftStart, rightStart) && rangeValuesAreEqual(leftEnd, rightEnd);
1187 };
1188 const copyValue = function (value) {
1189 if (typeof value === "number") {
1190 return value;
1191 } else {
1192 return copyObject(value);
1193 }
1194 };
1195 const rangeValuesAreEqual = function (left, right) {
1196 if (typeof left === "number") {
1197 return left === right;
1198 } else {
1199 return objectsAreEqual(left, right);
1200 }
1201 };
1202
1203 class SelectionChangeObserver extends BasicObject {
1204 constructor() {
1205 super(...arguments);
1206 this.update = this.update.bind(this);
1207 this.selectionManagers = [];
1208 }
1209 start() {
1210 if (!this.started) {
1211 this.started = true;
1212 document.addEventListener("selectionchange", this.update, true);
1213 }
1214 }
1215 stop() {
1216 if (this.started) {
1217 this.started = false;
1218 return document.removeEventListener("selectionchange", this.update, true);
1219 }
1220 }
1221 registerSelectionManager(selectionManager) {
1222 if (!this.selectionManagers.includes(selectionManager)) {
1223 this.selectionManagers.push(selectionManager);
1224 return this.start();
1225 }
1226 }
1227 unregisterSelectionManager(selectionManager) {
1228 this.selectionManagers = this.selectionManagers.filter(sm => sm !== selectionManager);
1229 if (this.selectionManagers.length === 0) {
1230 return this.stop();
1231 }
1232 }
1233 notifySelectionManagersOfSelectionChange() {
1234 return this.selectionManagers.map(selectionManager => selectionManager.selectionDidChange());
1235 }
1236 update() {
1237 this.notifySelectionManagersOfSelectionChange();
1238 }
1239 reset() {
1240 this.update();
1241 }
1242 }
1243 const selectionChangeObserver = new SelectionChangeObserver();
1244 const getDOMSelection = function () {
1245 const selection = window.getSelection();
1246 if (selection.rangeCount > 0) {
1247 return selection;
1248 }
1249 };
1250 const getDOMRange = function () {
1251 var _getDOMSelection;
1252 const domRange = (_getDOMSelection = getDOMSelection()) === null || _getDOMSelection === void 0 ? void 0 : _getDOMSelection.getRangeAt(0);
1253 if (domRange) {
1254 if (!domRangeIsPrivate(domRange)) {
1255 return domRange;
1256 }
1257 }
1258 };
1259 const setDOMRange = function (domRange) {
1260 const selection = window.getSelection();
1261 selection.removeAllRanges();
1262 selection.addRange(domRange);
1263 return selectionChangeObserver.update();
1264 };
1265
1266 // In Firefox, clicking certain <input> elements changes the selection to a
1267 // private element used to draw its UI. Attempting to access properties of those
1268 // elements throws an error.
1269 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
1270 const domRangeIsPrivate = domRange => nodeIsPrivate(domRange.startContainer) || nodeIsPrivate(domRange.endContainer);
1271 const nodeIsPrivate = node => !Object.getPrototypeOf(node);
1272
1273 /* eslint-disable
1274 id-length,
1275 no-useless-escape,
1276 */
1277 const normalizeSpaces = string => string.replace(new RegExp("".concat(ZERO_WIDTH_SPACE), "g"), "").replace(new RegExp("".concat(NON_BREAKING_SPACE), "g"), " ");
1278 const normalizeNewlines = string => string.replace(/\r\n?/g, "\n");
1279 const breakableWhitespacePattern = new RegExp("[^\\S".concat(NON_BREAKING_SPACE, "]"));
1280 const squishBreakableWhitespace = string => string
1281 // Replace all breakable whitespace characters with a space
1282 .replace(new RegExp("".concat(breakableWhitespacePattern.source), "g"), " ")
1283 // Replace two or more spaces with a single space
1284 .replace(/\ {2,}/g, " ");
1285 const summarizeStringChange = function (oldString, newString) {
1286 let added, removed;
1287 oldString = UTF16String.box(oldString);
1288 newString = UTF16String.box(newString);
1289 if (newString.length < oldString.length) {
1290 [removed, added] = utf16StringDifferences(oldString, newString);
1291 } else {
1292 [added, removed] = utf16StringDifferences(newString, oldString);
1293 }
1294 return {
1295 added,
1296 removed
1297 };
1298 };
1299 const utf16StringDifferences = function (a, b) {
1300 if (a.isEqualTo(b)) {
1301 return ["", ""];
1302 }
1303 const diffA = utf16StringDifference(a, b);
1304 const {
1305 length
1306 } = diffA.utf16String;
1307 let diffB;
1308 if (length) {
1309 const {
1310 offset
1311 } = diffA;
1312 const codepoints = a.codepoints.slice(0, offset).concat(a.codepoints.slice(offset + length));
1313 diffB = utf16StringDifference(b, UTF16String.fromCodepoints(codepoints));
1314 } else {
1315 diffB = utf16StringDifference(b, a);
1316 }
1317 return [diffA.utf16String.toString(), diffB.utf16String.toString()];
1318 };
1319 const utf16StringDifference = function (a, b) {
1320 let leftIndex = 0;
1321 let rightIndexA = a.length;
1322 let rightIndexB = b.length;
1323 while (leftIndex < rightIndexA && a.charAt(leftIndex).isEqualTo(b.charAt(leftIndex))) {
1324 leftIndex++;
1325 }
1326 while (rightIndexA > leftIndex + 1 && a.charAt(rightIndexA - 1).isEqualTo(b.charAt(rightIndexB - 1))) {
1327 rightIndexA--;
1328 rightIndexB--;
1329 }
1330 return {
1331 utf16String: a.slice(leftIndex, rightIndexA),
1332 offset: leftIndex
1333 };
1334 };
1335
1336 class Hash extends TrixObject {
1337 static fromCommonAttributesOfObjects() {
1338 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1339 if (!objects.length) {
1340 return new this();
1341 }
1342 let hash = box(objects[0]);
1343 let keys = hash.getKeys();
1344 objects.slice(1).forEach(object => {
1345 keys = hash.getKeysCommonToHash(box(object));
1346 hash = hash.slice(keys);
1347 });
1348 return hash;
1349 }
1350 static box(values) {
1351 return box(values);
1352 }
1353 constructor() {
1354 let values = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1355 super(...arguments);
1356 this.values = copy(values);
1357 }
1358 add(key, value) {
1359 return this.merge(object(key, value));
1360 }
1361 remove(key) {
1362 return new Hash(copy(this.values, key));
1363 }
1364 get(key) {
1365 return this.values[key];
1366 }
1367 has(key) {
1368 return key in this.values;
1369 }
1370 merge(values) {
1371 return new Hash(merge(this.values, unbox(values)));
1372 }
1373 slice(keys) {
1374 const values = {};
1375 Array.from(keys).forEach(key => {
1376 if (this.has(key)) {
1377 values[key] = this.values[key];
1378 }
1379 });
1380 return new Hash(values);
1381 }
1382 getKeys() {
1383 return Object.keys(this.values);
1384 }
1385 getKeysCommonToHash(hash) {
1386 hash = box(hash);
1387 return this.getKeys().filter(key => this.values[key] === hash.values[key]);
1388 }
1389 isEqualTo(values) {
1390 return arraysAreEqual(this.toArray(), box(values).toArray());
1391 }
1392 isEmpty() {
1393 return this.getKeys().length === 0;
1394 }
1395 toArray() {
1396 if (!this.array) {
1397 const result = [];
1398 for (const key in this.values) {
1399 const value = this.values[key];
1400 result.push(result.push(key, value));
1401 }
1402 this.array = result.slice(0);
1403 }
1404 return this.array;
1405 }
1406 toObject() {
1407 return copy(this.values);
1408 }
1409 toJSON() {
1410 return this.toObject();
1411 }
1412 contentsForInspection() {
1413 return {
1414 values: JSON.stringify(this.values)
1415 };
1416 }
1417 }
1418 const object = function (key, value) {
1419 const result = {};
1420 result[key] = value;
1421 return result;
1422 };
1423 const merge = function (object, values) {
1424 const result = copy(object);
1425 for (const key in values) {
1426 const value = values[key];
1427 result[key] = value;
1428 }
1429 return result;
1430 };
1431 const copy = function (object, keyToRemove) {
1432 const result = {};
1433 const sortedKeys = Object.keys(object).sort();
1434 sortedKeys.forEach(key => {
1435 if (key !== keyToRemove) {
1436 result[key] = object[key];
1437 }
1438 });
1439 return result;
1440 };
1441 const box = function (object) {
1442 if (object instanceof Hash) {
1443 return object;
1444 } else {
1445 return new Hash(object);
1446 }
1447 };
1448 const unbox = function (object) {
1449 if (object instanceof Hash) {
1450 return object.values;
1451 } else {
1452 return object;
1453 }
1454 };
1455
1456 class ObjectGroup {
1457 static groupObjects() {
1458 let ungroupedObjects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1459 let {
1460 depth,
1461 asTree
1462 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1463 let group;
1464 if (asTree) {
1465 if (depth == null) {
1466 depth = 0;
1467 }
1468 }
1469 const objects = [];
1470 Array.from(ungroupedObjects).forEach(object => {
1471 var _object$canBeGrouped2;
1472 if (group) {
1473 var _object$canBeGrouped, _group$canBeGroupedWi, _group;
1474 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)) {
1475 group.push(object);
1476 return;
1477 } else {
1478 objects.push(new this(group, {
1479 depth,
1480 asTree
1481 }));
1482 group = null;
1483 }
1484 }
1485 if ((_object$canBeGrouped2 = object.canBeGrouped) !== null && _object$canBeGrouped2 !== void 0 && _object$canBeGrouped2.call(object, depth)) {
1486 group = [object];
1487 } else {
1488 objects.push(object);
1489 }
1490 });
1491 if (group) {
1492 objects.push(new this(group, {
1493 depth,
1494 asTree
1495 }));
1496 }
1497 return objects;
1498 }
1499 constructor() {
1500 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1501 let {
1502 depth,
1503 asTree
1504 } = arguments.length > 1 ? arguments[1] : undefined;
1505 this.objects = objects;
1506 if (asTree) {
1507 this.depth = depth;
1508 this.objects = this.constructor.groupObjects(this.objects, {
1509 asTree,
1510 depth: this.depth + 1
1511 });
1512 }
1513 }
1514 getObjects() {
1515 return this.objects;
1516 }
1517 getDepth() {
1518 return this.depth;
1519 }
1520 getCacheKey() {
1521 const keys = ["objectGroup"];
1522 Array.from(this.getObjects()).forEach(object => {
1523 keys.push(object.getCacheKey());
1524 });
1525 return keys.join("/");
1526 }
1527 }
1528
1529 class ObjectMap extends BasicObject {
1530 constructor() {
1531 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1532 super(...arguments);
1533 this.objects = {};
1534 Array.from(objects).forEach(object => {
1535 const hash = JSON.stringify(object);
1536 if (this.objects[hash] == null) {
1537 this.objects[hash] = object;
1538 }
1539 });
1540 }
1541 find(object) {
1542 const hash = JSON.stringify(object);
1543 return this.objects[hash];
1544 }
1545 }
1546
1547 class ElementStore {
1548 constructor(elements) {
1549 this.reset(elements);
1550 }
1551 add(element) {
1552 const key = getKey(element);
1553 this.elements[key] = element;
1554 }
1555 remove(element) {
1556 const key = getKey(element);
1557 const value = this.elements[key];
1558 if (value) {
1559 delete this.elements[key];
1560 return value;
1561 }
1562 }
1563 reset() {
1564 let elements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1565 this.elements = {};
1566 Array.from(elements).forEach(element => {
1567 this.add(element);
1568 });
1569 return elements;
1570 }
1571 }
1572 const getKey = element => element.dataset.trixStoreKey;
1573
1574 class Operation extends BasicObject {
1575 isPerforming() {
1576 return this.performing === true;
1577 }
1578 hasPerformed() {
1579 return this.performed === true;
1580 }
1581 hasSucceeded() {
1582 return this.performed && this.succeeded;
1583 }
1584 hasFailed() {
1585 return this.performed && !this.succeeded;
1586 }
1587 getPromise() {
1588 if (!this.promise) {
1589 this.promise = new Promise((resolve, reject) => {
1590 this.performing = true;
1591 return this.perform((succeeded, result) => {
1592 this.succeeded = succeeded;
1593 this.performing = false;
1594 this.performed = true;
1595 if (this.succeeded) {
1596 resolve(result);
1597 } else {
1598 reject(result);
1599 }
1600 });
1601 });
1602 }
1603 return this.promise;
1604 }
1605 perform(callback) {
1606 return callback(false);
1607 }
1608 release() {
1609 var _this$promise, _this$promise$cancel;
1610 (_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);
1611 this.promise = null;
1612 this.performing = null;
1613 this.performed = null;
1614 this.succeeded = null;
1615 }
1616 }
1617 Operation.proxyMethod("getPromise().then");
1618 Operation.proxyMethod("getPromise().catch");
1619
1620 class ObjectView extends BasicObject {
1621 constructor(object) {
1622 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1623 super(...arguments);
1624 this.object = object;
1625 this.options = options;
1626 this.childViews = [];
1627 this.rootView = this;
1628 }
1629 getNodes() {
1630 if (!this.nodes) {
1631 this.nodes = this.createNodes();
1632 }
1633 return this.nodes.map(node => node.cloneNode(true));
1634 }
1635 invalidate() {
1636 var _this$parentView;
1637 this.nodes = null;
1638 this.childViews = [];
1639 return (_this$parentView = this.parentView) === null || _this$parentView === void 0 ? void 0 : _this$parentView.invalidate();
1640 }
1641 invalidateViewForObject(object) {
1642 var _this$findViewForObje;
1643 return (_this$findViewForObje = this.findViewForObject(object)) === null || _this$findViewForObje === void 0 ? void 0 : _this$findViewForObje.invalidate();
1644 }
1645 findOrCreateCachedChildView(viewClass, object, options) {
1646 let view = this.getCachedViewForObject(object);
1647 if (view) {
1648 this.recordChildView(view);
1649 } else {
1650 view = this.createChildView(...arguments);
1651 this.cacheViewForObject(view, object);
1652 }
1653 return view;
1654 }
1655 createChildView(viewClass, object) {
1656 let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1657 if (object instanceof ObjectGroup) {
1658 options.viewClass = viewClass;
1659 viewClass = ObjectGroupView;
1660 }
1661 const view = new viewClass(object, options);
1662 return this.recordChildView(view);
1663 }
1664 recordChildView(view) {
1665 view.parentView = this;
1666 view.rootView = this.rootView;
1667 this.childViews.push(view);
1668 return view;
1669 }
1670 getAllChildViews() {
1671 let views = [];
1672 this.childViews.forEach(childView => {
1673 views.push(childView);
1674 views = views.concat(childView.getAllChildViews());
1675 });
1676 return views;
1677 }
1678 findElement() {
1679 return this.findElementForObject(this.object);
1680 }
1681 findElementForObject(object) {
1682 const id = object === null || object === void 0 ? void 0 : object.id;
1683 if (id) {
1684 return this.rootView.element.querySelector("[data-trix-id='".concat(id, "']"));
1685 }
1686 }
1687 findViewForObject(object) {
1688 for (const view of this.getAllChildViews()) {
1689 if (view.object === object) {
1690 return view;
1691 }
1692 }
1693 }
1694 getViewCache() {
1695 if (this.rootView === this) {
1696 if (this.isViewCachingEnabled()) {
1697 if (!this.viewCache) {
1698 this.viewCache = {};
1699 }
1700 return this.viewCache;
1701 }
1702 } else {
1703 return this.rootView.getViewCache();
1704 }
1705 }
1706 isViewCachingEnabled() {
1707 return this.shouldCacheViews !== false;
1708 }
1709 enableViewCaching() {
1710 this.shouldCacheViews = true;
1711 }
1712 disableViewCaching() {
1713 this.shouldCacheViews = false;
1714 }
1715 getCachedViewForObject(object) {
1716 var _this$getViewCache;
1717 return (_this$getViewCache = this.getViewCache()) === null || _this$getViewCache === void 0 ? void 0 : _this$getViewCache[object.getCacheKey()];
1718 }
1719 cacheViewForObject(view, object) {
1720 const cache = this.getViewCache();
1721 if (cache) {
1722 cache[object.getCacheKey()] = view;
1723 }
1724 }
1725 garbageCollectCachedViews() {
1726 const cache = this.getViewCache();
1727 if (cache) {
1728 const views = this.getAllChildViews().concat(this);
1729 const objectKeys = views.map(view => view.object.getCacheKey());
1730 for (const key in cache) {
1731 if (!objectKeys.includes(key)) {
1732 delete cache[key];
1733 }
1734 }
1735 }
1736 }
1737 }
1738 class ObjectGroupView extends ObjectView {
1739 constructor() {
1740 super(...arguments);
1741 this.objectGroup = this.object;
1742 this.viewClass = this.options.viewClass;
1743 delete this.options.viewClass;
1744 }
1745 getChildViews() {
1746 if (!this.childViews.length) {
1747 Array.from(this.objectGroup.getObjects()).forEach(object => {
1748 this.findOrCreateCachedChildView(this.viewClass, object, this.options);
1749 });
1750 }
1751 return this.childViews;
1752 }
1753 createNodes() {
1754 const element = this.createContainerElement();
1755 this.getChildViews().forEach(view => {
1756 Array.from(view.getNodes()).forEach(node => {
1757 element.appendChild(node);
1758 });
1759 });
1760 return [element];
1761 }
1762 createContainerElement() {
1763 let depth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.objectGroup.getDepth();
1764 return this.getChildViews()[0].createContainerElement(depth);
1765 }
1766 }
1767
1768 /*! @license DOMPurify 3.4.2 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.2/LICENSE */
1769
1770 const {
1771 entries,
1772 setPrototypeOf,
1773 isFrozen,
1774 getPrototypeOf,
1775 getOwnPropertyDescriptor
1776 } = Object;
1777 let {
1778 freeze,
1779 seal,
1780 create
1781 } = Object; // eslint-disable-line import/no-mutable-exports
1782 let {
1783 apply,
1784 construct
1785 } = typeof Reflect !== 'undefined' && Reflect;
1786 if (!freeze) {
1787 freeze = function freeze(x) {
1788 return x;
1789 };
1790 }
1791 if (!seal) {
1792 seal = function seal(x) {
1793 return x;
1794 };
1795 }
1796 if (!apply) {
1797 apply = function apply(func, thisArg) {
1798 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
1799 args[_key - 2] = arguments[_key];
1800 }
1801 return func.apply(thisArg, args);
1802 };
1803 }
1804 if (!construct) {
1805 construct = function construct(Func) {
1806 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
1807 args[_key2 - 1] = arguments[_key2];
1808 }
1809 return new Func(...args);
1810 };
1811 }
1812 const arrayForEach = unapply(Array.prototype.forEach);
1813 const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
1814 const arrayPop = unapply(Array.prototype.pop);
1815 const arrayPush = unapply(Array.prototype.push);
1816 const arraySplice = unapply(Array.prototype.splice);
1817 const arrayIsArray = Array.isArray;
1818 const stringToLowerCase = unapply(String.prototype.toLowerCase);
1819 const stringToString = unapply(String.prototype.toString);
1820 const stringMatch = unapply(String.prototype.match);
1821 const stringReplace = unapply(String.prototype.replace);
1822 const stringIndexOf = unapply(String.prototype.indexOf);
1823 const stringTrim = unapply(String.prototype.trim);
1824 const numberToString = unapply(Number.prototype.toString);
1825 const booleanToString = unapply(Boolean.prototype.toString);
1826 const bigintToString = typeof BigInt === 'undefined' ? null : unapply(BigInt.prototype.toString);
1827 const symbolToString = typeof Symbol === 'undefined' ? null : unapply(Symbol.prototype.toString);
1828 const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
1829 const objectToString = unapply(Object.prototype.toString);
1830 const regExpTest = unapply(RegExp.prototype.test);
1831 const typeErrorCreate = unconstruct(TypeError);
1832 /**
1833 * Creates a new function that calls the given function with a specified thisArg and arguments.
1834 *
1835 * @param func - The function to be wrapped and called.
1836 * @returns A new function that calls the given function with a specified thisArg and arguments.
1837 */
1838 function unapply(func) {
1839 return function (thisArg) {
1840 if (thisArg instanceof RegExp) {
1841 thisArg.lastIndex = 0;
1842 }
1843 for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
1844 args[_key3 - 1] = arguments[_key3];
1845 }
1846 return apply(func, thisArg, args);
1847 };
1848 }
1849 /**
1850 * Creates a new function that constructs an instance of the given constructor function with the provided arguments.
1851 *
1852 * @param func - The constructor function to be wrapped and called.
1853 * @returns A new function that constructs an instance of the given constructor function with the provided arguments.
1854 */
1855 function unconstruct(Func) {
1856 return function () {
1857 for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
1858 args[_key4] = arguments[_key4];
1859 }
1860 return construct(Func, args);
1861 };
1862 }
1863 /**
1864 * Add properties to a lookup table
1865 *
1866 * @param set - The set to which elements will be added.
1867 * @param array - The array containing elements to be added to the set.
1868 * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.
1869 * @returns The modified set with added elements.
1870 */
1871 function addToSet(set, array) {
1872 let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
1873 if (setPrototypeOf) {
1874 // Make 'in' and truthy checks like Boolean(set.constructor)
1875 // independent of any properties defined on Object.prototype.
1876 // Prevent prototype setters from intercepting set as a this value.
1877 setPrototypeOf(set, null);
1878 }
1879 if (!arrayIsArray(array)) {
1880 return set;
1881 }
1882 let l = array.length;
1883 while (l--) {
1884 let element = array[l];
1885 if (typeof element === 'string') {
1886 const lcElement = transformCaseFunc(element);
1887 if (lcElement !== element) {
1888 // Config presets (e.g. tags.js, attrs.js) are immutable.
1889 if (!isFrozen(array)) {
1890 array[l] = lcElement;
1891 }
1892 element = lcElement;
1893 }
1894 }
1895 set[element] = true;
1896 }
1897 return set;
1898 }
1899 /**
1900 * Clean up an array to harden against CSPP
1901 *
1902 * @param array - The array to be cleaned.
1903 * @returns The cleaned version of the array
1904 */
1905 function cleanArray(array) {
1906 for (let index = 0; index < array.length; index++) {
1907 const isPropertyExist = objectHasOwnProperty(array, index);
1908 if (!isPropertyExist) {
1909 array[index] = null;
1910 }
1911 }
1912 return array;
1913 }
1914 /**
1915 * Shallow clone an object
1916 *
1917 * @param object - The object to be cloned.
1918 * @returns A new object that copies the original.
1919 */
1920 function clone(object) {
1921 const newObject = create(null);
1922 for (const [property, value] of entries(object)) {
1923 const isPropertyExist = objectHasOwnProperty(object, property);
1924 if (isPropertyExist) {
1925 if (arrayIsArray(value)) {
1926 newObject[property] = cleanArray(value);
1927 } else if (value && typeof value === 'object' && value.constructor === Object) {
1928 newObject[property] = clone(value);
1929 } else {
1930 newObject[property] = value;
1931 }
1932 }
1933 }
1934 return newObject;
1935 }
1936 /**
1937 * Convert non-node values into strings without depending on direct property access.
1938 *
1939 * @param value - The value to stringify.
1940 * @returns A string representation of the provided value.
1941 */
1942 function stringifyValue(value) {
1943 switch (typeof value) {
1944 case 'string':
1945 {
1946 return value;
1947 }
1948 case 'number':
1949 {
1950 return numberToString(value);
1951 }
1952 case 'boolean':
1953 {
1954 return booleanToString(value);
1955 }
1956 case 'bigint':
1957 {
1958 return bigintToString ? bigintToString(value) : '0';
1959 }
1960 case 'symbol':
1961 {
1962 return symbolToString ? symbolToString(value) : 'Symbol()';
1963 }
1964 case 'undefined':
1965 {
1966 return objectToString(value);
1967 }
1968 case 'function':
1969 case 'object':
1970 {
1971 if (value === null) {
1972 return objectToString(value);
1973 }
1974 const valueAsRecord = value;
1975 const valueToString = lookupGetter(valueAsRecord, 'toString');
1976 if (typeof valueToString === 'function') {
1977 const stringified = valueToString(valueAsRecord);
1978 return typeof stringified === 'string' ? stringified : objectToString(stringified);
1979 }
1980 return objectToString(value);
1981 }
1982 default:
1983 {
1984 return objectToString(value);
1985 }
1986 }
1987 }
1988 /**
1989 * This method automatically checks if the prop is function or getter and behaves accordingly.
1990 *
1991 * @param object - The object to look up the getter function in its prototype chain.
1992 * @param prop - The property name for which to find the getter function.
1993 * @returns The getter function found in the prototype chain or a fallback function.
1994 */
1995 function lookupGetter(object, prop) {
1996 while (object !== null) {
1997 const desc = getOwnPropertyDescriptor(object, prop);
1998 if (desc) {
1999 if (desc.get) {
2000 return unapply(desc.get);
2001 }
2002 if (typeof desc.value === 'function') {
2003 return unapply(desc.value);
2004 }
2005 }
2006 object = getPrototypeOf(object);
2007 }
2008 function fallbackValue() {
2009 return null;
2010 }
2011 return fallbackValue;
2012 }
2013 function isRegex(value) {
2014 try {
2015 regExpTest(value, '');
2016 return true;
2017 } catch (_unused) {
2018 return false;
2019 }
2020 }
2021 const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
2022 const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
2023 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']);
2024 // List of SVG elements that are disallowed by default.
2025 // We still need to know them so that we can do namespace
2026 // checks properly in case one wants to add them to
2027 // allow-list.
2028 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']);
2029 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']);
2030 // Similarly to SVG, we want to know all MathML elements,
2031 // even those that we disallow by default.
2032 const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
2033 const text = freeze(['#text']);
2034 const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns']);
2035 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', 'mask-type', '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']);
2036 const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnalign', 'columnlines', 'columnspacing', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lquote', 'lspace', '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']);
2037 const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
2038
2039 // eslint-disable-next-line unicorn/better-regex
2040 const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
2041 const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
2042 const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex
2043 const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
2044 const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
2045 const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
2046 );
2047 const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
2048 const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
2049 );
2050 const DOCTYPE_NAME = seal(/^html$/i);
2051 const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
2052 var EXPRESSIONS = /*#__PURE__*/Object.freeze({
2053 __proto__: null,
2054 ARIA_ATTR: ARIA_ATTR,
2055 ATTR_WHITESPACE: ATTR_WHITESPACE,
2056 CUSTOM_ELEMENT: CUSTOM_ELEMENT,
2057 DATA_ATTR: DATA_ATTR,
2058 DOCTYPE_NAME: DOCTYPE_NAME,
2059 ERB_EXPR: ERB_EXPR,
2060 IS_ALLOWED_URI: IS_ALLOWED_URI,
2061 IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
2062 MUSTACHE_EXPR: MUSTACHE_EXPR,
2063 TMPLIT_EXPR: TMPLIT_EXPR
2064 });
2065
2066 /* eslint-disable @typescript-eslint/indent */
2067 // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
2068 const NODE_TYPE = {
2069 element: 1,
2070 text: 3,
2071 // Deprecated
2072 progressingInstruction: 7,
2073 comment: 8,
2074 document: 9
2075 };
2076 const getGlobal = function getGlobal() {
2077 return typeof window === 'undefined' ? null : window;
2078 };
2079 /**
2080 * Creates a no-op policy for internal use only.
2081 * Don't export this function outside this module!
2082 * @param trustedTypes The policy factory.
2083 * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).
2084 * @return The policy created (or null, if Trusted Types
2085 * are not supported or creating the policy failed).
2086 */
2087 const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
2088 if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
2089 return null;
2090 }
2091 // Allow the callers to control the unique policy name
2092 // by adding a data-tt-policy-suffix to the script element with the DOMPurify.
2093 // Policy creation with duplicate names throws in Trusted Types.
2094 let suffix = null;
2095 const ATTR_NAME = 'data-tt-policy-suffix';
2096 if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
2097 suffix = purifyHostElement.getAttribute(ATTR_NAME);
2098 }
2099 const policyName = 'dompurify' + (suffix ? '#' + suffix : '');
2100 try {
2101 return trustedTypes.createPolicy(policyName, {
2102 createHTML(html) {
2103 return html;
2104 },
2105 createScriptURL(scriptUrl) {
2106 return scriptUrl;
2107 }
2108 });
2109 } catch (_) {
2110 // Policy creation failed (most likely another DOMPurify script has
2111 // already run). Skip creating the policy, as this will only cause errors
2112 // if TT are enforced.
2113 console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
2114 return null;
2115 }
2116 };
2117 const _createHooksMap = function _createHooksMap() {
2118 return {
2119 afterSanitizeAttributes: [],
2120 afterSanitizeElements: [],
2121 afterSanitizeShadowDOM: [],
2122 beforeSanitizeAttributes: [],
2123 beforeSanitizeElements: [],
2124 beforeSanitizeShadowDOM: [],
2125 uponSanitizeAttribute: [],
2126 uponSanitizeElement: [],
2127 uponSanitizeShadowNode: []
2128 };
2129 };
2130 function createDOMPurify() {
2131 let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
2132 const DOMPurify = root => createDOMPurify(root);
2133 DOMPurify.version = '3.4.2';
2134 DOMPurify.removed = [];
2135 if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
2136 // Not running in a browser, provide a factory function
2137 // so that you can pass your own Window
2138 DOMPurify.isSupported = false;
2139 return DOMPurify;
2140 }
2141 let {
2142 document
2143 } = window;
2144 const originalDocument = document;
2145 const currentScript = originalDocument.currentScript;
2146 const {
2147 DocumentFragment,
2148 HTMLTemplateElement,
2149 Node,
2150 Element,
2151 NodeFilter,
2152 NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,
2153 HTMLFormElement,
2154 DOMParser,
2155 trustedTypes
2156 } = window;
2157 const ElementPrototype = Element.prototype;
2158 const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
2159 const remove = lookupGetter(ElementPrototype, 'remove');
2160 const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
2161 const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
2162 const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
2163 // As per issue #47, the web-components registry is inherited by a
2164 // new document created via createHTMLDocument. As per the spec
2165 // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
2166 // a new empty registry is used when creating a template contents owner
2167 // document, so we use that as our parent document to ensure nothing
2168 // is inherited.
2169 if (typeof HTMLTemplateElement === 'function') {
2170 const template = document.createElement('template');
2171 if (template.content && template.content.ownerDocument) {
2172 document = template.content.ownerDocument;
2173 }
2174 }
2175 let trustedTypesPolicy;
2176 let emptyHTML = '';
2177 const {
2178 implementation,
2179 createNodeIterator,
2180 createDocumentFragment,
2181 getElementsByTagName
2182 } = document;
2183 const {
2184 importNode
2185 } = originalDocument;
2186 let hooks = _createHooksMap();
2187 /**
2188 * Expose whether this browser supports running the full DOMPurify.
2189 */
2190 DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
2191 const {
2192 MUSTACHE_EXPR,
2193 ERB_EXPR,
2194 TMPLIT_EXPR,
2195 DATA_ATTR,
2196 ARIA_ATTR,
2197 IS_SCRIPT_OR_DATA,
2198 ATTR_WHITESPACE,
2199 CUSTOM_ELEMENT
2200 } = EXPRESSIONS;
2201 let {
2202 IS_ALLOWED_URI: IS_ALLOWED_URI$1
2203 } = EXPRESSIONS;
2204 /**
2205 * We consider the elements and attributes below to be safe. Ideally
2206 * don't add any new ones but feel free to remove unwanted ones.
2207 */
2208 /* allowed element names */
2209 let ALLOWED_TAGS = null;
2210 const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
2211 /* Allowed attribute names */
2212 let ALLOWED_ATTR = null;
2213 const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
2214 /*
2215 * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.
2216 * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
2217 * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
2218 * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
2219 */
2220 let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
2221 tagNameCheck: {
2222 writable: true,
2223 configurable: false,
2224 enumerable: true,
2225 value: null
2226 },
2227 attributeNameCheck: {
2228 writable: true,
2229 configurable: false,
2230 enumerable: true,
2231 value: null
2232 },
2233 allowCustomizedBuiltInElements: {
2234 writable: true,
2235 configurable: false,
2236 enumerable: true,
2237 value: false
2238 }
2239 }));
2240 /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
2241 let FORBID_TAGS = null;
2242 /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
2243 let FORBID_ATTR = null;
2244 /* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */
2245 const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
2246 tagCheck: {
2247 writable: true,
2248 configurable: false,
2249 enumerable: true,
2250 value: null
2251 },
2252 attributeCheck: {
2253 writable: true,
2254 configurable: false,
2255 enumerable: true,
2256 value: null
2257 }
2258 }));
2259 /* Decide if ARIA attributes are okay */
2260 let ALLOW_ARIA_ATTR = true;
2261 /* Decide if custom data attributes are okay */
2262 let ALLOW_DATA_ATTR = true;
2263 /* Decide if unknown protocols are okay */
2264 let ALLOW_UNKNOWN_PROTOCOLS = false;
2265 /* Decide if self-closing tags in attributes are allowed.
2266 * Usually removed due to a mXSS issue in jQuery 3.0 */
2267 let ALLOW_SELF_CLOSE_IN_ATTR = true;
2268 /* Output should be safe for common template engines.
2269 * This means, DOMPurify removes data attributes, mustaches and ERB
2270 */
2271 let SAFE_FOR_TEMPLATES = false;
2272 /* Output should be safe even for XML used within HTML and alike.
2273 * This means, DOMPurify removes comments when containing risky content.
2274 */
2275 let SAFE_FOR_XML = true;
2276 /* Decide if document with <html>... should be returned */
2277 let WHOLE_DOCUMENT = false;
2278 /* Track whether config is already set on this instance of DOMPurify. */
2279 let SET_CONFIG = false;
2280 /* Decide if all elements (e.g. style, script) must be children of
2281 * document.body. By default, browsers might move them to document.head */
2282 let FORCE_BODY = false;
2283 /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
2284 * string (or a TrustedHTML object if Trusted Types are supported).
2285 * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
2286 */
2287 let RETURN_DOM = false;
2288 /* Decide if a DOM `DocumentFragment` should be returned, instead of a html
2289 * string (or a TrustedHTML object if Trusted Types are supported) */
2290 let RETURN_DOM_FRAGMENT = false;
2291 /* Try to return a Trusted Type object instead of a string, return a string in
2292 * case Trusted Types are not supported */
2293 let RETURN_TRUSTED_TYPE = false;
2294 /* Output should be free from DOM clobbering attacks?
2295 * This sanitizes markups named with colliding, clobberable built-in DOM APIs.
2296 */
2297 let SANITIZE_DOM = true;
2298 /* Achieve full DOM Clobbering protection by isolating the namespace of named
2299 * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
2300 *
2301 * HTML/DOM spec rules that enable DOM Clobbering:
2302 * - Named Access on Window (§7.3.3)
2303 * - DOM Tree Accessors (§3.1.5)
2304 * - Form Element Parent-Child Relations (§4.10.3)
2305 * - Iframe srcdoc / Nested WindowProxies (§4.8.5)
2306 * - HTMLCollection (§4.2.10.2)
2307 *
2308 * Namespace isolation is implemented by prefixing `id` and `name` attributes
2309 * with a constant string, i.e., `user-content-`
2310 */
2311 let SANITIZE_NAMED_PROPS = false;
2312 const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
2313 /* Keep element content when removing element? */
2314 let KEEP_CONTENT = true;
2315 /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
2316 * of importing it into a new Document and returning a sanitized copy */
2317 let IN_PLACE = false;
2318 /* Allow usage of profiles like html, svg and mathMl */
2319 let USE_PROFILES = {};
2320 /* Tags to ignore content of when KEEP_CONTENT is true */
2321 let FORBID_CONTENTS = null;
2322 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']);
2323 /* Tags that are safe for data: URIs */
2324 let DATA_URI_TAGS = null;
2325 const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
2326 /* Attributes safe for values like "javascript:" */
2327 let URI_SAFE_ATTRIBUTES = null;
2328 const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
2329 const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
2330 const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
2331 const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
2332 /* Document namespace */
2333 let NAMESPACE = HTML_NAMESPACE;
2334 let IS_EMPTY_INPUT = false;
2335 /* Allowed XHTML+XML namespaces */
2336 let ALLOWED_NAMESPACES = null;
2337 const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
2338 let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
2339 let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);
2340 // Certain elements are allowed in both SVG and HTML
2341 // namespace. We need to specify them explicitly
2342 // so that they don't get erroneously deleted from
2343 // HTML namespace.
2344 const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
2345 /* Parsing of strict XHTML documents */
2346 let PARSER_MEDIA_TYPE = null;
2347 const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
2348 const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
2349 let transformCaseFunc = null;
2350 /* Keep a reference to config to pass to hooks */
2351 let CONFIG = null;
2352 /* Ideally, do not touch anything below this line */
2353 /* ______________________________________________ */
2354 const formElement = document.createElement('form');
2355 const isRegexOrFunction = function isRegexOrFunction(testValue) {
2356 return testValue instanceof RegExp || testValue instanceof Function;
2357 };
2358 /**
2359 * _parseConfig
2360 *
2361 * @param cfg optional config literal
2362 */
2363 // eslint-disable-next-line complexity
2364 const _parseConfig = function _parseConfig() {
2365 let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2366 if (CONFIG && CONFIG === cfg) {
2367 return;
2368 }
2369 /* Shield configuration object from tampering */
2370 if (!cfg || typeof cfg !== 'object') {
2371 cfg = {};
2372 }
2373 /* Shield configuration object from prototype pollution */
2374 cfg = clone(cfg);
2375 PARSER_MEDIA_TYPE =
2376 // eslint-disable-next-line unicorn/prefer-includes
2377 SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
2378 // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
2379 transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
2380 /* Set configuration parameters */
2381 ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') && arrayIsArray(cfg.ALLOWED_TAGS) ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
2382 ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') && arrayIsArray(cfg.ALLOWED_ATTR) ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
2383 ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') && arrayIsArray(cfg.ALLOWED_NAMESPACES) ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
2384 URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') && arrayIsArray(cfg.ADD_URI_SAFE_ATTR) ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
2385 DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') && arrayIsArray(cfg.ADD_DATA_URI_TAGS) ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
2386 FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') && arrayIsArray(cfg.FORBID_CONTENTS) ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
2387 FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') && arrayIsArray(cfg.FORBID_TAGS) ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
2388 FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') && arrayIsArray(cfg.FORBID_ATTR) ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
2389 USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === 'object' ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
2390 ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
2391 ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
2392 ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
2393 ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
2394 SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
2395 SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true
2396 WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
2397 RETURN_DOM = cfg.RETURN_DOM || false; // Default false
2398 RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
2399 RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
2400 FORCE_BODY = cfg.FORCE_BODY || false; // Default false
2401 SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
2402 SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
2403 KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
2404 IN_PLACE = cfg.IN_PLACE || false; // Default false
2405 IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI; // Default regexp
2406 NAMESPACE = typeof cfg.NAMESPACE === 'string' ? cfg.NAMESPACE : HTML_NAMESPACE; // Default HTML namespace
2407 MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, 'MATHML_TEXT_INTEGRATION_POINTS') && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === 'object' ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']); // Default built-in map
2408 HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, 'HTML_INTEGRATION_POINTS') && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === 'object' ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, ['annotation-xml']); // Default built-in map
2409 const customElementHandling = objectHasOwnProperty(cfg, 'CUSTOM_ELEMENT_HANDLING') && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === 'object' ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
2410 CUSTOM_ELEMENT_HANDLING = create(null);
2411 if (objectHasOwnProperty(customElementHandling, 'tagNameCheck') && isRegexOrFunction(customElementHandling.tagNameCheck)) {
2412 CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck; // Default undefined
2413 }
2414 if (objectHasOwnProperty(customElementHandling, 'attributeNameCheck') && isRegexOrFunction(customElementHandling.attributeNameCheck)) {
2415 CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck; // Default undefined
2416 }
2417 if (objectHasOwnProperty(customElementHandling, 'allowCustomizedBuiltInElements') && typeof customElementHandling.allowCustomizedBuiltInElements === 'boolean') {
2418 CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements; // Default undefined
2419 }
2420 if (SAFE_FOR_TEMPLATES) {
2421 ALLOW_DATA_ATTR = false;
2422 }
2423 if (RETURN_DOM_FRAGMENT) {
2424 RETURN_DOM = true;
2425 }
2426 /* Parse profile info */
2427 if (USE_PROFILES) {
2428 ALLOWED_TAGS = addToSet({}, text);
2429 ALLOWED_ATTR = create(null);
2430 if (USE_PROFILES.html === true) {
2431 addToSet(ALLOWED_TAGS, html$1);
2432 addToSet(ALLOWED_ATTR, html);
2433 }
2434 if (USE_PROFILES.svg === true) {
2435 addToSet(ALLOWED_TAGS, svg$1);
2436 addToSet(ALLOWED_ATTR, svg);
2437 addToSet(ALLOWED_ATTR, xml);
2438 }
2439 if (USE_PROFILES.svgFilters === true) {
2440 addToSet(ALLOWED_TAGS, svgFilters);
2441 addToSet(ALLOWED_ATTR, svg);
2442 addToSet(ALLOWED_ATTR, xml);
2443 }
2444 if (USE_PROFILES.mathMl === true) {
2445 addToSet(ALLOWED_TAGS, mathMl$1);
2446 addToSet(ALLOWED_ATTR, mathMl);
2447 addToSet(ALLOWED_ATTR, xml);
2448 }
2449 }
2450 /* Always reset function-based ADD_TAGS / ADD_ATTR checks to prevent
2451 * leaking across calls when switching from function to array config */
2452 EXTRA_ELEMENT_HANDLING.tagCheck = null;
2453 EXTRA_ELEMENT_HANDLING.attributeCheck = null;
2454 /* Merge configuration parameters */
2455 if (objectHasOwnProperty(cfg, 'ADD_TAGS')) {
2456 if (typeof cfg.ADD_TAGS === 'function') {
2457 EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
2458 } else if (arrayIsArray(cfg.ADD_TAGS)) {
2459 if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
2460 ALLOWED_TAGS = clone(ALLOWED_TAGS);
2461 }
2462 addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
2463 }
2464 }
2465 if (objectHasOwnProperty(cfg, 'ADD_ATTR')) {
2466 if (typeof cfg.ADD_ATTR === 'function') {
2467 EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
2468 } else if (arrayIsArray(cfg.ADD_ATTR)) {
2469 if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
2470 ALLOWED_ATTR = clone(ALLOWED_ATTR);
2471 }
2472 addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
2473 }
2474 }
2475 if (objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) {
2476 addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
2477 }
2478 if (objectHasOwnProperty(cfg, 'FORBID_CONTENTS') && arrayIsArray(cfg.FORBID_CONTENTS)) {
2479 if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
2480 FORBID_CONTENTS = clone(FORBID_CONTENTS);
2481 }
2482 addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
2483 }
2484 if (objectHasOwnProperty(cfg, 'ADD_FORBID_CONTENTS') && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
2485 if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
2486 FORBID_CONTENTS = clone(FORBID_CONTENTS);
2487 }
2488 addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
2489 }
2490 /* Add #text in case KEEP_CONTENT is set to true */
2491 if (KEEP_CONTENT) {
2492 ALLOWED_TAGS['#text'] = true;
2493 }
2494 /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
2495 if (WHOLE_DOCUMENT) {
2496 addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
2497 }
2498 /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
2499 if (ALLOWED_TAGS.table) {
2500 addToSet(ALLOWED_TAGS, ['tbody']);
2501 delete FORBID_TAGS.tbody;
2502 }
2503 if (cfg.TRUSTED_TYPES_POLICY) {
2504 if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {
2505 throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
2506 }
2507 if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {
2508 throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
2509 }
2510 // Overwrite existing TrustedTypes policy.
2511 trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
2512 // Sign local variables required by `sanitize`.
2513 emptyHTML = trustedTypesPolicy.createHTML('');
2514 } else {
2515 // Uninitialized policy, attempt to initialize the internal dompurify policy.
2516 if (trustedTypesPolicy === undefined) {
2517 trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
2518 }
2519 // If creating the internal policy succeeded sign internal variables.
2520 if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {
2521 emptyHTML = trustedTypesPolicy.createHTML('');
2522 }
2523 }
2524 // Prevent further manipulation of configuration.
2525 // Not available in IE8, Safari 5, etc.
2526 if (freeze) {
2527 freeze(cfg);
2528 }
2529 CONFIG = cfg;
2530 };
2531 /* Keep track of all possible SVG and MathML tags
2532 * so that we can perform the namespace checks
2533 * correctly. */
2534 const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
2535 const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
2536 /**
2537 * @param element a DOM element whose namespace is being checked
2538 * @returns Return false if the element has a
2539 * namespace that a spec-compliant parser would never
2540 * return. Return true otherwise.
2541 */
2542 const _checkValidNamespace = function _checkValidNamespace(element) {
2543 let parent = getParentNode(element);
2544 // In JSDOM, if we're inside shadow DOM, then parentNode
2545 // can be null. We just simulate parent in this case.
2546 if (!parent || !parent.tagName) {
2547 parent = {
2548 namespaceURI: NAMESPACE,
2549 tagName: 'template'
2550 };
2551 }
2552 const tagName = stringToLowerCase(element.tagName);
2553 const parentTagName = stringToLowerCase(parent.tagName);
2554 if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
2555 return false;
2556 }
2557 if (element.namespaceURI === SVG_NAMESPACE) {
2558 // The only way to switch from HTML namespace to SVG
2559 // is via <svg>. If it happens via any other tag, then
2560 // it should be killed.
2561 if (parent.namespaceURI === HTML_NAMESPACE) {
2562 return tagName === 'svg';
2563 }
2564 // The only way to switch from MathML to SVG is via`
2565 // svg if parent is either <annotation-xml> or MathML
2566 // text integration points.
2567 if (parent.namespaceURI === MATHML_NAMESPACE) {
2568 return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
2569 }
2570 // We only allow elements that are defined in SVG
2571 // spec. All others are disallowed in SVG namespace.
2572 return Boolean(ALL_SVG_TAGS[tagName]);
2573 }
2574 if (element.namespaceURI === MATHML_NAMESPACE) {
2575 // The only way to switch from HTML namespace to MathML
2576 // is via <math>. If it happens via any other tag, then
2577 // it should be killed.
2578 if (parent.namespaceURI === HTML_NAMESPACE) {
2579 return tagName === 'math';
2580 }
2581 // The only way to switch from SVG to MathML is via
2582 // <math> and HTML integration points
2583 if (parent.namespaceURI === SVG_NAMESPACE) {
2584 return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
2585 }
2586 // We only allow elements that are defined in MathML
2587 // spec. All others are disallowed in MathML namespace.
2588 return Boolean(ALL_MATHML_TAGS[tagName]);
2589 }
2590 if (element.namespaceURI === HTML_NAMESPACE) {
2591 // The only way to switch from SVG to HTML is via
2592 // HTML integration points, and from MathML to HTML
2593 // is via MathML text integration points
2594 if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
2595 return false;
2596 }
2597 if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
2598 return false;
2599 }
2600 // We disallow tags that are specific for MathML
2601 // or SVG and should never appear in HTML namespace
2602 return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
2603 }
2604 // For XHTML and XML documents that support custom namespaces
2605 if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {
2606 return true;
2607 }
2608 // The code should never reach this place (this means
2609 // that the element somehow got namespace that is not
2610 // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).
2611 // Return false just in case.
2612 return false;
2613 };
2614 /**
2615 * _forceRemove
2616 *
2617 * @param node a DOM node
2618 */
2619 const _forceRemove = function _forceRemove(node) {
2620 arrayPush(DOMPurify.removed, {
2621 element: node
2622 });
2623 try {
2624 // eslint-disable-next-line unicorn/prefer-dom-node-remove
2625 getParentNode(node).removeChild(node);
2626 } catch (_) {
2627 remove(node);
2628 }
2629 };
2630 /**
2631 * _removeAttribute
2632 *
2633 * @param name an Attribute name
2634 * @param element a DOM node
2635 */
2636 const _removeAttribute = function _removeAttribute(name, element) {
2637 try {
2638 arrayPush(DOMPurify.removed, {
2639 attribute: element.getAttributeNode(name),
2640 from: element
2641 });
2642 } catch (_) {
2643 arrayPush(DOMPurify.removed, {
2644 attribute: null,
2645 from: element
2646 });
2647 }
2648 element.removeAttribute(name);
2649 // We void attribute values for unremovable "is" attributes
2650 if (name === 'is') {
2651 if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
2652 try {
2653 _forceRemove(element);
2654 } catch (_) {}
2655 } else {
2656 try {
2657 element.setAttribute(name, '');
2658 } catch (_) {}
2659 }
2660 }
2661 };
2662 /**
2663 * _initDocument
2664 *
2665 * @param dirty - a string of dirty markup
2666 * @return a DOM, filled with the dirty markup
2667 */
2668 const _initDocument = function _initDocument(dirty) {
2669 /* Create a HTML document */
2670 let doc = null;
2671 let leadingWhitespace = null;
2672 if (FORCE_BODY) {
2673 dirty = '<remove></remove>' + dirty;
2674 } else {
2675 /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
2676 const matches = stringMatch(dirty, /^[\r\n\t ]+/);
2677 leadingWhitespace = matches && matches[0];
2678 }
2679 if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {
2680 // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
2681 dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
2682 }
2683 const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
2684 /*
2685 * Use the DOMParser API by default, fallback later if needs be
2686 * DOMParser not work for svg when has multiple root element.
2687 */
2688 if (NAMESPACE === HTML_NAMESPACE) {
2689 try {
2690 doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
2691 } catch (_) {}
2692 }
2693 /* Use createHTMLDocument in case DOMParser is not available */
2694 if (!doc || !doc.documentElement) {
2695 doc = implementation.createDocument(NAMESPACE, 'template', null);
2696 try {
2697 doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
2698 } catch (_) {
2699 // Syntax error if dirtyPayload is invalid xml
2700 }
2701 }
2702 const body = doc.body || doc.documentElement;
2703 if (dirty && leadingWhitespace) {
2704 body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
2705 }
2706 /* Work on whole document or just its body */
2707 if (NAMESPACE === HTML_NAMESPACE) {
2708 return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
2709 }
2710 return WHOLE_DOCUMENT ? doc.documentElement : body;
2711 };
2712 /**
2713 * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
2714 *
2715 * @param root The root element or node to start traversing on.
2716 * @return The created NodeIterator
2717 */
2718 const _createNodeIterator = function _createNodeIterator(root) {
2719 return createNodeIterator.call(root.ownerDocument || root, root,
2720 // eslint-disable-next-line no-bitwise
2721 NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
2722 };
2723 /**
2724 * _isClobbered
2725 *
2726 * @param element element to check for clobbering attacks
2727 * @return true if clobbered, false if safe
2728 */
2729 const _isClobbered = function _isClobbered(element) {
2730 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');
2731 };
2732 /**
2733 * Checks whether the given object is a DOM node.
2734 *
2735 * @param value object to check whether it's a DOM node
2736 * @return true is object is a DOM node
2737 */
2738 const _isNode = function _isNode(value) {
2739 return typeof Node === 'function' && value instanceof Node;
2740 };
2741 function _executeHooks(hooks, currentNode, data) {
2742 arrayForEach(hooks, hook => {
2743 hook.call(DOMPurify, currentNode, data, CONFIG);
2744 });
2745 }
2746 /**
2747 * _sanitizeElements
2748 *
2749 * @protect nodeName
2750 * @protect textContent
2751 * @protect removeChild
2752 * @param currentNode to check for permission to exist
2753 * @return true if node was killed, false if left alive
2754 */
2755 const _sanitizeElements = function _sanitizeElements(currentNode) {
2756 let content = null;
2757 /* Execute a hook if present */
2758 _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
2759 /* Check if element is clobbered or can clobber */
2760 if (_isClobbered(currentNode)) {
2761 _forceRemove(currentNode);
2762 return true;
2763 }
2764 /* Now let's check the element's type and name */
2765 const tagName = transformCaseFunc(currentNode.nodeName);
2766 /* Execute a hook if present */
2767 _executeHooks(hooks.uponSanitizeElement, currentNode, {
2768 tagName,
2769 allowedTags: ALLOWED_TAGS
2770 });
2771 /* Detect mXSS attempts abusing namespace confusion */
2772 if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
2773 _forceRemove(currentNode);
2774 return true;
2775 }
2776 /* Remove risky CSS construction leading to mXSS */
2777 if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === 'style' && _isNode(currentNode.firstElementChild)) {
2778 _forceRemove(currentNode);
2779 return true;
2780 }
2781 /* Remove any occurrence of processing instructions */
2782 if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
2783 _forceRemove(currentNode);
2784 return true;
2785 }
2786 /* Remove any kind of possibly harmful comments */
2787 if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
2788 _forceRemove(currentNode);
2789 return true;
2790 }
2791 /* Remove element if anything forbids its presence */
2792 if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
2793 /* Check if we have a custom element to handle */
2794 if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
2795 if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
2796 return false;
2797 }
2798 if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
2799 return false;
2800 }
2801 }
2802 /* Keep content except for bad-listed elements */
2803 if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
2804 const parentNode = getParentNode(currentNode) || currentNode.parentNode;
2805 const childNodes = getChildNodes(currentNode) || currentNode.childNodes;
2806 if (childNodes && parentNode) {
2807 const childCount = childNodes.length;
2808 for (let i = childCount - 1; i >= 0; --i) {
2809 const childClone = cloneNode(childNodes[i], true);
2810 parentNode.insertBefore(childClone, getNextSibling(currentNode));
2811 }
2812 }
2813 }
2814 _forceRemove(currentNode);
2815 return true;
2816 }
2817 /* Check whether element has a valid namespace */
2818 if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
2819 _forceRemove(currentNode);
2820 return true;
2821 }
2822 /* Make sure that older browsers don't get fallback-tag mXSS */
2823 if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
2824 _forceRemove(currentNode);
2825 return true;
2826 }
2827 /* Sanitize element content to be template-safe */
2828 if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
2829 /* Get the element's text content */
2830 content = currentNode.textContent;
2831 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
2832 content = stringReplace(content, expr, ' ');
2833 });
2834 if (currentNode.textContent !== content) {
2835 arrayPush(DOMPurify.removed, {
2836 element: currentNode.cloneNode()
2837 });
2838 currentNode.textContent = content;
2839 }
2840 }
2841 /* Execute a hook if present */
2842 _executeHooks(hooks.afterSanitizeElements, currentNode, null);
2843 return false;
2844 };
2845 /**
2846 * _isValidAttribute
2847 *
2848 * @param lcTag Lowercase tag name of containing element.
2849 * @param lcName Lowercase attribute name.
2850 * @param value Attribute value.
2851 * @return Returns true if `value` is valid, otherwise false.
2852 */
2853 // eslint-disable-next-line complexity
2854 const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
2855 /* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */
2856 if (FORBID_ATTR[lcName]) {
2857 return false;
2858 }
2859 /* Make sure attribute cannot clobber */
2860 if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
2861 return false;
2862 }
2863 const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
2864 /* Allow valid data-* attributes: At least one character after "-"
2865 (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
2866 XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
2867 We don't need to check the value; it's always URI safe. */
2868 if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ;else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ;else if (!nameIsPermitted || FORBID_ATTR[lcName]) {
2869 if (
2870 // First condition does a very basic check if a) it's basically a valid custom element tagname AND
2871 // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
2872 // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
2873 _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) ||
2874 // Alternative, second condition checks if it's an `is`-attribute, AND
2875 // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
2876 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 {
2877 return false;
2878 }
2879 /* Check value is safe. First, is attr inert? If so, is safe */
2880 } 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) {
2881 return false;
2882 } else ;
2883 return true;
2884 };
2885 /* Names the HTML spec reserves from valid-custom-element-name; these must
2886 * never be treated as basic custom elements even when a permissive
2887 * CUSTOM_ELEMENT_HANDLING.tagNameCheck is configured. */
2888 const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, ['annotation-xml', 'color-profile', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'missing-glyph']);
2889 /**
2890 * _isBasicCustomElement
2891 * checks if at least one dash is included in tagName, and it's not the first char
2892 * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
2893 *
2894 * @param tagName name of the tag of the node to sanitize
2895 * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
2896 */
2897 const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
2898 return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT, tagName);
2899 };
2900 /**
2901 * _sanitizeAttributes
2902 *
2903 * @protect attributes
2904 * @protect nodeName
2905 * @protect removeAttribute
2906 * @protect setAttribute
2907 *
2908 * @param currentNode to sanitize
2909 */
2910 const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
2911 /* Execute a hook if present */
2912 _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
2913 const {
2914 attributes
2915 } = currentNode;
2916 /* Check if we have attributes; if not we might have a text node */
2917 if (!attributes || _isClobbered(currentNode)) {
2918 return;
2919 }
2920 const hookEvent = {
2921 attrName: '',
2922 attrValue: '',
2923 keepAttr: true,
2924 allowedAttributes: ALLOWED_ATTR,
2925 forceKeepAttr: undefined
2926 };
2927 let l = attributes.length;
2928 /* Go backwards over all attributes; safely remove bad ones */
2929 while (l--) {
2930 const attr = attributes[l];
2931 const {
2932 name,
2933 namespaceURI,
2934 value: attrValue
2935 } = attr;
2936 const lcName = transformCaseFunc(name);
2937 const initValue = attrValue;
2938 let value = name === 'value' ? initValue : stringTrim(initValue);
2939 /* Execute a hook if present */
2940 hookEvent.attrName = lcName;
2941 hookEvent.attrValue = value;
2942 hookEvent.keepAttr = true;
2943 hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
2944 _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
2945 value = hookEvent.attrValue;
2946 /* Full DOM Clobbering protection via namespace isolation,
2947 * Prefix id and name attributes with `user-content-`
2948 */
2949 if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name') && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
2950 // Remove the attribute with this value
2951 _removeAttribute(name, currentNode);
2952 // Prefix the value and later re-create the attribute with the sanitized value
2953 value = SANITIZE_NAMED_PROPS_PREFIX + value;
2954 }
2955 // Else: already prefixed, leave the attribute alone — the prefix is
2956 // itself the clobbering protection, and re-applying it is incorrect.
2957 /* Work around a security issue with comments inside attributes */
2958 if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
2959 _removeAttribute(name, currentNode);
2960 continue;
2961 }
2962 /* Make sure we cannot easily use animated hrefs, even if animations are allowed */
2963 if (lcName === 'attributename' && stringMatch(value, 'href')) {
2964 _removeAttribute(name, currentNode);
2965 continue;
2966 }
2967 /* Did the hooks approve of the attribute? */
2968 if (hookEvent.forceKeepAttr) {
2969 continue;
2970 }
2971 /* Did the hooks approve of the attribute? */
2972 if (!hookEvent.keepAttr) {
2973 _removeAttribute(name, currentNode);
2974 continue;
2975 }
2976 /* Work around a security issue in jQuery 3.0 */
2977 if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
2978 _removeAttribute(name, currentNode);
2979 continue;
2980 }
2981 /* Sanitize attribute content to be template-safe */
2982 if (SAFE_FOR_TEMPLATES) {
2983 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
2984 value = stringReplace(value, expr, ' ');
2985 });
2986 }
2987 /* Is `value` valid for this attribute? */
2988 const lcTag = transformCaseFunc(currentNode.nodeName);
2989 if (!_isValidAttribute(lcTag, lcName, value)) {
2990 _removeAttribute(name, currentNode);
2991 continue;
2992 }
2993 /* Handle attributes that require Trusted Types */
2994 if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {
2995 if (namespaceURI) ;else {
2996 switch (trustedTypes.getAttributeType(lcTag, lcName)) {
2997 case 'TrustedHTML':
2998 {
2999 value = trustedTypesPolicy.createHTML(value);
3000 break;
3001 }
3002 case 'TrustedScriptURL':
3003 {
3004 value = trustedTypesPolicy.createScriptURL(value);
3005 break;
3006 }
3007 }
3008 }
3009 }
3010 /* Handle invalid data-* attribute set by try-catching it */
3011 if (value !== initValue) {
3012 try {
3013 if (namespaceURI) {
3014 currentNode.setAttributeNS(namespaceURI, name, value);
3015 } else {
3016 /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
3017 currentNode.setAttribute(name, value);
3018 }
3019 if (_isClobbered(currentNode)) {
3020 _forceRemove(currentNode);
3021 } else {
3022 arrayPop(DOMPurify.removed);
3023 }
3024 } catch (_) {
3025 _removeAttribute(name, currentNode);
3026 }
3027 }
3028 }
3029 /* Execute a hook if present */
3030 _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
3031 };
3032 /**
3033 * _sanitizeShadowDOM
3034 *
3035 * @param fragment to iterate over recursively
3036 */
3037 const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
3038 let shadowNode = null;
3039 const shadowIterator = _createNodeIterator(fragment);
3040 /* Execute a hook if present */
3041 _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
3042 while (shadowNode = shadowIterator.nextNode()) {
3043 /* Execute a hook if present */
3044 _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
3045 /* Sanitize tags and elements */
3046 _sanitizeElements(shadowNode);
3047 /* Check attributes next */
3048 _sanitizeAttributes(shadowNode);
3049 /* Deep shadow DOM detected */
3050 if (shadowNode.content instanceof DocumentFragment) {
3051 _sanitizeShadowDOM2(shadowNode.content);
3052 }
3053 }
3054 /* Execute a hook if present */
3055 _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
3056 };
3057 // eslint-disable-next-line complexity
3058 DOMPurify.sanitize = function (dirty) {
3059 let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3060 let body = null;
3061 let importedNode = null;
3062 let currentNode = null;
3063 let returnNode = null;
3064 /* Make sure we have a string to sanitize.
3065 DO NOT return early, as this will return the wrong type if
3066 the user has requested a DOM object rather than a string */
3067 IS_EMPTY_INPUT = !dirty;
3068 if (IS_EMPTY_INPUT) {
3069 dirty = '<!-->';
3070 }
3071 /* Stringify, in case dirty is an object */
3072 if (typeof dirty !== 'string' && !_isNode(dirty)) {
3073 dirty = stringifyValue(dirty);
3074 if (typeof dirty !== 'string') {
3075 throw typeErrorCreate('dirty is not a string, aborting');
3076 }
3077 }
3078 /* Return dirty HTML if DOMPurify cannot run */
3079 if (!DOMPurify.isSupported) {
3080 return dirty;
3081 }
3082 /* Assign config vars */
3083 if (!SET_CONFIG) {
3084 _parseConfig(cfg);
3085 }
3086 /* Clean up removed elements */
3087 DOMPurify.removed = [];
3088 /* Check if dirty is correctly typed for IN_PLACE */
3089 if (typeof dirty === 'string') {
3090 IN_PLACE = false;
3091 }
3092 if (IN_PLACE) {
3093 /* Do some early pre-sanitization to avoid unsafe root nodes */
3094 const nn = dirty.nodeName;
3095 if (typeof nn === 'string') {
3096 const tagName = transformCaseFunc(nn);
3097 if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
3098 throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
3099 }
3100 }
3101 } else if (dirty instanceof Node) {
3102 /* If dirty is a DOM element, append to an empty document to avoid
3103 elements being stripped by the parser */
3104 body = _initDocument('<!---->');
3105 importedNode = body.ownerDocument.importNode(dirty, true);
3106 if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {
3107 /* Node is already a body, use as is */
3108 body = importedNode;
3109 } else if (importedNode.nodeName === 'HTML') {
3110 body = importedNode;
3111 } else {
3112 // eslint-disable-next-line unicorn/prefer-dom-node-append
3113 body.appendChild(importedNode);
3114 }
3115 } else {
3116 /* Exit directly if we have nothing to do */
3117 if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
3118 // eslint-disable-next-line unicorn/prefer-includes
3119 dirty.indexOf('<') === -1) {
3120 return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
3121 }
3122 /* Initialize the document to work on */
3123 body = _initDocument(dirty);
3124 /* Check we have a DOM node from the data */
3125 if (!body) {
3126 return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
3127 }
3128 }
3129 /* Remove first element node (ours) if FORCE_BODY is set */
3130 if (body && FORCE_BODY) {
3131 _forceRemove(body.firstChild);
3132 }
3133 /* Get node iterator */
3134 const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
3135 /* Now start iterating over the created document */
3136 while (currentNode = nodeIterator.nextNode()) {
3137 /* Sanitize tags and elements */
3138 _sanitizeElements(currentNode);
3139 /* Check attributes next */
3140 _sanitizeAttributes(currentNode);
3141 /* Shadow DOM detected, sanitize it */
3142 if (currentNode.content instanceof DocumentFragment) {
3143 _sanitizeShadowDOM2(currentNode.content);
3144 }
3145 }
3146 /* If we sanitized `dirty` in-place, return it. */
3147 if (IN_PLACE) {
3148 return dirty;
3149 }
3150 /* Return sanitized string or DOM */
3151 if (RETURN_DOM) {
3152 if (SAFE_FOR_TEMPLATES) {
3153 body.normalize();
3154 let html = body.innerHTML;
3155 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
3156 html = stringReplace(html, expr, ' ');
3157 });
3158 body.innerHTML = html;
3159 }
3160 if (RETURN_DOM_FRAGMENT) {
3161 returnNode = createDocumentFragment.call(body.ownerDocument);
3162 while (body.firstChild) {
3163 // eslint-disable-next-line unicorn/prefer-dom-node-append
3164 returnNode.appendChild(body.firstChild);
3165 }
3166 } else {
3167 returnNode = body;
3168 }
3169 if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
3170 /*
3171 AdoptNode() is not used because internal state is not reset
3172 (e.g. the past names map of a HTMLFormElement), this is safe
3173 in theory but we would rather not risk another attack vector.
3174 The state that is cloned by importNode() is explicitly defined
3175 by the specs.
3176 */
3177 returnNode = importNode.call(originalDocument, returnNode, true);
3178 }
3179 return returnNode;
3180 }
3181 let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
3182 /* Serialize doctype if allowed */
3183 if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
3184 serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
3185 }
3186 /* Sanitize final string template-safe */
3187 if (SAFE_FOR_TEMPLATES) {
3188 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
3189 serializedHTML = stringReplace(serializedHTML, expr, ' ');
3190 });
3191 }
3192 return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
3193 };
3194 DOMPurify.setConfig = function () {
3195 let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3196 _parseConfig(cfg);
3197 SET_CONFIG = true;
3198 };
3199 DOMPurify.clearConfig = function () {
3200 CONFIG = null;
3201 SET_CONFIG = false;
3202 };
3203 DOMPurify.isValidAttribute = function (tag, attr, value) {
3204 /* Initialize shared config vars if necessary. */
3205 if (!CONFIG) {
3206 _parseConfig({});
3207 }
3208 const lcTag = transformCaseFunc(tag);
3209 const lcName = transformCaseFunc(attr);
3210 return _isValidAttribute(lcTag, lcName, value);
3211 };
3212 DOMPurify.addHook = function (entryPoint, hookFunction) {
3213 if (typeof hookFunction !== 'function') {
3214 return;
3215 }
3216 arrayPush(hooks[entryPoint], hookFunction);
3217 };
3218 DOMPurify.removeHook = function (entryPoint, hookFunction) {
3219 if (hookFunction !== undefined) {
3220 const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
3221 return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0];
3222 }
3223 return arrayPop(hooks[entryPoint]);
3224 };
3225 DOMPurify.removeHooks = function (entryPoint) {
3226 hooks[entryPoint] = [];
3227 };
3228 DOMPurify.removeAllHooks = function () {
3229 hooks = _createHooksMap();
3230 };
3231 return DOMPurify;
3232 }
3233 var purify = createDOMPurify();
3234
3235 purify.addHook("uponSanitizeAttribute", function (node, data) {
3236 if (data.attrName === "data-trix-serialized-attributes") {
3237 data.keepAttr = false;
3238 return;
3239 }
3240 const allowedAttributePattern = /^data-trix-/;
3241 if (allowedAttributePattern.test(data.attrName)) {
3242 data.forceKeepAttr = true;
3243 }
3244 });
3245 const DEFAULT_ALLOWED_ATTRIBUTES = "style href src width height language class".split(" ");
3246 const DEFAULT_FORBIDDEN_PROTOCOLS = "javascript:".split(" ");
3247 const DEFAULT_FORBIDDEN_ELEMENTS = "script iframe form noscript".split(" ");
3248 class HTMLSanitizer extends BasicObject {
3249 static setHTML(element, html, options) {
3250 const sanitizedElement = new this(html, options).sanitize();
3251 const sanitizedHtml = sanitizedElement.getHTML ? sanitizedElement.getHTML() : sanitizedElement.outerHTML;
3252 element.innerHTML = sanitizedHtml;
3253 }
3254 static sanitize(html, options) {
3255 const sanitizer = new this(html, options);
3256 sanitizer.sanitize();
3257 return sanitizer;
3258 }
3259 constructor(html) {
3260 let {
3261 allowedAttributes,
3262 forbiddenProtocols,
3263 forbiddenElements,
3264 purifyOptions
3265 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3266 super(...arguments);
3267 this.allowedAttributes = allowedAttributes || DEFAULT_ALLOWED_ATTRIBUTES;
3268 this.forbiddenProtocols = forbiddenProtocols || DEFAULT_FORBIDDEN_PROTOCOLS;
3269 this.forbiddenElements = forbiddenElements || DEFAULT_FORBIDDEN_ELEMENTS;
3270 this.purifyOptions = purifyOptions || {};
3271 this.body = createBodyElementForHTML(html);
3272 }
3273 sanitize() {
3274 this.sanitizeElements();
3275 this.normalizeListElementNesting();
3276 const purifyConfig = Object.assign({}, dompurify, this.purifyOptions);
3277 purify.setConfig(purifyConfig);
3278 this.body = purify.sanitize(this.body);
3279 return this.body;
3280 }
3281 getHTML() {
3282 return this.body.innerHTML;
3283 }
3284 getBody() {
3285 return this.body;
3286 }
3287
3288 // Private
3289
3290 sanitizeElements() {
3291 const walker = walkTree(this.body);
3292 const nodesToRemove = [];
3293 while (walker.nextNode()) {
3294 const node = walker.currentNode;
3295 switch (node.nodeType) {
3296 case Node.ELEMENT_NODE:
3297 if (this.elementIsRemovable(node)) {
3298 nodesToRemove.push(node);
3299 } else {
3300 this.sanitizeElement(node);
3301 }
3302 break;
3303 case Node.COMMENT_NODE:
3304 nodesToRemove.push(node);
3305 break;
3306 }
3307 }
3308 nodesToRemove.forEach(node => removeNode(node));
3309 return this.body;
3310 }
3311 sanitizeElement(element) {
3312 if (element.hasAttribute("href")) {
3313 if (this.forbiddenProtocols.includes(element.protocol)) {
3314 element.removeAttribute("href");
3315 }
3316 }
3317 Array.from(element.attributes).forEach(_ref => {
3318 let {
3319 name
3320 } = _ref;
3321 if (!this.allowedAttributes.includes(name) && name.indexOf("data-trix") !== 0) {
3322 element.removeAttribute(name);
3323 }
3324 });
3325 return element;
3326 }
3327 normalizeListElementNesting() {
3328 Array.from(this.body.querySelectorAll("ul,ol")).forEach(listElement => {
3329 const previousElement = listElement.previousElementSibling;
3330 if (previousElement) {
3331 if (tagName(previousElement) === "li") {
3332 previousElement.appendChild(listElement);
3333 }
3334 }
3335 });
3336 return this.body;
3337 }
3338 elementIsRemovable(element) {
3339 if ((element === null || element === void 0 ? void 0 : element.nodeType) !== Node.ELEMENT_NODE) return;
3340 return this.elementIsForbidden(element) || this.elementIsntSerializable(element);
3341 }
3342 elementIsForbidden(element) {
3343 return this.forbiddenElements.includes(tagName(element));
3344 }
3345 elementIsntSerializable(element) {
3346 return element.getAttribute("data-trix-serialize") === "false" && !nodeIsAttachmentElement(element);
3347 }
3348 }
3349 const createBodyElementForHTML = function () {
3350 let html = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
3351 // Remove everything after </html>
3352 html = html.replace(/<\/html[^>]*>[^]*$/i, "</html>");
3353 const doc = document.implementation.createHTMLDocument("");
3354 doc.documentElement.innerHTML = html;
3355 Array.from(doc.head.querySelectorAll("style")).forEach(element => {
3356 doc.body.appendChild(element);
3357 });
3358 return doc.body;
3359 };
3360
3361 const {
3362 css: css$2
3363 } = config;
3364 class AttachmentView extends ObjectView {
3365 constructor() {
3366 super(...arguments);
3367 this.attachment = this.object;
3368 this.attachment.uploadProgressDelegate = this;
3369 this.attachmentPiece = this.options.piece;
3370 }
3371 createContentNodes() {
3372 return [];
3373 }
3374 createNodes() {
3375 let innerElement;
3376 const figure = innerElement = makeElement({
3377 tagName: "figure",
3378 className: this.getClassName(),
3379 data: this.getData(),
3380 editable: false
3381 });
3382 const href = this.getHref();
3383 if (href) {
3384 innerElement = makeElement({
3385 tagName: "a",
3386 editable: false,
3387 attributes: {
3388 href,
3389 tabindex: -1
3390 }
3391 });
3392 figure.appendChild(innerElement);
3393 }
3394 if (this.attachment.hasContent()) {
3395 HTMLSanitizer.setHTML(innerElement, this.attachment.getContent());
3396 } else {
3397 this.createContentNodes().forEach(node => {
3398 innerElement.appendChild(node);
3399 });
3400 }
3401 innerElement.appendChild(this.createCaptionElement());
3402 if (this.attachment.isPending()) {
3403 this.progressElement = makeElement({
3404 tagName: "progress",
3405 attributes: {
3406 class: css$2.attachmentProgress,
3407 value: this.attachment.getUploadProgress(),
3408 max: 100
3409 },
3410 data: {
3411 trixMutable: true,
3412 trixStoreKey: ["progressElement", this.attachment.id].join("/")
3413 }
3414 });
3415 figure.appendChild(this.progressElement);
3416 }
3417 return [createCursorTarget("left"), figure, createCursorTarget("right")];
3418 }
3419 createCaptionElement() {
3420 const figcaption = makeElement({
3421 tagName: "figcaption",
3422 className: css$2.attachmentCaption
3423 });
3424 const caption = this.attachmentPiece.getCaption();
3425 if (caption) {
3426 figcaption.classList.add("".concat(css$2.attachmentCaption, "--edited"));
3427 figcaption.textContent = caption;
3428 } else {
3429 let name, size;
3430 const captionConfig = this.getCaptionConfig();
3431 if (captionConfig.name) {
3432 name = this.attachment.getFilename();
3433 }
3434 if (captionConfig.size) {
3435 size = this.attachment.getFormattedFilesize();
3436 }
3437 if (name) {
3438 const nameElement = makeElement({
3439 tagName: "span",
3440 className: css$2.attachmentName,
3441 textContent: name
3442 });
3443 figcaption.appendChild(nameElement);
3444 }
3445 if (size) {
3446 if (name) {
3447 figcaption.appendChild(document.createTextNode(" "));
3448 }
3449 const sizeElement = makeElement({
3450 tagName: "span",
3451 className: css$2.attachmentSize,
3452 textContent: size
3453 });
3454 figcaption.appendChild(sizeElement);
3455 }
3456 }
3457 return figcaption;
3458 }
3459 getClassName() {
3460 const names = [css$2.attachment, "".concat(css$2.attachment, "--").concat(this.attachment.getType())];
3461 const extension = this.attachment.getExtension();
3462 if (extension) {
3463 names.push("".concat(css$2.attachment, "--").concat(extension));
3464 }
3465 return names.join(" ");
3466 }
3467 getData() {
3468 const data = {
3469 trixAttachment: JSON.stringify(this.attachment),
3470 trixContentType: this.attachment.getContentType(),
3471 trixId: this.attachment.id
3472 };
3473 const {
3474 attributes
3475 } = this.attachmentPiece;
3476 if (!attributes.isEmpty()) {
3477 data.trixAttributes = JSON.stringify(attributes);
3478 }
3479 if (this.attachment.isPending()) {
3480 data.trixSerialize = false;
3481 }
3482 return data;
3483 }
3484 getHref() {
3485 if (!htmlContainsTagName(this.attachment.getContent(), "a")) {
3486 const href = this.attachment.getHref();
3487 if (href && purify.isValidAttribute("a", "href", href)) {
3488 return href;
3489 }
3490 }
3491 }
3492 getCaptionConfig() {
3493 var _config$attachments$t;
3494 const type = this.attachment.getType();
3495 const captionConfig = copyObject((_config$attachments$t = attachments[type]) === null || _config$attachments$t === void 0 ? void 0 : _config$attachments$t.caption);
3496 if (type === "file") {
3497 captionConfig.name = true;
3498 }
3499 return captionConfig;
3500 }
3501 findProgressElement() {
3502 var _this$findElement;
3503 return (_this$findElement = this.findElement()) === null || _this$findElement === void 0 ? void 0 : _this$findElement.querySelector("progress");
3504 }
3505
3506 // Attachment delegate
3507
3508 attachmentDidChangeUploadProgress() {
3509 const value = this.attachment.getUploadProgress();
3510 const progressElement = this.findProgressElement();
3511 if (progressElement) {
3512 progressElement.value = value;
3513 }
3514 }
3515 }
3516 const createCursorTarget = name => makeElement({
3517 tagName: "span",
3518 textContent: ZERO_WIDTH_SPACE,
3519 data: {
3520 trixCursorTarget: name,
3521 trixSerialize: false
3522 }
3523 });
3524 const htmlContainsTagName = function (html, tagName) {
3525 const div = makeElement("div");
3526 HTMLSanitizer.setHTML(div, html || "");
3527 return div.querySelector(tagName);
3528 };
3529
3530 class PreviewableAttachmentView extends AttachmentView {
3531 constructor() {
3532 super(...arguments);
3533 this.attachment.previewDelegate = this;
3534 }
3535 createContentNodes() {
3536 this.image = makeElement({
3537 tagName: "img",
3538 attributes: {
3539 src: ""
3540 },
3541 data: {
3542 trixMutable: true
3543 }
3544 });
3545 this.refresh(this.image);
3546 return [this.image];
3547 }
3548 createCaptionElement() {
3549 const figcaption = super.createCaptionElement(...arguments);
3550 if (!figcaption.textContent) {
3551 figcaption.setAttribute("data-trix-placeholder", lang$1.captionPlaceholder);
3552 }
3553 return figcaption;
3554 }
3555 refresh(image) {
3556 if (!image) {
3557 var _this$findElement;
3558 image = (_this$findElement = this.findElement()) === null || _this$findElement === void 0 ? void 0 : _this$findElement.querySelector("img");
3559 }
3560 if (image) {
3561 return this.updateAttributesForImage(image);
3562 }
3563 }
3564 updateAttributesForImage(image) {
3565 const url = this.attachment.getURL();
3566 const previewURL = this.attachment.getPreviewURL();
3567 image.src = previewURL || url;
3568 if (previewURL === url) {
3569 image.removeAttribute("data-trix-serialized-attributes");
3570 } else {
3571 const serializedAttributes = JSON.stringify({
3572 src: url
3573 });
3574 image.setAttribute("data-trix-serialized-attributes", serializedAttributes);
3575 }
3576 const width = this.attachment.getWidth();
3577 const height = this.attachment.getHeight();
3578 const alt = this.attachment.getAttribute("alt");
3579 if (width != null) {
3580 image.width = width;
3581 }
3582 if (height != null) {
3583 image.height = height;
3584 }
3585 if (alt != null) {
3586 image.alt = alt;
3587 }
3588 const storeKey = ["imageElement", this.attachment.id, image.src, image.width, image.height].join("/");
3589 image.dataset.trixStoreKey = storeKey;
3590 }
3591
3592 // Attachment delegate
3593
3594 attachmentDidChangeAttributes() {
3595 this.refresh(this.image);
3596 return this.refresh();
3597 }
3598 }
3599
3600 /* eslint-disable
3601 no-useless-escape,
3602 no-var,
3603 */
3604 class PieceView extends ObjectView {
3605 constructor() {
3606 super(...arguments);
3607 this.piece = this.object;
3608 this.attributes = this.piece.getAttributes();
3609 this.textConfig = this.options.textConfig;
3610 this.context = this.options.context;
3611 if (this.piece.attachment) {
3612 this.attachment = this.piece.attachment;
3613 } else {
3614 this.string = this.piece.toString();
3615 }
3616 }
3617 createNodes() {
3618 let nodes = this.attachment ? this.createAttachmentNodes() : this.createStringNodes();
3619 const element = this.createElement();
3620 if (element) {
3621 const innerElement = findInnerElement(element);
3622 Array.from(nodes).forEach(node => {
3623 innerElement.appendChild(node);
3624 });
3625 nodes = [element];
3626 }
3627 return nodes;
3628 }
3629 createAttachmentNodes() {
3630 const constructor = this.attachment.isPreviewable() ? PreviewableAttachmentView : AttachmentView;
3631 const view = this.createChildView(constructor, this.piece.attachment, {
3632 piece: this.piece
3633 });
3634 return view.getNodes();
3635 }
3636 createStringNodes() {
3637 var _this$textConfig;
3638 if ((_this$textConfig = this.textConfig) !== null && _this$textConfig !== void 0 && _this$textConfig.plaintext) {
3639 return [document.createTextNode(this.string)];
3640 } else {
3641 const nodes = [];
3642 const iterable = this.string.split("\n");
3643 for (let index = 0; index < iterable.length; index++) {
3644 const substring = iterable[index];
3645 if (index > 0) {
3646 const element = makeElement("br");
3647 nodes.push(element);
3648 }
3649 if (substring.length) {
3650 const node = document.createTextNode(this.preserveSpaces(substring));
3651 nodes.push(node);
3652 }
3653 }
3654 return nodes;
3655 }
3656 }
3657 createElement() {
3658 let element, key, value;
3659 const styles = {};
3660 for (key in this.attributes) {
3661 value = this.attributes[key];
3662 const config = getTextConfig(key);
3663 if (config) {
3664 if (config.tagName) {
3665 var innerElement;
3666 const pendingElement = makeElement(config.tagName);
3667 if (innerElement) {
3668 innerElement.appendChild(pendingElement);
3669 innerElement = pendingElement;
3670 } else {
3671 element = innerElement = pendingElement;
3672 }
3673 }
3674 if (config.styleProperty) {
3675 styles[config.styleProperty] = value;
3676 }
3677 if (config.style) {
3678 for (key in config.style) {
3679 value = config.style[key];
3680 styles[key] = value;
3681 }
3682 }
3683 }
3684 }
3685 if (Object.keys(styles).length) {
3686 if (!element) {
3687 element = makeElement("span");
3688 }
3689 for (key in styles) {
3690 value = styles[key];
3691 element.style[key] = value;
3692 }
3693 }
3694 return element;
3695 }
3696 createContainerElement() {
3697 for (const key in this.attributes) {
3698 const value = this.attributes[key];
3699 const config = getTextConfig(key);
3700 if (config) {
3701 if (config.groupTagName) {
3702 const attributes = {};
3703 attributes[key] = value;
3704 return makeElement(config.groupTagName, attributes);
3705 }
3706 }
3707 }
3708 }
3709 preserveSpaces(string) {
3710 if (this.context.isLast) {
3711 string = string.replace(/\ $/, NON_BREAKING_SPACE);
3712 }
3713 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));
3714 if (this.context.isFirst || this.context.followsWhitespace) {
3715 string = string.replace(/^\ /, NON_BREAKING_SPACE);
3716 }
3717 return string;
3718 }
3719 }
3720
3721 /* eslint-disable
3722 no-var,
3723 */
3724 class TextView extends ObjectView {
3725 constructor() {
3726 super(...arguments);
3727 this.text = this.object;
3728 this.textConfig = this.options.textConfig;
3729 }
3730 createNodes() {
3731 const nodes = [];
3732 const pieces = ObjectGroup.groupObjects(this.getPieces());
3733 const lastIndex = pieces.length - 1;
3734 for (let index = 0; index < pieces.length; index++) {
3735 const piece = pieces[index];
3736 const context = {};
3737 if (index === 0) {
3738 context.isFirst = true;
3739 }
3740 if (index === lastIndex) {
3741 context.isLast = true;
3742 }
3743 if (endsWithWhitespace(previousPiece)) {
3744 context.followsWhitespace = true;
3745 }
3746 const view = this.findOrCreateCachedChildView(PieceView, piece, {
3747 textConfig: this.textConfig,
3748 context
3749 });
3750 nodes.push(...Array.from(view.getNodes() || []));
3751 var previousPiece = piece;
3752 }
3753 return nodes;
3754 }
3755 getPieces() {
3756 return Array.from(this.text.getPieces()).filter(piece => !piece.hasAttribute("blockBreak"));
3757 }
3758 }
3759 const endsWithWhitespace = piece => /\s$/.test(piece === null || piece === void 0 ? void 0 : piece.toString());
3760
3761 const {
3762 css: css$1
3763 } = config;
3764 class BlockView extends ObjectView {
3765 constructor() {
3766 super(...arguments);
3767 this.block = this.object;
3768 this.attributes = this.block.getAttributes();
3769 }
3770 createNodes() {
3771 const comment = document.createComment("block");
3772 const nodes = [comment];
3773 if (this.block.isEmpty()) {
3774 nodes.push(makeElement("br"));
3775 } else {
3776 var _getBlockConfig;
3777 const textConfig = (_getBlockConfig = getBlockConfig(this.block.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.text;
3778 const textView = this.findOrCreateCachedChildView(TextView, this.block.text, {
3779 textConfig
3780 });
3781 nodes.push(...Array.from(textView.getNodes() || []));
3782 if (this.shouldAddExtraNewlineElement()) {
3783 nodes.push(makeElement("br"));
3784 }
3785 }
3786 if (this.attributes.length) {
3787 return nodes;
3788 } else {
3789 let attributes$1;
3790 const {
3791 tagName
3792 } = attributes.default;
3793 if (this.block.isRTL()) {
3794 attributes$1 = {
3795 dir: "rtl"
3796 };
3797 }
3798 const element = makeElement({
3799 tagName,
3800 attributes: attributes$1
3801 });
3802 nodes.forEach(node => element.appendChild(node));
3803 return [element];
3804 }
3805 }
3806 createContainerElement(depth) {
3807 const attributes = {};
3808 let className;
3809 const attributeName = this.attributes[depth];
3810 const {
3811 tagName,
3812 htmlAttributes = []
3813 } = getBlockConfig(attributeName);
3814 if (depth === 0 && this.block.isRTL()) {
3815 Object.assign(attributes, {
3816 dir: "rtl"
3817 });
3818 }
3819 if (attributeName === "attachmentGallery") {
3820 const size = this.block.getBlockBreakPosition();
3821 className = "".concat(css$1.attachmentGallery, " ").concat(css$1.attachmentGallery, "--").concat(size);
3822 }
3823 Object.entries(this.block.htmlAttributes).forEach(_ref => {
3824 let [name, value] = _ref;
3825 if (htmlAttributes.includes(name)) {
3826 attributes[name] = value;
3827 }
3828 });
3829 return makeElement({
3830 tagName,
3831 className,
3832 attributes
3833 });
3834 }
3835
3836 // A single <br> at the end of a block element has no visual representation
3837 // so add an extra one.
3838 shouldAddExtraNewlineElement() {
3839 return /\n\n$/.test(this.block.toString());
3840 }
3841 }
3842
3843 class DocumentView extends ObjectView {
3844 static render(document) {
3845 const element = makeElement("div");
3846 const view = new this(document, {
3847 element
3848 });
3849 view.render();
3850 view.sync();
3851 return element;
3852 }
3853 constructor() {
3854 super(...arguments);
3855 this.element = this.options.element;
3856 this.elementStore = new ElementStore();
3857 this.setDocument(this.object);
3858 }
3859 setDocument(document) {
3860 if (!document.isEqualTo(this.document)) {
3861 this.document = this.object = document;
3862 }
3863 }
3864 render() {
3865 this.childViews = [];
3866 this.shadowElement = makeElement("div");
3867 if (!this.document.isEmpty()) {
3868 const objects = ObjectGroup.groupObjects(this.document.getBlocks(), {
3869 asTree: true
3870 });
3871 Array.from(objects).forEach(object => {
3872 const view = this.findOrCreateCachedChildView(BlockView, object);
3873 Array.from(view.getNodes()).map(node => this.shadowElement.appendChild(node));
3874 });
3875 }
3876 }
3877 isSynced() {
3878 return elementsHaveEqualHTML(this.shadowElement, this.element);
3879 }
3880 sync() {
3881 const render = (element, documentFragment) => {
3882 while (element.lastChild) {
3883 element.removeChild(element.lastChild);
3884 }
3885 element.appendChild(documentFragment);
3886 };
3887 const event = createEvent("trix-before-render", {
3888 cancelable: false,
3889 attributes: {
3890 render
3891 }
3892 });
3893 this.element.dispatchEvent(event);
3894 const fragment = this.createDocumentFragmentForSync();
3895 event.render(this.element, fragment);
3896 return this.didSync();
3897 }
3898
3899 // Private
3900
3901 didSync() {
3902 this.elementStore.reset(findStoredElements(this.element));
3903 return defer(() => this.garbageCollectCachedViews());
3904 }
3905 createDocumentFragmentForSync() {
3906 const fragment = document.createDocumentFragment();
3907 Array.from(this.shadowElement.childNodes).forEach(node => {
3908 fragment.appendChild(node.cloneNode(true));
3909 });
3910 Array.from(findStoredElements(fragment)).forEach(element => {
3911 const storedElement = this.elementStore.remove(element);
3912 if (storedElement) {
3913 element.parentNode.replaceChild(storedElement, element);
3914 }
3915 });
3916 return fragment;
3917 }
3918 }
3919 const findStoredElements = element => element.querySelectorAll("[data-trix-store-key]");
3920 const elementsHaveEqualHTML = (element, otherElement) => ignoreSpaces(element.innerHTML) === ignoreSpaces(otherElement.innerHTML);
3921 const ignoreSpaces = html => html.replace(/&nbsp;/g, " ");
3922
3923 function _AsyncGenerator(e) {
3924 var r, t;
3925 function resume(r, t) {
3926 try {
3927 var n = e[r](t),
3928 o = n.value,
3929 u = o instanceof _OverloadYield;
3930 Promise.resolve(u ? o.v : o).then(function (t) {
3931 if (u) {
3932 var i = "return" === r ? "return" : "next";
3933 if (!o.k || t.done) return resume(i, t);
3934 t = e[i](t).value;
3935 }
3936 settle(n.done ? "return" : "normal", t);
3937 }, function (e) {
3938 resume("throw", e);
3939 });
3940 } catch (e) {
3941 settle("throw", e);
3942 }
3943 }
3944 function settle(e, n) {
3945 switch (e) {
3946 case "return":
3947 r.resolve({
3948 value: n,
3949 done: !0
3950 });
3951 break;
3952 case "throw":
3953 r.reject(n);
3954 break;
3955 default:
3956 r.resolve({
3957 value: n,
3958 done: !1
3959 });
3960 }
3961 (r = r.next) ? resume(r.key, r.arg) : t = null;
3962 }
3963 this._invoke = function (e, n) {
3964 return new Promise(function (o, u) {
3965 var i = {
3966 key: e,
3967 arg: n,
3968 resolve: o,
3969 reject: u,
3970 next: null
3971 };
3972 t ? t = t.next = i : (r = t = i, resume(e, n));
3973 });
3974 }, "function" != typeof e.return && (this.return = void 0);
3975 }
3976 _AsyncGenerator.prototype["function" == typeof Symbol && Symbol.asyncIterator || "@@asyncIterator"] = function () {
3977 return this;
3978 }, _AsyncGenerator.prototype.next = function (e) {
3979 return this._invoke("next", e);
3980 }, _AsyncGenerator.prototype.throw = function (e) {
3981 return this._invoke("throw", e);
3982 }, _AsyncGenerator.prototype.return = function (e) {
3983 return this._invoke("return", e);
3984 };
3985 function _OverloadYield(t, e) {
3986 this.v = t, this.k = e;
3987 }
3988 function old_createMetadataMethodsForProperty(e, t, a, r) {
3989 return {
3990 getMetadata: function (o) {
3991 old_assertNotFinished(r, "getMetadata"), old_assertMetadataKey(o);
3992 var i = e[o];
3993 if (void 0 !== i) if (1 === t) {
3994 var n = i.public;
3995 if (void 0 !== n) return n[a];
3996 } else if (2 === t) {
3997 var l = i.private;
3998 if (void 0 !== l) return l.get(a);
3999 } else if (Object.hasOwnProperty.call(i, "constructor")) return i.constructor;
4000 },
4001 setMetadata: function (o, i) {
4002 old_assertNotFinished(r, "setMetadata"), old_assertMetadataKey(o);
4003 var n = e[o];
4004 if (void 0 === n && (n = e[o] = {}), 1 === t) {
4005 var l = n.public;
4006 void 0 === l && (l = n.public = {}), l[a] = i;
4007 } else if (2 === t) {
4008 var s = n.priv;
4009 void 0 === s && (s = n.private = new Map()), s.set(a, i);
4010 } else n.constructor = i;
4011 }
4012 };
4013 }
4014 function old_convertMetadataMapToFinal(e, t) {
4015 var a = e[Symbol.metadata || Symbol.for("Symbol.metadata")],
4016 r = Object.getOwnPropertySymbols(t);
4017 if (0 !== r.length) {
4018 for (var o = 0; o < r.length; o++) {
4019 var i = r[o],
4020 n = t[i],
4021 l = a ? a[i] : null,
4022 s = n.public,
4023 c = l ? l.public : null;
4024 s && c && Object.setPrototypeOf(s, c);
4025 var d = n.private;
4026 if (d) {
4027 var u = Array.from(d.values()),
4028 f = l ? l.private : null;
4029 f && (u = u.concat(f)), n.private = u;
4030 }
4031 l && Object.setPrototypeOf(n, l);
4032 }
4033 a && Object.setPrototypeOf(t, a), e[Symbol.metadata || Symbol.for("Symbol.metadata")] = t;
4034 }
4035 }
4036 function old_createAddInitializerMethod(e, t) {
4037 return function (a) {
4038 old_assertNotFinished(t, "addInitializer"), old_assertCallable(a, "An initializer"), e.push(a);
4039 };
4040 }
4041 function old_memberDec(e, t, a, r, o, i, n, l, s) {
4042 var c;
4043 switch (i) {
4044 case 1:
4045 c = "accessor";
4046 break;
4047 case 2:
4048 c = "method";
4049 break;
4050 case 3:
4051 c = "getter";
4052 break;
4053 case 4:
4054 c = "setter";
4055 break;
4056 default:
4057 c = "field";
4058 }
4059 var d,
4060 u,
4061 f = {
4062 kind: c,
4063 name: l ? "#" + t : _toPropertyKey(t),
4064 isStatic: n,
4065 isPrivate: l
4066 },
4067 p = {
4068 v: !1
4069 };
4070 if (0 !== i && (f.addInitializer = old_createAddInitializerMethod(o, p)), l) {
4071 d = 2, u = Symbol(t);
4072 var v = {};
4073 0 === i ? (v.get = a.get, v.set = a.set) : 2 === i ? v.get = function () {
4074 return a.value;
4075 } : (1 !== i && 3 !== i || (v.get = function () {
4076 return a.get.call(this);
4077 }), 1 !== i && 4 !== i || (v.set = function (e) {
4078 a.set.call(this, e);
4079 })), f.access = v;
4080 } else d = 1, u = t;
4081 try {
4082 return e(s, Object.assign(f, old_createMetadataMethodsForProperty(r, d, u, p)));
4083 } finally {
4084 p.v = !0;
4085 }
4086 }
4087 function old_assertNotFinished(e, t) {
4088 if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
4089 }
4090 function old_assertMetadataKey(e) {
4091 if ("symbol" != typeof e) throw new TypeError("Metadata keys must be symbols, received: " + e);
4092 }
4093 function old_assertCallable(e, t) {
4094 if ("function" != typeof e) throw new TypeError(t + " must be a function");
4095 }
4096 function old_assertValidReturnValue(e, t) {
4097 var a = typeof t;
4098 if (1 === e) {
4099 if ("object" !== a || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
4100 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");
4101 } else if ("function" !== a) throw new TypeError((0 === e ? "field" : 10 === e ? "class" : "method") + " decorators must return a function or void 0");
4102 }
4103 function old_getInit(e) {
4104 var t;
4105 return null == (t = e.init) && (t = e.initializer) && "undefined" != typeof console && console.warn(".initializer has been renamed to .init as of March 2022"), t;
4106 }
4107 function old_applyMemberDec(e, t, a, r, o, i, n, l, s) {
4108 var c,
4109 d,
4110 u,
4111 f,
4112 p,
4113 v,
4114 y,
4115 h = a[0];
4116 if (n ? (0 === o || 1 === o ? (c = {
4117 get: a[3],
4118 set: a[4]
4119 }, u = "get") : 3 === o ? (c = {
4120 get: a[3]
4121 }, u = "get") : 4 === o ? (c = {
4122 set: a[3]
4123 }, u = "set") : c = {
4124 value: a[3]
4125 }, 0 !== o && (1 === o && _setFunctionName(a[4], "#" + r, "set"), _setFunctionName(a[3], "#" + r, u))) : 0 !== o && (c = Object.getOwnPropertyDescriptor(t, r)), 1 === o ? f = {
4126 get: c.get,
4127 set: c.set
4128 } : 2 === o ? f = c.value : 3 === o ? f = c.get : 4 === o && (f = c.set), "function" == typeof h) void 0 !== (p = old_memberDec(h, r, c, l, s, o, i, n, f)) && (old_assertValidReturnValue(o, p), 0 === o ? d = p : 1 === o ? (d = old_getInit(p), v = p.get || f.get, y = p.set || f.set, f = {
4129 get: v,
4130 set: y
4131 }) : f = p);else for (var m = h.length - 1; m >= 0; m--) {
4132 var b;
4133 void 0 !== (p = old_memberDec(h[m], r, c, l, s, o, i, n, f)) && (old_assertValidReturnValue(o, p), 0 === o ? b = p : 1 === o ? (b = old_getInit(p), v = p.get || f.get, y = p.set || f.set, f = {
4134 get: v,
4135 set: y
4136 }) : f = p, void 0 !== b && (void 0 === d ? d = b : "function" == typeof d ? d = [d, b] : d.push(b)));
4137 }
4138 if (0 === o || 1 === o) {
4139 if (void 0 === d) d = function (e, t) {
4140 return t;
4141 };else if ("function" != typeof d) {
4142 var g = d;
4143 d = function (e, t) {
4144 for (var a = t, r = 0; r < g.length; r++) a = g[r].call(e, a);
4145 return a;
4146 };
4147 } else {
4148 var _ = d;
4149 d = function (e, t) {
4150 return _.call(e, t);
4151 };
4152 }
4153 e.push(d);
4154 }
4155 0 !== o && (1 === o ? (c.get = f.get, c.set = f.set) : 2 === o ? c.value = f : 3 === o ? c.get = f : 4 === o && (c.set = f), n ? 1 === o ? (e.push(function (e, t) {
4156 return f.get.call(e, t);
4157 }), e.push(function (e, t) {
4158 return f.set.call(e, t);
4159 })) : 2 === o ? e.push(f) : e.push(function (e, t) {
4160 return f.call(e, t);
4161 }) : Object.defineProperty(t, r, c));
4162 }
4163 function old_applyMemberDecs(e, t, a, r, o) {
4164 for (var i, n, l = new Map(), s = new Map(), c = 0; c < o.length; c++) {
4165 var d = o[c];
4166 if (Array.isArray(d)) {
4167 var u,
4168 f,
4169 p,
4170 v = d[1],
4171 y = d[2],
4172 h = d.length > 3,
4173 m = v >= 5;
4174 if (m ? (u = t, f = r, 0 != (v -= 5) && (p = n = n || [])) : (u = t.prototype, f = a, 0 !== v && (p = i = i || [])), 0 !== v && !h) {
4175 var b = m ? s : l,
4176 g = b.get(y) || 0;
4177 if (!0 === g || 3 === g && 4 !== v || 4 === g && 3 !== v) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + y);
4178 !g && v > 2 ? b.set(y, v) : b.set(y, !0);
4179 }
4180 old_applyMemberDec(e, u, d, y, v, m, h, f, p);
4181 }
4182 }
4183 old_pushInitializers(e, i), old_pushInitializers(e, n);
4184 }
4185 function old_pushInitializers(e, t) {
4186 t && e.push(function (e) {
4187 for (var a = 0; a < t.length; a++) t[a].call(e);
4188 return e;
4189 });
4190 }
4191 function old_applyClassDecs(e, t, a, r) {
4192 if (r.length > 0) {
4193 for (var o = [], i = t, n = t.name, l = r.length - 1; l >= 0; l--) {
4194 var s = {
4195 v: !1
4196 };
4197 try {
4198 var c = Object.assign({
4199 kind: "class",
4200 name: n,
4201 addInitializer: old_createAddInitializerMethod(o, s)
4202 }, old_createMetadataMethodsForProperty(a, 0, n, s)),
4203 d = r[l](i, c);
4204 } finally {
4205 s.v = !0;
4206 }
4207 void 0 !== d && (old_assertValidReturnValue(10, d), i = d);
4208 }
4209 e.push(i, function () {
4210 for (var e = 0; e < o.length; e++) o[e].call(i);
4211 });
4212 }
4213 }
4214 function _applyDecs(e, t, a) {
4215 var r = [],
4216 o = {},
4217 i = {};
4218 return old_applyMemberDecs(r, e, i, o, t), old_convertMetadataMapToFinal(e.prototype, i), old_applyClassDecs(r, e, o, a), old_convertMetadataMapToFinal(e, o), r;
4219 }
4220 function applyDecs2203Factory() {
4221 function createAddInitializerMethod(e, t) {
4222 return function (r) {
4223 !function (e, t) {
4224 if (e.v) throw new Error("attempted to call addInitializer after decoration was finished");
4225 }(t), assertCallable(r, "An initializer"), e.push(r);
4226 };
4227 }
4228 function memberDec(e, t, r, a, n, i, s, o) {
4229 var c;
4230 switch (n) {
4231 case 1:
4232 c = "accessor";
4233 break;
4234 case 2:
4235 c = "method";
4236 break;
4237 case 3:
4238 c = "getter";
4239 break;
4240 case 4:
4241 c = "setter";
4242 break;
4243 default:
4244 c = "field";
4245 }
4246 var l,
4247 u,
4248 f = {
4249 kind: c,
4250 name: s ? "#" + t : t,
4251 static: i,
4252 private: s
4253 },
4254 p = {
4255 v: !1
4256 };
4257 0 !== n && (f.addInitializer = createAddInitializerMethod(a, p)), 0 === n ? s ? (l = r.get, u = r.set) : (l = function () {
4258 return this[t];
4259 }, u = function (e) {
4260 this[t] = e;
4261 }) : 2 === n ? l = function () {
4262 return r.value;
4263 } : (1 !== n && 3 !== n || (l = function () {
4264 return r.get.call(this);
4265 }), 1 !== n && 4 !== n || (u = function (e) {
4266 r.set.call(this, e);
4267 })), f.access = l && u ? {
4268 get: l,
4269 set: u
4270 } : l ? {
4271 get: l
4272 } : {
4273 set: u
4274 };
4275 try {
4276 return e(o, f);
4277 } finally {
4278 p.v = !0;
4279 }
4280 }
4281 function assertCallable(e, t) {
4282 if ("function" != typeof e) throw new TypeError(t + " must be a function");
4283 }
4284 function assertValidReturnValue(e, t) {
4285 var r = typeof t;
4286 if (1 === e) {
4287 if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
4288 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");
4289 } else if ("function" !== r) throw new TypeError((0 === e ? "field" : 10 === e ? "class" : "method") + " decorators must return a function or void 0");
4290 }
4291 function applyMemberDec(e, t, r, a, n, i, s, o) {
4292 var c,
4293 l,
4294 u,
4295 f,
4296 p,
4297 d,
4298 h = r[0];
4299 if (s ? c = 0 === n || 1 === n ? {
4300 get: r[3],
4301 set: r[4]
4302 } : 3 === n ? {
4303 get: r[3]
4304 } : 4 === n ? {
4305 set: r[3]
4306 } : {
4307 value: r[3]
4308 } : 0 !== n && (c = Object.getOwnPropertyDescriptor(t, a)), 1 === n ? u = {
4309 get: c.get,
4310 set: c.set
4311 } : 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 = {
4312 get: p,
4313 set: d
4314 }) : u = f);else for (var v = h.length - 1; v >= 0; v--) {
4315 var g;
4316 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 = {
4317 get: p,
4318 set: d
4319 }) : u = f, void 0 !== g && (void 0 === l ? l = g : "function" == typeof l ? l = [l, g] : l.push(g)));
4320 }
4321 if (0 === n || 1 === n) {
4322 if (void 0 === l) l = function (e, t) {
4323 return t;
4324 };else if ("function" != typeof l) {
4325 var y = l;
4326 l = function (e, t) {
4327 for (var r = t, a = 0; a < y.length; a++) r = y[a].call(e, r);
4328 return r;
4329 };
4330 } else {
4331 var m = l;
4332 l = function (e, t) {
4333 return m.call(e, t);
4334 };
4335 }
4336 e.push(l);
4337 }
4338 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) {
4339 return u.get.call(e, t);
4340 }), e.push(function (e, t) {
4341 return u.set.call(e, t);
4342 })) : 2 === n ? e.push(u) : e.push(function (e, t) {
4343 return u.call(e, t);
4344 }) : Object.defineProperty(t, a, c));
4345 }
4346 function pushInitializers(e, t) {
4347 t && e.push(function (e) {
4348 for (var r = 0; r < t.length; r++) t[r].call(e);
4349 return e;
4350 });
4351 }
4352 return function (e, t, r) {
4353 var a = [];
4354 return function (e, t, r) {
4355 for (var a, n, i = new Map(), s = new Map(), o = 0; o < r.length; o++) {
4356 var c = r[o];
4357 if (Array.isArray(c)) {
4358 var l,
4359 u,
4360 f = c[1],
4361 p = c[2],
4362 d = c.length > 3,
4363 h = f >= 5;
4364 if (h ? (l = t, 0 != (f -= 5) && (u = n = n || [])) : (l = t.prototype, 0 !== f && (u = a = a || [])), 0 !== f && !d) {
4365 var v = h ? s : i,
4366 g = v.get(p) || 0;
4367 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);
4368 !g && f > 2 ? v.set(p, f) : v.set(p, !0);
4369 }
4370 applyMemberDec(e, l, c, p, f, h, d, u);
4371 }
4372 }
4373 pushInitializers(e, a), pushInitializers(e, n);
4374 }(a, e, t), function (e, t, r) {
4375 if (r.length > 0) {
4376 for (var a = [], n = t, i = t.name, s = r.length - 1; s >= 0; s--) {
4377 var o = {
4378 v: !1
4379 };
4380 try {
4381 var c = r[s](n, {
4382 kind: "class",
4383 name: i,
4384 addInitializer: createAddInitializerMethod(a, o)
4385 });
4386 } finally {
4387 o.v = !0;
4388 }
4389 void 0 !== c && (assertValidReturnValue(10, c), n = c);
4390 }
4391 e.push(n, function () {
4392 for (var e = 0; e < a.length; e++) a[e].call(n);
4393 });
4394 }
4395 }(a, e, r), a;
4396 };
4397 }
4398 var applyDecs2203Impl;
4399 function _applyDecs2203(e, t, r) {
4400 return (applyDecs2203Impl = applyDecs2203Impl || applyDecs2203Factory())(e, t, r);
4401 }
4402 function applyDecs2203RFactory() {
4403 function createAddInitializerMethod(e, t) {
4404 return function (r) {
4405 !function (e, t) {
4406 if (e.v) throw new Error("attempted to call addInitializer after decoration was finished");
4407 }(t), assertCallable(r, "An initializer"), e.push(r);
4408 };
4409 }
4410 function memberDec(e, t, r, n, a, i, o, s) {
4411 var c;
4412 switch (a) {
4413 case 1:
4414 c = "accessor";
4415 break;
4416 case 2:
4417 c = "method";
4418 break;
4419 case 3:
4420 c = "getter";
4421 break;
4422 case 4:
4423 c = "setter";
4424 break;
4425 default:
4426 c = "field";
4427 }
4428 var l,
4429 u,
4430 f = {
4431 kind: c,
4432 name: o ? "#" + t : _toPropertyKey(t),
4433 static: i,
4434 private: o
4435 },
4436 p = {
4437 v: !1
4438 };
4439 0 !== a && (f.addInitializer = createAddInitializerMethod(n, p)), 0 === a ? o ? (l = r.get, u = r.set) : (l = function () {
4440 return this[t];
4441 }, u = function (e) {
4442 this[t] = e;
4443 }) : 2 === a ? l = function () {
4444 return r.value;
4445 } : (1 !== a && 3 !== a || (l = function () {
4446 return r.get.call(this);
4447 }), 1 !== a && 4 !== a || (u = function (e) {
4448 r.set.call(this, e);
4449 })), f.access = l && u ? {
4450 get: l,
4451 set: u
4452 } : l ? {
4453 get: l
4454 } : {
4455 set: u
4456 };
4457 try {
4458 return e(s, f);
4459 } finally {
4460 p.v = !0;
4461 }
4462 }
4463 function assertCallable(e, t) {
4464 if ("function" != typeof e) throw new TypeError(t + " must be a function");
4465 }
4466 function assertValidReturnValue(e, t) {
4467 var r = typeof t;
4468 if (1 === e) {
4469 if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
4470 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");
4471 } else if ("function" !== r) throw new TypeError((0 === e ? "field" : 10 === e ? "class" : "method") + " decorators must return a function or void 0");
4472 }
4473 function applyMemberDec(e, t, r, n, a, i, o, s) {
4474 var c,
4475 l,
4476 u,
4477 f,
4478 p,
4479 d,
4480 h,
4481 v = r[0];
4482 if (o ? (0 === a || 1 === a ? (c = {
4483 get: r[3],
4484 set: r[4]
4485 }, u = "get") : 3 === a ? (c = {
4486 get: r[3]
4487 }, u = "get") : 4 === a ? (c = {
4488 set: r[3]
4489 }, u = "set") : c = {
4490 value: r[3]
4491 }, 0 !== a && (1 === a && _setFunctionName(r[4], "#" + n, "set"), _setFunctionName(r[3], "#" + n, u))) : 0 !== a && (c = Object.getOwnPropertyDescriptor(t, n)), 1 === a ? f = {
4492 get: c.get,
4493 set: c.set
4494 } : 2 === a ? f = c.value : 3 === a ? f = c.get : 4 === a && (f = c.set), "function" == typeof v) void 0 !== (p = memberDec(v, n, c, s, a, i, o, f)) && (assertValidReturnValue(a, p), 0 === a ? l = p : 1 === a ? (l = p.init, d = p.get || f.get, h = p.set || f.set, f = {
4495 get: d,
4496 set: h
4497 }) : f = p);else for (var g = v.length - 1; g >= 0; g--) {
4498 var y;
4499 void 0 !== (p = memberDec(v[g], n, c, s, a, i, o, f)) && (assertValidReturnValue(a, p), 0 === a ? y = p : 1 === a ? (y = p.init, d = p.get || f.get, h = p.set || f.set, f = {
4500 get: d,
4501 set: h
4502 }) : f = p, void 0 !== y && (void 0 === l ? l = y : "function" == typeof l ? l = [l, y] : l.push(y)));
4503 }
4504 if (0 === a || 1 === a) {
4505 if (void 0 === l) l = function (e, t) {
4506 return t;
4507 };else if ("function" != typeof l) {
4508 var m = l;
4509 l = function (e, t) {
4510 for (var r = t, n = 0; n < m.length; n++) r = m[n].call(e, r);
4511 return r;
4512 };
4513 } else {
4514 var b = l;
4515 l = function (e, t) {
4516 return b.call(e, t);
4517 };
4518 }
4519 e.push(l);
4520 }
4521 0 !== a && (1 === a ? (c.get = f.get, c.set = f.set) : 2 === a ? c.value = f : 3 === a ? c.get = f : 4 === a && (c.set = f), o ? 1 === a ? (e.push(function (e, t) {
4522 return f.get.call(e, t);
4523 }), e.push(function (e, t) {
4524 return f.set.call(e, t);
4525 })) : 2 === a ? e.push(f) : e.push(function (e, t) {
4526 return f.call(e, t);
4527 }) : Object.defineProperty(t, n, c));
4528 }
4529 function applyMemberDecs(e, t) {
4530 for (var r, n, a = [], i = new Map(), o = new Map(), s = 0; s < t.length; s++) {
4531 var c = t[s];
4532 if (Array.isArray(c)) {
4533 var l,
4534 u,
4535 f = c[1],
4536 p = c[2],
4537 d = c.length > 3,
4538 h = f >= 5;
4539 if (h ? (l = e, 0 != (f -= 5) && (u = n = n || [])) : (l = e.prototype, 0 !== f && (u = r = r || [])), 0 !== f && !d) {
4540 var v = h ? o : i,
4541 g = v.get(p) || 0;
4542 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);
4543 !g && f > 2 ? v.set(p, f) : v.set(p, !0);
4544 }
4545 applyMemberDec(a, l, c, p, f, h, d, u);
4546 }
4547 }
4548 return pushInitializers(a, r), pushInitializers(a, n), a;
4549 }
4550 function pushInitializers(e, t) {
4551 t && e.push(function (e) {
4552 for (var r = 0; r < t.length; r++) t[r].call(e);
4553 return e;
4554 });
4555 }
4556 return function (e, t, r) {
4557 return {
4558 e: applyMemberDecs(e, t),
4559 get c() {
4560 return function (e, t) {
4561 if (t.length > 0) {
4562 for (var r = [], n = e, a = e.name, i = t.length - 1; i >= 0; i--) {
4563 var o = {
4564 v: !1
4565 };
4566 try {
4567 var s = t[i](n, {
4568 kind: "class",
4569 name: a,
4570 addInitializer: createAddInitializerMethod(r, o)
4571 });
4572 } finally {
4573 o.v = !0;
4574 }
4575 void 0 !== s && (assertValidReturnValue(10, s), n = s);
4576 }
4577 return [n, function () {
4578 for (var e = 0; e < r.length; e++) r[e].call(n);
4579 }];
4580 }
4581 }(e, r);
4582 }
4583 };
4584 };
4585 }
4586 function _applyDecs2203R(e, t, r) {
4587 return (_applyDecs2203R = applyDecs2203RFactory())(e, t, r);
4588 }
4589 function applyDecs2301Factory() {
4590 function createAddInitializerMethod(e, t) {
4591 return function (r) {
4592 !function (e, t) {
4593 if (e.v) throw new Error("attempted to call addInitializer after decoration was finished");
4594 }(t), assertCallable(r, "An initializer"), e.push(r);
4595 };
4596 }
4597 function assertInstanceIfPrivate(e, t) {
4598 if (!e(t)) throw new TypeError("Attempted to access private element on non-instance");
4599 }
4600 function memberDec(e, t, r, n, a, i, s, o, c) {
4601 var u;
4602 switch (a) {
4603 case 1:
4604 u = "accessor";
4605 break;
4606 case 2:
4607 u = "method";
4608 break;
4609 case 3:
4610 u = "getter";
4611 break;
4612 case 4:
4613 u = "setter";
4614 break;
4615 default:
4616 u = "field";
4617 }
4618 var l,
4619 f,
4620 p = {
4621 kind: u,
4622 name: s ? "#" + t : _toPropertyKey(t),
4623 static: i,
4624 private: s
4625 },
4626 d = {
4627 v: !1
4628 };
4629 if (0 !== a && (p.addInitializer = createAddInitializerMethod(n, d)), s || 0 !== a && 2 !== a) {
4630 if (2 === a) l = function (e) {
4631 return assertInstanceIfPrivate(c, e), r.value;
4632 };else {
4633 var h = 0 === a || 1 === a;
4634 (h || 3 === a) && (l = s ? function (e) {
4635 return assertInstanceIfPrivate(c, e), r.get.call(e);
4636 } : function (e) {
4637 return r.get.call(e);
4638 }), (h || 4 === a) && (f = s ? function (e, t) {
4639 assertInstanceIfPrivate(c, e), r.set.call(e, t);
4640 } : function (e, t) {
4641 r.set.call(e, t);
4642 });
4643 }
4644 } else l = function (e) {
4645 return e[t];
4646 }, 0 === a && (f = function (e, r) {
4647 e[t] = r;
4648 });
4649 var v = s ? c.bind() : function (e) {
4650 return t in e;
4651 };
4652 p.access = l && f ? {
4653 get: l,
4654 set: f,
4655 has: v
4656 } : l ? {
4657 get: l,
4658 has: v
4659 } : {
4660 set: f,
4661 has: v
4662 };
4663 try {
4664 return e(o, p);
4665 } finally {
4666 d.v = !0;
4667 }
4668 }
4669 function assertCallable(e, t) {
4670 if ("function" != typeof e) throw new TypeError(t + " must be a function");
4671 }
4672 function assertValidReturnValue(e, t) {
4673 var r = typeof t;
4674 if (1 === e) {
4675 if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
4676 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");
4677 } else if ("function" !== r) throw new TypeError((0 === e ? "field" : 10 === e ? "class" : "method") + " decorators must return a function or void 0");
4678 }
4679 function curryThis2(e) {
4680 return function (t) {
4681 e(this, t);
4682 };
4683 }
4684 function applyMemberDec(e, t, r, n, a, i, s, o, c) {
4685 var u,
4686 l,
4687 f,
4688 p,
4689 d,
4690 h,
4691 v,
4692 y,
4693 g = r[0];
4694 if (s ? (0 === a || 1 === a ? (u = {
4695 get: (d = r[3], function () {
4696 return d(this);
4697 }),
4698 set: curryThis2(r[4])
4699 }, f = "get") : 3 === a ? (u = {
4700 get: r[3]
4701 }, f = "get") : 4 === a ? (u = {
4702 set: r[3]
4703 }, f = "set") : u = {
4704 value: r[3]
4705 }, 0 !== a && (1 === a && _setFunctionName(u.set, "#" + n, "set"), _setFunctionName(u[f || "value"], "#" + n, f))) : 0 !== a && (u = Object.getOwnPropertyDescriptor(t, n)), 1 === a ? p = {
4706 get: u.get,
4707 set: u.set
4708 } : 2 === a ? p = u.value : 3 === a ? p = u.get : 4 === a && (p = u.set), "function" == typeof g) void 0 !== (h = memberDec(g, n, u, o, a, i, s, p, c)) && (assertValidReturnValue(a, h), 0 === a ? l = h : 1 === a ? (l = h.init, v = h.get || p.get, y = h.set || p.set, p = {
4709 get: v,
4710 set: y
4711 }) : p = h);else for (var m = g.length - 1; m >= 0; m--) {
4712 var b;
4713 void 0 !== (h = memberDec(g[m], n, u, o, a, i, s, p, c)) && (assertValidReturnValue(a, h), 0 === a ? b = h : 1 === a ? (b = h.init, v = h.get || p.get, y = h.set || p.set, p = {
4714 get: v,
4715 set: y
4716 }) : p = h, void 0 !== b && (void 0 === l ? l = b : "function" == typeof l ? l = [l, b] : l.push(b)));
4717 }
4718 if (0 === a || 1 === a) {
4719 if (void 0 === l) l = function (e, t) {
4720 return t;
4721 };else if ("function" != typeof l) {
4722 var I = l;
4723 l = function (e, t) {
4724 for (var r = t, n = 0; n < I.length; n++) r = I[n].call(e, r);
4725 return r;
4726 };
4727 } else {
4728 var w = l;
4729 l = function (e, t) {
4730 return w.call(e, t);
4731 };
4732 }
4733 e.push(l);
4734 }
4735 0 !== a && (1 === a ? (u.get = p.get, u.set = p.set) : 2 === a ? u.value = p : 3 === a ? u.get = p : 4 === a && (u.set = p), s ? 1 === a ? (e.push(function (e, t) {
4736 return p.get.call(e, t);
4737 }), e.push(function (e, t) {
4738 return p.set.call(e, t);
4739 })) : 2 === a ? e.push(p) : e.push(function (e, t) {
4740 return p.call(e, t);
4741 }) : Object.defineProperty(t, n, u));
4742 }
4743 function applyMemberDecs(e, t, r) {
4744 for (var n, a, i, s = [], o = new Map(), c = new Map(), u = 0; u < t.length; u++) {
4745 var l = t[u];
4746 if (Array.isArray(l)) {
4747 var f,
4748 p,
4749 d = l[1],
4750 h = l[2],
4751 v = l.length > 3,
4752 y = d >= 5,
4753 g = r;
4754 if (y ? (f = e, 0 != (d -= 5) && (p = a = a || []), v && !i && (i = function (t) {
4755 return _checkInRHS(t) === e;
4756 }), g = i) : (f = e.prototype, 0 !== d && (p = n = n || [])), 0 !== d && !v) {
4757 var m = y ? c : o,
4758 b = m.get(h) || 0;
4759 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);
4760 !b && d > 2 ? m.set(h, d) : m.set(h, !0);
4761 }
4762 applyMemberDec(s, f, l, h, d, y, v, p, g);
4763 }
4764 }
4765 return pushInitializers(s, n), pushInitializers(s, a), s;
4766 }
4767 function pushInitializers(e, t) {
4768 t && e.push(function (e) {
4769 for (var r = 0; r < t.length; r++) t[r].call(e);
4770 return e;
4771 });
4772 }
4773 return function (e, t, r, n) {
4774 return {
4775 e: applyMemberDecs(e, t, n),
4776 get c() {
4777 return function (e, t) {
4778 if (t.length > 0) {
4779 for (var r = [], n = e, a = e.name, i = t.length - 1; i >= 0; i--) {
4780 var s = {
4781 v: !1
4782 };
4783 try {
4784 var o = t[i](n, {
4785 kind: "class",
4786 name: a,
4787 addInitializer: createAddInitializerMethod(r, s)
4788 });
4789 } finally {
4790 s.v = !0;
4791 }
4792 void 0 !== o && (assertValidReturnValue(10, o), n = o);
4793 }
4794 return [n, function () {
4795 for (var e = 0; e < r.length; e++) r[e].call(n);
4796 }];
4797 }
4798 }(e, r);
4799 }
4800 };
4801 };
4802 }
4803 function _applyDecs2301(e, t, r, n) {
4804 return (_applyDecs2301 = applyDecs2301Factory())(e, t, r, n);
4805 }
4806 function _applyDecs2305(e, t, r, n, o, a) {
4807 function i(e, t, r) {
4808 return function (n, o) {
4809 return r && r(n), e[t].call(n, o);
4810 };
4811 }
4812 function c(e, t) {
4813 for (var r = 0; r < e.length; r++) e[r].call(t);
4814 return t;
4815 }
4816 function s(e, t, r, n) {
4817 if ("function" != typeof e && (n || void 0 !== e)) throw new TypeError(t + " must " + (r || "be") + " a function" + (n ? "" : " or undefined"));
4818 return e;
4819 }
4820 function applyDec(e, t, r, n, o, a, c, u, l, f, p, d, h) {
4821 function m(e) {
4822 if (!h(e)) throw new TypeError("Attempted to access private element on non-instance");
4823 }
4824 var y,
4825 v = t[0],
4826 g = t[3],
4827 b = !u;
4828 if (!b) {
4829 r || Array.isArray(v) || (v = [v]);
4830 var w = {},
4831 S = [],
4832 A = 3 === o ? "get" : 4 === o || d ? "set" : "value";
4833 f ? (p || d ? w = {
4834 get: _setFunctionName(function () {
4835 return g(this);
4836 }, n, "get"),
4837 set: function (e) {
4838 t[4](this, e);
4839 }
4840 } : w[A] = g, p || _setFunctionName(w[A], n, 2 === o ? "" : A)) : p || (w = Object.getOwnPropertyDescriptor(e, n));
4841 }
4842 for (var P = e, j = v.length - 1; j >= 0; j -= r ? 2 : 1) {
4843 var D = v[j],
4844 E = r ? v[j - 1] : void 0,
4845 I = {},
4846 O = {
4847 kind: ["field", "accessor", "method", "getter", "setter", "class"][o],
4848 name: n,
4849 metadata: a,
4850 addInitializer: function (e, t) {
4851 if (e.v) throw new Error("attempted to call addInitializer after decoration was finished");
4852 s(t, "An initializer", "be", !0), c.push(t);
4853 }.bind(null, I)
4854 };
4855 try {
4856 if (b) (y = s(D.call(E, P, O), "class decorators", "return")) && (P = y);else {
4857 var k, F;
4858 O.static = l, O.private = f, f ? 2 === o ? k = function (e) {
4859 return m(e), w.value;
4860 } : (o < 4 && (k = i(w, "get", m)), 3 !== o && (F = i(w, "set", m))) : (k = function (e) {
4861 return e[n];
4862 }, (o < 2 || 4 === o) && (F = function (e, t) {
4863 e[n] = t;
4864 }));
4865 var N = O.access = {
4866 has: f ? h.bind() : function (e) {
4867 return n in e;
4868 }
4869 };
4870 if (k && (N.get = k), F && (N.set = F), P = D.call(E, d ? {
4871 get: w.get,
4872 set: w.set
4873 } : w[A], O), d) {
4874 if ("object" == typeof P && P) (y = s(P.get, "accessor.get")) && (w.get = y), (y = s(P.set, "accessor.set")) && (w.set = y), (y = s(P.init, "accessor.init")) && S.push(y);else if (void 0 !== P) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
4875 } else s(P, (p ? "field" : "method") + " decorators", "return") && (p ? S.push(P) : w[A] = P);
4876 }
4877 } finally {
4878 I.v = !0;
4879 }
4880 }
4881 return (p || d) && u.push(function (e, t) {
4882 for (var r = S.length - 1; r >= 0; r--) t = S[r].call(e, t);
4883 return t;
4884 }), p || b || (f ? d ? u.push(i(w, "get"), i(w, "set")) : u.push(2 === o ? w[A] : i.call.bind(w[A])) : Object.defineProperty(e, n, w)), P;
4885 }
4886 function u(e, t) {
4887 return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), {
4888 configurable: !0,
4889 enumerable: !0,
4890 value: t
4891 });
4892 }
4893 if (arguments.length >= 6) var l = a[Symbol.metadata || Symbol.for("Symbol.metadata")];
4894 var f = Object.create(null == l ? null : l),
4895 p = function (e, t, r, n) {
4896 var o,
4897 a,
4898 i = [],
4899 s = function (t) {
4900 return _checkInRHS(t) === e;
4901 },
4902 u = new Map();
4903 function l(e) {
4904 e && i.push(c.bind(null, e));
4905 }
4906 for (var f = 0; f < t.length; f++) {
4907 var p = t[f];
4908 if (Array.isArray(p)) {
4909 var d = p[1],
4910 h = p[2],
4911 m = p.length > 3,
4912 y = 16 & d,
4913 v = !!(8 & d),
4914 g = 0 == (d &= 7),
4915 b = h + "/" + v;
4916 if (!g && !m) {
4917 var w = u.get(b);
4918 if (!0 === w || 3 === w && 4 !== d || 4 === w && 3 !== d) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + h);
4919 u.set(b, !(d > 2) || d);
4920 }
4921 applyDec(v ? e : e.prototype, p, y, m ? "#" + h : _toPropertyKey(h), d, n, v ? a = a || [] : o = o || [], i, v, m, g, 1 === d, v && m ? s : r);
4922 }
4923 }
4924 return l(o), l(a), i;
4925 }(e, t, o, f);
4926 return r.length || u(e, f), {
4927 e: p,
4928 get c() {
4929 var t = [];
4930 return r.length && [u(applyDec(e, [r], n, e.name, 5, f, t), f), c.bind(null, t, e)];
4931 }
4932 };
4933 }
4934 function _asyncGeneratorDelegate(t) {
4935 var e = {},
4936 n = !1;
4937 function pump(e, r) {
4938 return n = !0, r = new Promise(function (n) {
4939 n(t[e](r));
4940 }), {
4941 done: !1,
4942 value: new _OverloadYield(r, 1)
4943 };
4944 }
4945 return e["undefined" != typeof Symbol && Symbol.iterator || "@@iterator"] = function () {
4946 return this;
4947 }, e.next = function (t) {
4948 return n ? (n = !1, t) : pump("next", t);
4949 }, "function" == typeof t.throw && (e.throw = function (t) {
4950 if (n) throw n = !1, t;
4951 return pump("throw", t);
4952 }), "function" == typeof t.return && (e.return = function (t) {
4953 return n ? (n = !1, t) : pump("return", t);
4954 }), e;
4955 }
4956 function _asyncIterator(r) {
4957 var n,
4958 t,
4959 o,
4960 e = 2;
4961 for ("undefined" != typeof Symbol && (t = Symbol.asyncIterator, o = Symbol.iterator); e--;) {
4962 if (t && null != (n = r[t])) return n.call(r);
4963 if (o && null != (n = r[o])) return new AsyncFromSyncIterator(n.call(r));
4964 t = "@@asyncIterator", o = "@@iterator";
4965 }
4966 throw new TypeError("Object is not async iterable");
4967 }
4968 function AsyncFromSyncIterator(r) {
4969 function AsyncFromSyncIteratorContinuation(r) {
4970 if (Object(r) !== r) return Promise.reject(new TypeError(r + " is not an object."));
4971 var n = r.done;
4972 return Promise.resolve(r.value).then(function (r) {
4973 return {
4974 value: r,
4975 done: n
4976 };
4977 });
4978 }
4979 return AsyncFromSyncIterator = function (r) {
4980 this.s = r, this.n = r.next;
4981 }, AsyncFromSyncIterator.prototype = {
4982 s: null,
4983 n: null,
4984 next: function () {
4985 return AsyncFromSyncIteratorContinuation(this.n.apply(this.s, arguments));
4986 },
4987 return: function (r) {
4988 var n = this.s.return;
4989 return void 0 === n ? Promise.resolve({
4990 value: r,
4991 done: !0
4992 }) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments));
4993 },
4994 throw: function (r) {
4995 var n = this.s.return;
4996 return void 0 === n ? Promise.reject(r) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments));
4997 }
4998 }, new AsyncFromSyncIterator(r);
4999 }
5000 function _awaitAsyncGenerator(e) {
5001 return new _OverloadYield(e, 0);
5002 }
5003 function _callSuper(t, o, e) {
5004 return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
5005 }
5006 function _checkInRHS(e) {
5007 if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null"));
5008 return e;
5009 }
5010 function _construct(t, e, r) {
5011 if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
5012 var o = [null];
5013 o.push.apply(o, e);
5014 var p = new (t.bind.apply(t, o))();
5015 return r && _setPrototypeOf(p, r.prototype), p;
5016 }
5017 function _defineAccessor(e, r, n, t) {
5018 var c = {
5019 configurable: !0,
5020 enumerable: !0
5021 };
5022 return c[e] = t, Object.defineProperty(r, n, c);
5023 }
5024 function dispose_SuppressedError(r, e) {
5025 return "undefined" != typeof SuppressedError ? dispose_SuppressedError = SuppressedError : (dispose_SuppressedError = function (r, e) {
5026 this.suppressed = e, this.error = r, this.stack = new Error().stack;
5027 }, dispose_SuppressedError.prototype = Object.create(Error.prototype, {
5028 constructor: {
5029 value: dispose_SuppressedError,
5030 writable: !0,
5031 configurable: !0
5032 }
5033 })), new dispose_SuppressedError(r, e);
5034 }
5035 function _dispose(r, e, s) {
5036 function next() {
5037 for (; r.length > 0;) try {
5038 var o = r.pop(),
5039 p = o.d.call(o.v);
5040 if (o.a) return Promise.resolve(p).then(next, err);
5041 } catch (r) {
5042 return err(r);
5043 }
5044 if (s) throw e;
5045 }
5046 function err(r) {
5047 return e = s ? new dispose_SuppressedError(e, r) : r, s = !0, next();
5048 }
5049 return next();
5050 }
5051 function _importDeferProxy(e) {
5052 var t = null,
5053 constValue = function (e) {
5054 return function () {
5055 return e;
5056 };
5057 },
5058 proxy = function (r) {
5059 return function (n, o, f) {
5060 return null === t && (t = e()), r(t, o, f);
5061 };
5062 };
5063 return new Proxy({}, {
5064 defineProperty: constValue(!1),
5065 deleteProperty: constValue(!1),
5066 get: proxy(Reflect.get),
5067 getOwnPropertyDescriptor: proxy(Reflect.getOwnPropertyDescriptor),
5068 getPrototypeOf: constValue(null),
5069 isExtensible: constValue(!1),
5070 has: proxy(Reflect.has),
5071 ownKeys: proxy(Reflect.ownKeys),
5072 preventExtensions: constValue(!0),
5073 set: constValue(!1),
5074 setPrototypeOf: constValue(!1)
5075 });
5076 }
5077 function _getRequireWildcardCache(e) {
5078 if ("function" != typeof WeakMap) return null;
5079 var r = new WeakMap(),
5080 t = new WeakMap();
5081 return (_getRequireWildcardCache = function (e) {
5082 return e ? t : r;
5083 })(e);
5084 }
5085 function _interopRequireWildcard(e, r) {
5086 if (!r && e && e.__esModule) return e;
5087 if (null === e || "object" != typeof e && "function" != typeof e) return {
5088 default: e
5089 };
5090 var t = _getRequireWildcardCache(r);
5091 if (t && t.has(e)) return t.get(e);
5092 var n = {
5093 __proto__: null
5094 },
5095 a = Object.defineProperty && Object.getOwnPropertyDescriptor;
5096 for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) {
5097 var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;
5098 i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u];
5099 }
5100 return n.default = e, t && t.set(e, n), n;
5101 }
5102 function _isNativeReflectConstruct() {
5103 try {
5104 var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
5105 } catch (t) {}
5106 return (_isNativeReflectConstruct = function () {
5107 return !!t;
5108 })();
5109 }
5110 function _iterableToArrayLimit(r, l) {
5111 var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
5112 if (null != t) {
5113 var e,
5114 n,
5115 i,
5116 u,
5117 a = [],
5118 f = !0,
5119 o = !1;
5120 try {
5121 if (i = (t = t.call(r)).next, 0 === l) {
5122 if (Object(t) !== t) return;
5123 f = !1;
5124 } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
5125 } catch (r) {
5126 o = !0, n = r;
5127 } finally {
5128 try {
5129 if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
5130 } finally {
5131 if (o) throw n;
5132 }
5133 }
5134 return a;
5135 }
5136 }
5137 function _iterableToArrayLimitLoose(e, r) {
5138 var t = e && ("undefined" != typeof Symbol && e[Symbol.iterator] || e["@@iterator"]);
5139 if (null != t) {
5140 var o,
5141 l = [];
5142 for (t = t.call(e); e.length < r && !(o = t.next()).done;) l.push(o.value);
5143 return l;
5144 }
5145 }
5146 var REACT_ELEMENT_TYPE;
5147 function _jsx(e, r, E, l) {
5148 REACT_ELEMENT_TYPE || (REACT_ELEMENT_TYPE = "function" == typeof Symbol && Symbol.for && Symbol.for("react.element") || 60103);
5149 var o = e && e.defaultProps,
5150 n = arguments.length - 3;
5151 if (r || 0 === n || (r = {
5152 children: void 0
5153 }), 1 === n) r.children = l;else if (n > 1) {
5154 for (var t = new Array(n), f = 0; f < n; f++) t[f] = arguments[f + 3];
5155 r.children = t;
5156 }
5157 if (r && o) for (var i in o) void 0 === r[i] && (r[i] = o[i]);else r || (r = o || {});
5158 return {
5159 $$typeof: REACT_ELEMENT_TYPE,
5160 type: e,
5161 key: void 0 === E ? null : "" + E,
5162 ref: null,
5163 props: r,
5164 _owner: null
5165 };
5166 }
5167 function ownKeys(e, r) {
5168 var t = Object.keys(e);
5169 if (Object.getOwnPropertySymbols) {
5170 var o = Object.getOwnPropertySymbols(e);
5171 r && (o = o.filter(function (r) {
5172 return Object.getOwnPropertyDescriptor(e, r).enumerable;
5173 })), t.push.apply(t, o);
5174 }
5175 return t;
5176 }
5177 function _objectSpread2(e) {
5178 for (var r = 1; r < arguments.length; r++) {
5179 var t = null != arguments[r] ? arguments[r] : {};
5180 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
5181 _defineProperty(e, r, t[r]);
5182 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
5183 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
5184 });
5185 }
5186 return e;
5187 }
5188 function _regeneratorRuntime() {
5189 "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
5190 _regeneratorRuntime = function () {
5191 return e;
5192 };
5193 var t,
5194 e = {},
5195 r = Object.prototype,
5196 n = r.hasOwnProperty,
5197 o = Object.defineProperty || function (t, e, r) {
5198 t[e] = r.value;
5199 },
5200 i = "function" == typeof Symbol ? Symbol : {},
5201 a = i.iterator || "@@iterator",
5202 c = i.asyncIterator || "@@asyncIterator",
5203 u = i.toStringTag || "@@toStringTag";
5204 function define(t, e, r) {
5205 return Object.defineProperty(t, e, {
5206 value: r,
5207 enumerable: !0,
5208 configurable: !0,
5209 writable: !0
5210 }), t[e];
5211 }
5212 try {
5213 define({}, "");
5214 } catch (t) {
5215 define = function (t, e, r) {
5216 return t[e] = r;
5217 };
5218 }
5219 function wrap(t, e, r, n) {
5220 var i = e && e.prototype instanceof Generator ? e : Generator,
5221 a = Object.create(i.prototype),
5222 c = new Context(n || []);
5223 return o(a, "_invoke", {
5224 value: makeInvokeMethod(t, r, c)
5225 }), a;
5226 }
5227 function tryCatch(t, e, r) {
5228 try {
5229 return {
5230 type: "normal",
5231 arg: t.call(e, r)
5232 };
5233 } catch (t) {
5234 return {
5235 type: "throw",
5236 arg: t
5237 };
5238 }
5239 }
5240 e.wrap = wrap;
5241 var h = "suspendedStart",
5242 l = "suspendedYield",
5243 f = "executing",
5244 s = "completed",
5245 y = {};
5246 function Generator() {}
5247 function GeneratorFunction() {}
5248 function GeneratorFunctionPrototype() {}
5249 var p = {};
5250 define(p, a, function () {
5251 return this;
5252 });
5253 var d = Object.getPrototypeOf,
5254 v = d && d(d(values([])));
5255 v && v !== r && n.call(v, a) && (p = v);
5256 var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p);
5257 function defineIteratorMethods(t) {
5258 ["next", "throw", "return"].forEach(function (e) {
5259 define(t, e, function (t) {
5260 return this._invoke(e, t);
5261 });
5262 });
5263 }
5264 function AsyncIterator(t, e) {
5265 function invoke(r, o, i, a) {
5266 var c = tryCatch(t[r], t, o);
5267 if ("throw" !== c.type) {
5268 var u = c.arg,
5269 h = u.value;
5270 return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) {
5271 invoke("next", t, i, a);
5272 }, function (t) {
5273 invoke("throw", t, i, a);
5274 }) : e.resolve(h).then(function (t) {
5275 u.value = t, i(u);
5276 }, function (t) {
5277 return invoke("throw", t, i, a);
5278 });
5279 }
5280 a(c.arg);
5281 }
5282 var r;
5283 o(this, "_invoke", {
5284 value: function (t, n) {
5285 function callInvokeWithMethodAndArg() {
5286 return new e(function (e, r) {
5287 invoke(t, n, e, r);
5288 });
5289 }
5290 return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
5291 }
5292 });
5293 }
5294 function makeInvokeMethod(e, r, n) {
5295 var o = h;
5296 return function (i, a) {
5297 if (o === f) throw new Error("Generator is already running");
5298 if (o === s) {
5299 if ("throw" === i) throw a;
5300 return {
5301 value: t,
5302 done: !0
5303 };
5304 }
5305 for (n.method = i, n.arg = a;;) {
5306 var c = n.delegate;
5307 if (c) {
5308 var u = maybeInvokeDelegate(c, n);
5309 if (u) {
5310 if (u === y) continue;
5311 return u;
5312 }
5313 }
5314 if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) {
5315 if (o === h) throw o = s, n.arg;
5316 n.dispatchException(n.arg);
5317 } else "return" === n.method && n.abrupt("return", n.arg);
5318 o = f;
5319 var p = tryCatch(e, r, n);
5320 if ("normal" === p.type) {
5321 if (o = n.done ? s : l, p.arg === y) continue;
5322 return {
5323 value: p.arg,
5324 done: n.done
5325 };
5326 }
5327 "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg);
5328 }
5329 };
5330 }
5331 function maybeInvokeDelegate(e, r) {
5332 var n = r.method,
5333 o = e.iterator[n];
5334 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;
5335 var i = tryCatch(o, e.iterator, r.arg);
5336 if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y;
5337 var a = i.arg;
5338 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);
5339 }
5340 function pushTryEntry(t) {
5341 var e = {
5342 tryLoc: t[0]
5343 };
5344 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e);
5345 }
5346 function resetTryEntry(t) {
5347 var e = t.completion || {};
5348 e.type = "normal", delete e.arg, t.completion = e;
5349 }
5350 function Context(t) {
5351 this.tryEntries = [{
5352 tryLoc: "root"
5353 }], t.forEach(pushTryEntry, this), this.reset(!0);
5354 }
5355 function values(e) {
5356 if (e || "" === e) {
5357 var r = e[a];
5358 if (r) return r.call(e);
5359 if ("function" == typeof e.next) return e;
5360 if (!isNaN(e.length)) {
5361 var o = -1,
5362 i = function next() {
5363 for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next;
5364 return next.value = t, next.done = !0, next;
5365 };
5366 return i.next = i;
5367 }
5368 }
5369 throw new TypeError(typeof e + " is not iterable");
5370 }
5371 return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", {
5372 value: GeneratorFunctionPrototype,
5373 configurable: !0
5374 }), o(GeneratorFunctionPrototype, "constructor", {
5375 value: GeneratorFunction,
5376 configurable: !0
5377 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) {
5378 var e = "function" == typeof t && t.constructor;
5379 return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name));
5380 }, e.mark = function (t) {
5381 return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t;
5382 }, e.awrap = function (t) {
5383 return {
5384 __await: t
5385 };
5386 }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () {
5387 return this;
5388 }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) {
5389 void 0 === i && (i = Promise);
5390 var a = new AsyncIterator(wrap(t, r, n, o), i);
5391 return e.isGeneratorFunction(r) ? a : a.next().then(function (t) {
5392 return t.done ? t.value : a.next();
5393 });
5394 }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () {
5395 return this;
5396 }), define(g, "toString", function () {
5397 return "[object Generator]";
5398 }), e.keys = function (t) {
5399 var e = Object(t),
5400 r = [];
5401 for (var n in e) r.push(n);
5402 return r.reverse(), function next() {
5403 for (; r.length;) {
5404 var t = r.pop();
5405 if (t in e) return next.value = t, next.done = !1, next;
5406 }
5407 return next.done = !0, next;
5408 };
5409 }, e.values = values, Context.prototype = {
5410 constructor: Context,
5411 reset: function (e) {
5412 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);
5413 },
5414 stop: function () {
5415 this.done = !0;
5416 var t = this.tryEntries[0].completion;
5417 if ("throw" === t.type) throw t.arg;
5418 return this.rval;
5419 },
5420 dispatchException: function (e) {
5421 if (this.done) throw e;
5422 var r = this;
5423 function handle(n, o) {
5424 return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o;
5425 }
5426 for (var o = this.tryEntries.length - 1; o >= 0; --o) {
5427 var i = this.tryEntries[o],
5428 a = i.completion;
5429 if ("root" === i.tryLoc) return handle("end");
5430 if (i.tryLoc <= this.prev) {
5431 var c = n.call(i, "catchLoc"),
5432 u = n.call(i, "finallyLoc");
5433 if (c && u) {
5434 if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
5435 if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
5436 } else if (c) {
5437 if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
5438 } else {
5439 if (!u) throw new Error("try statement without catch or finally");
5440 if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
5441 }
5442 }
5443 }
5444 },
5445 abrupt: function (t, e) {
5446 for (var r = this.tryEntries.length - 1; r >= 0; --r) {
5447 var o = this.tryEntries[r];
5448 if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
5449 var i = o;
5450 break;
5451 }
5452 }
5453 i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
5454 var a = i ? i.completion : {};
5455 return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a);
5456 },
5457 complete: function (t, e) {
5458 if ("throw" === t.type) throw t.arg;
5459 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;
5460 },
5461 finish: function (t) {
5462 for (var e = this.tryEntries.length - 1; e >= 0; --e) {
5463 var r = this.tryEntries[e];
5464 if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y;
5465 }
5466 },
5467 catch: function (t) {
5468 for (var e = this.tryEntries.length - 1; e >= 0; --e) {
5469 var r = this.tryEntries[e];
5470 if (r.tryLoc === t) {
5471 var n = r.completion;
5472 if ("throw" === n.type) {
5473 var o = n.arg;
5474 resetTryEntry(r);
5475 }
5476 return o;
5477 }
5478 }
5479 throw new Error("illegal catch attempt");
5480 },
5481 delegateYield: function (e, r, n) {
5482 return this.delegate = {
5483 iterator: values(e),
5484 resultName: r,
5485 nextLoc: n
5486 }, "next" === this.method && (this.arg = t), y;
5487 }
5488 }, e;
5489 }
5490 function _setFunctionName(e, t, n) {
5491 "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : "");
5492 try {
5493 Object.defineProperty(e, "name", {
5494 configurable: !0,
5495 value: n ? n + " " + t : t
5496 });
5497 } catch (e) {}
5498 return e;
5499 }
5500 function _toPrimitive(t, r) {
5501 if ("object" != typeof t || !t) return t;
5502 var e = t[Symbol.toPrimitive];
5503 if (void 0 !== e) {
5504 var i = e.call(t, r || "default");
5505 if ("object" != typeof i) return i;
5506 throw new TypeError("@@toPrimitive must return a primitive value.");
5507 }
5508 return ("string" === r ? String : Number)(t);
5509 }
5510 function _toPropertyKey(t) {
5511 var i = _toPrimitive(t, "string");
5512 return "symbol" == typeof i ? i : String(i);
5513 }
5514 function _typeof(o) {
5515 "@babel/helpers - typeof";
5516
5517 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
5518 return typeof o;
5519 } : function (o) {
5520 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
5521 }, _typeof(o);
5522 }
5523 function _using(o, n, e) {
5524 if (null == n) return n;
5525 if (Object(n) !== n) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
5526 if (e) var r = n[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
5527 if (null == r && (r = n[Symbol.dispose || Symbol.for("Symbol.dispose")]), "function" != typeof r) throw new TypeError("Property [Symbol.dispose] is not a function.");
5528 return o.push({
5529 v: n,
5530 d: r,
5531 a: e
5532 }), n;
5533 }
5534 function _usingCtx() {
5535 var r = "function" == typeof SuppressedError ? SuppressedError : function (r, n) {
5536 var e = new Error();
5537 return e.name = "SuppressedError", e.suppressed = n, e.error = r, e;
5538 },
5539 n = {},
5540 e = [];
5541 function using(r, n) {
5542 if (null != n) {
5543 if (Object(n) !== n) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
5544 if (r) var o = n[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
5545 if (null == o && (o = n[Symbol.dispose || Symbol.for("Symbol.dispose")]), "function" != typeof o) throw new TypeError("Property [Symbol.dispose] is not a function.");
5546 e.push({
5547 v: n,
5548 d: o,
5549 a: r
5550 });
5551 }
5552 return n;
5553 }
5554 return {
5555 e: n,
5556 u: using.bind(null, !1),
5557 a: using.bind(null, !0),
5558 d: function () {
5559 var o = this.e;
5560 function next() {
5561 for (; r = e.pop();) try {
5562 var r,
5563 t = r.d.call(r.v);
5564 if (r.a) return Promise.resolve(t).then(next, err);
5565 } catch (r) {
5566 return err(r);
5567 }
5568 if (o !== n) throw o;
5569 }
5570 function err(e) {
5571 return o = o !== n ? new r(o, e) : e, next();
5572 }
5573 return next();
5574 }
5575 };
5576 }
5577 function _wrapRegExp() {
5578 _wrapRegExp = function (e, r) {
5579 return new BabelRegExp(e, void 0, r);
5580 };
5581 var e = RegExp.prototype,
5582 r = new WeakMap();
5583 function BabelRegExp(e, t, p) {
5584 var o = new RegExp(e, t);
5585 return r.set(o, p || r.get(e)), _setPrototypeOf(o, BabelRegExp.prototype);
5586 }
5587 function buildGroups(e, t) {
5588 var p = r.get(t);
5589 return Object.keys(p).reduce(function (r, t) {
5590 var o = p[t];
5591 if ("number" == typeof o) r[t] = e[o];else {
5592 for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++;
5593 r[t] = e[o[i]];
5594 }
5595 return r;
5596 }, Object.create(null));
5597 }
5598 return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) {
5599 var t = e.exec.call(this, r);
5600 if (t) {
5601 t.groups = buildGroups(t, this);
5602 var p = t.indices;
5603 p && (p.groups = buildGroups(p, this));
5604 }
5605 return t;
5606 }, BabelRegExp.prototype[Symbol.replace] = function (t, p) {
5607 if ("string" == typeof p) {
5608 var o = r.get(this);
5609 return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)>/g, function (e, r) {
5610 var t = o[r];
5611 return "$" + (Array.isArray(t) ? t.join("$") : t);
5612 }));
5613 }
5614 if ("function" == typeof p) {
5615 var i = this;
5616 return e[Symbol.replace].call(this, t, function () {
5617 var e = arguments;
5618 return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e);
5619 });
5620 }
5621 return e[Symbol.replace].call(this, t, p);
5622 }, _wrapRegExp.apply(this, arguments);
5623 }
5624 function _AwaitValue(value) {
5625 this.wrapped = value;
5626 }
5627 function _wrapAsyncGenerator(fn) {
5628 return function () {
5629 return new _AsyncGenerator(fn.apply(this, arguments));
5630 };
5631 }
5632 function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
5633 try {
5634 var info = gen[key](arg);
5635 var value = info.value;
5636 } catch (error) {
5637 reject(error);
5638 return;
5639 }
5640 if (info.done) {
5641 resolve(value);
5642 } else {
5643 Promise.resolve(value).then(_next, _throw);
5644 }
5645 }
5646 function _asyncToGenerator(fn) {
5647 return function () {
5648 var self = this,
5649 args = arguments;
5650 return new Promise(function (resolve, reject) {
5651 var gen = fn.apply(self, args);
5652 function _next(value) {
5653 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
5654 }
5655 function _throw(err) {
5656 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
5657 }
5658 _next(undefined);
5659 });
5660 };
5661 }
5662 function _classCallCheck(instance, Constructor) {
5663 if (!(instance instanceof Constructor)) {
5664 throw new TypeError("Cannot call a class as a function");
5665 }
5666 }
5667 function _defineProperties(target, props) {
5668 for (var i = 0; i < props.length; i++) {
5669 var descriptor = props[i];
5670 descriptor.enumerable = descriptor.enumerable || false;
5671 descriptor.configurable = true;
5672 if ("value" in descriptor) descriptor.writable = true;
5673 Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
5674 }
5675 }
5676 function _createClass(Constructor, protoProps, staticProps) {
5677 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
5678 if (staticProps) _defineProperties(Constructor, staticProps);
5679 Object.defineProperty(Constructor, "prototype", {
5680 writable: false
5681 });
5682 return Constructor;
5683 }
5684 function _defineEnumerableProperties(obj, descs) {
5685 for (var key in descs) {
5686 var desc = descs[key];
5687 desc.configurable = desc.enumerable = true;
5688 if ("value" in desc) desc.writable = true;
5689 Object.defineProperty(obj, key, desc);
5690 }
5691 if (Object.getOwnPropertySymbols) {
5692 var objectSymbols = Object.getOwnPropertySymbols(descs);
5693 for (var i = 0; i < objectSymbols.length; i++) {
5694 var sym = objectSymbols[i];
5695 var desc = descs[sym];
5696 desc.configurable = desc.enumerable = true;
5697 if ("value" in desc) desc.writable = true;
5698 Object.defineProperty(obj, sym, desc);
5699 }
5700 }
5701 return obj;
5702 }
5703 function _defaults(obj, defaults) {
5704 var keys = Object.getOwnPropertyNames(defaults);
5705 for (var i = 0; i < keys.length; i++) {
5706 var key = keys[i];
5707 var value = Object.getOwnPropertyDescriptor(defaults, key);
5708 if (value && value.configurable && obj[key] === undefined) {
5709 Object.defineProperty(obj, key, value);
5710 }
5711 }
5712 return obj;
5713 }
5714 function _defineProperty(obj, key, value) {
5715 key = _toPropertyKey(key);
5716 if (key in obj) {
5717 Object.defineProperty(obj, key, {
5718 value: value,
5719 enumerable: true,
5720 configurable: true,
5721 writable: true
5722 });
5723 } else {
5724 obj[key] = value;
5725 }
5726 return obj;
5727 }
5728 function _extends() {
5729 _extends = Object.assign ? Object.assign.bind() : function (target) {
5730 for (var i = 1; i < arguments.length; i++) {
5731 var source = arguments[i];
5732 for (var key in source) {
5733 if (Object.prototype.hasOwnProperty.call(source, key)) {
5734 target[key] = source[key];
5735 }
5736 }
5737 }
5738 return target;
5739 };
5740 return _extends.apply(this, arguments);
5741 }
5742 function _objectSpread(target) {
5743 for (var i = 1; i < arguments.length; i++) {
5744 var source = arguments[i] != null ? Object(arguments[i]) : {};
5745 var ownKeys = Object.keys(source);
5746 if (typeof Object.getOwnPropertySymbols === 'function') {
5747 ownKeys.push.apply(ownKeys, Object.getOwnPropertySymbols(source).filter(function (sym) {
5748 return Object.getOwnPropertyDescriptor(source, sym).enumerable;
5749 }));
5750 }
5751 ownKeys.forEach(function (key) {
5752 _defineProperty(target, key, source[key]);
5753 });
5754 }
5755 return target;
5756 }
5757 function _inherits(subClass, superClass) {
5758 if (typeof superClass !== "function" && superClass !== null) {
5759 throw new TypeError("Super expression must either be null or a function");
5760 }
5761 subClass.prototype = Object.create(superClass && superClass.prototype, {
5762 constructor: {
5763 value: subClass,
5764 writable: true,
5765 configurable: true
5766 }
5767 });
5768 Object.defineProperty(subClass, "prototype", {
5769 writable: false
5770 });
5771 if (superClass) _setPrototypeOf(subClass, superClass);
5772 }
5773 function _inheritsLoose(subClass, superClass) {
5774 subClass.prototype = Object.create(superClass.prototype);
5775 subClass.prototype.constructor = subClass;
5776 _setPrototypeOf(subClass, superClass);
5777 }
5778 function _getPrototypeOf(o) {
5779 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
5780 return o.__proto__ || Object.getPrototypeOf(o);
5781 };
5782 return _getPrototypeOf(o);
5783 }
5784 function _setPrototypeOf(o, p) {
5785 _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
5786 o.__proto__ = p;
5787 return o;
5788 };
5789 return _setPrototypeOf(o, p);
5790 }
5791 function _isNativeFunction(fn) {
5792 try {
5793 return Function.toString.call(fn).indexOf("[native code]") !== -1;
5794 } catch (e) {
5795 return typeof fn === "function";
5796 }
5797 }
5798 function _wrapNativeSuper(Class) {
5799 var _cache = typeof Map === "function" ? new Map() : undefined;
5800 _wrapNativeSuper = function _wrapNativeSuper(Class) {
5801 if (Class === null || !_isNativeFunction(Class)) return Class;
5802 if (typeof Class !== "function") {
5803 throw new TypeError("Super expression must either be null or a function");
5804 }
5805 if (typeof _cache !== "undefined") {
5806 if (_cache.has(Class)) return _cache.get(Class);
5807 _cache.set(Class, Wrapper);
5808 }
5809 function Wrapper() {
5810 return _construct(Class, arguments, _getPrototypeOf(this).constructor);
5811 }
5812 Wrapper.prototype = Object.create(Class.prototype, {
5813 constructor: {
5814 value: Wrapper,
5815 enumerable: false,
5816 writable: true,
5817 configurable: true
5818 }
5819 });
5820 return _setPrototypeOf(Wrapper, Class);
5821 };
5822 return _wrapNativeSuper(Class);
5823 }
5824 function _instanceof(left, right) {
5825 if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
5826 return !!right[Symbol.hasInstance](left);
5827 } else {
5828 return left instanceof right;
5829 }
5830 }
5831 function _interopRequireDefault(obj) {
5832 return obj && obj.__esModule ? obj : {
5833 default: obj
5834 };
5835 }
5836 function _newArrowCheck(innerThis, boundThis) {
5837 if (innerThis !== boundThis) {
5838 throw new TypeError("Cannot instantiate an arrow function");
5839 }
5840 }
5841 function _objectDestructuringEmpty(obj) {
5842 if (obj == null) throw new TypeError("Cannot destructure " + obj);
5843 }
5844 function _objectWithoutPropertiesLoose(source, excluded) {
5845 if (source == null) return {};
5846 var target = {};
5847 var sourceKeys = Object.keys(source);
5848 var key, i;
5849 for (i = 0; i < sourceKeys.length; i++) {
5850 key = sourceKeys[i];
5851 if (excluded.indexOf(key) >= 0) continue;
5852 target[key] = source[key];
5853 }
5854 return target;
5855 }
5856 function _objectWithoutProperties(source, excluded) {
5857 if (source == null) return {};
5858 var target = _objectWithoutPropertiesLoose(source, excluded);
5859 var key, i;
5860 if (Object.getOwnPropertySymbols) {
5861 var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
5862 for (i = 0; i < sourceSymbolKeys.length; i++) {
5863 key = sourceSymbolKeys[i];
5864 if (excluded.indexOf(key) >= 0) continue;
5865 if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
5866 target[key] = source[key];
5867 }
5868 }
5869 return target;
5870 }
5871 function _assertThisInitialized(self) {
5872 if (self === void 0) {
5873 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
5874 }
5875 return self;
5876 }
5877 function _possibleConstructorReturn(self, call) {
5878 if (call && (typeof call === "object" || typeof call === "function")) {
5879 return call;
5880 } else if (call !== void 0) {
5881 throw new TypeError("Derived constructors may only return object or undefined");
5882 }
5883 return _assertThisInitialized(self);
5884 }
5885 function _createSuper(Derived) {
5886 var hasNativeReflectConstruct = _isNativeReflectConstruct();
5887 return function _createSuperInternal() {
5888 var Super = _getPrototypeOf(Derived),
5889 result;
5890 if (hasNativeReflectConstruct) {
5891 var NewTarget = _getPrototypeOf(this).constructor;
5892 result = Reflect.construct(Super, arguments, NewTarget);
5893 } else {
5894 result = Super.apply(this, arguments);
5895 }
5896 return _possibleConstructorReturn(this, result);
5897 };
5898 }
5899 function _superPropBase(object, property) {
5900 while (!Object.prototype.hasOwnProperty.call(object, property)) {
5901 object = _getPrototypeOf(object);
5902 if (object === null) break;
5903 }
5904 return object;
5905 }
5906 function _get() {
5907 if (typeof Reflect !== "undefined" && Reflect.get) {
5908 _get = Reflect.get.bind();
5909 } else {
5910 _get = function _get(target, property, receiver) {
5911 var base = _superPropBase(target, property);
5912 if (!base) return;
5913 var desc = Object.getOwnPropertyDescriptor(base, property);
5914 if (desc.get) {
5915 return desc.get.call(arguments.length < 3 ? target : receiver);
5916 }
5917 return desc.value;
5918 };
5919 }
5920 return _get.apply(this, arguments);
5921 }
5922 function set(target, property, value, receiver) {
5923 if (typeof Reflect !== "undefined" && Reflect.set) {
5924 set = Reflect.set;
5925 } else {
5926 set = function set(target, property, value, receiver) {
5927 var base = _superPropBase(target, property);
5928 var desc;
5929 if (base) {
5930 desc = Object.getOwnPropertyDescriptor(base, property);
5931 if (desc.set) {
5932 desc.set.call(receiver, value);
5933 return true;
5934 } else if (!desc.writable) {
5935 return false;
5936 }
5937 }
5938 desc = Object.getOwnPropertyDescriptor(receiver, property);
5939 if (desc) {
5940 if (!desc.writable) {
5941 return false;
5942 }
5943 desc.value = value;
5944 Object.defineProperty(receiver, property, desc);
5945 } else {
5946 _defineProperty(receiver, property, value);
5947 }
5948 return true;
5949 };
5950 }
5951 return set(target, property, value, receiver);
5952 }
5953 function _set(target, property, value, receiver, isStrict) {
5954 var s = set(target, property, value, receiver || target);
5955 if (!s && isStrict) {
5956 throw new TypeError('failed to set property');
5957 }
5958 return value;
5959 }
5960 function _taggedTemplateLiteral(strings, raw) {
5961 if (!raw) {
5962 raw = strings.slice(0);
5963 }
5964 return Object.freeze(Object.defineProperties(strings, {
5965 raw: {
5966 value: Object.freeze(raw)
5967 }
5968 }));
5969 }
5970 function _taggedTemplateLiteralLoose(strings, raw) {
5971 if (!raw) {
5972 raw = strings.slice(0);
5973 }
5974 strings.raw = raw;
5975 return strings;
5976 }
5977 function _readOnlyError(name) {
5978 throw new TypeError("\"" + name + "\" is read-only");
5979 }
5980 function _writeOnlyError(name) {
5981 throw new TypeError("\"" + name + "\" is write-only");
5982 }
5983 function _classNameTDZError(name) {
5984 throw new ReferenceError("Class \"" + name + "\" cannot be referenced in computed property keys.");
5985 }
5986 function _temporalUndefined() {}
5987 function _tdz(name) {
5988 throw new ReferenceError(name + " is not defined - temporal dead zone");
5989 }
5990 function _temporalRef(val, name) {
5991 return val === _temporalUndefined ? _tdz(name) : val;
5992 }
5993 function _slicedToArray(arr, i) {
5994 return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
5995 }
5996 function _slicedToArrayLoose(arr, i) {
5997 return _arrayWithHoles(arr) || _iterableToArrayLimitLoose(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
5998 }
5999 function _toArray(arr) {
6000 return _arrayWithHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableRest();
6001 }
6002 function _toConsumableArray(arr) {
6003 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
6004 }
6005 function _arrayWithoutHoles(arr) {
6006 if (Array.isArray(arr)) return _arrayLikeToArray(arr);
6007 }
6008 function _arrayWithHoles(arr) {
6009 if (Array.isArray(arr)) return arr;
6010 }
6011 function _maybeArrayLike(next, arr, i) {
6012 if (arr && !Array.isArray(arr) && typeof arr.length === "number") {
6013 var len = arr.length;
6014 return _arrayLikeToArray(arr, i !== void 0 && i < len ? i : len);
6015 }
6016 return next(arr, i);
6017 }
6018 function _iterableToArray(iter) {
6019 if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
6020 }
6021 function _unsupportedIterableToArray(o, minLen) {
6022 if (!o) return;
6023 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
6024 var n = Object.prototype.toString.call(o).slice(8, -1);
6025 if (n === "Object" && o.constructor) n = o.constructor.name;
6026 if (n === "Map" || n === "Set") return Array.from(o);
6027 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
6028 }
6029 function _arrayLikeToArray(arr, len) {
6030 if (len == null || len > arr.length) len = arr.length;
6031 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
6032 return arr2;
6033 }
6034 function _nonIterableSpread() {
6035 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
6036 }
6037 function _nonIterableRest() {
6038 throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
6039 }
6040 function _createForOfIteratorHelper(o, allowArrayLike) {
6041 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
6042 if (!it) {
6043 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
6044 if (it) o = it;
6045 var i = 0;
6046 var F = function () {};
6047 return {
6048 s: F,
6049 n: function () {
6050 if (i >= o.length) return {
6051 done: true
6052 };
6053 return {
6054 done: false,
6055 value: o[i++]
6056 };
6057 },
6058 e: function (e) {
6059 throw e;
6060 },
6061 f: F
6062 };
6063 }
6064 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
6065 }
6066 var normalCompletion = true,
6067 didErr = false,
6068 err;
6069 return {
6070 s: function () {
6071 it = it.call(o);
6072 },
6073 n: function () {
6074 var step = it.next();
6075 normalCompletion = step.done;
6076 return step;
6077 },
6078 e: function (e) {
6079 didErr = true;
6080 err = e;
6081 },
6082 f: function () {
6083 try {
6084 if (!normalCompletion && it.return != null) it.return();
6085 } finally {
6086 if (didErr) throw err;
6087 }
6088 }
6089 };
6090 }
6091 function _createForOfIteratorHelperLoose(o, allowArrayLike) {
6092 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
6093 if (it) return (it = it.call(o)).next.bind(it);
6094 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
6095 if (it) o = it;
6096 var i = 0;
6097 return function () {
6098 if (i >= o.length) return {
6099 done: true
6100 };
6101 return {
6102 done: false,
6103 value: o[i++]
6104 };
6105 };
6106 }
6107 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
6108 }
6109 function _skipFirstGeneratorNext(fn) {
6110 return function () {
6111 var it = fn.apply(this, arguments);
6112 it.next();
6113 return it;
6114 };
6115 }
6116 function _initializerWarningHelper(descriptor, context) {
6117 throw new Error('Decorating class property failed. Please ensure that ' + 'transform-class-properties is enabled and runs after the decorators transform.');
6118 }
6119 function _initializerDefineProperty(target, property, descriptor, context) {
6120 if (!descriptor) return;
6121 Object.defineProperty(target, property, {
6122 enumerable: descriptor.enumerable,
6123 configurable: descriptor.configurable,
6124 writable: descriptor.writable,
6125 value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
6126 });
6127 }
6128 function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
6129 var desc = {};
6130 Object.keys(descriptor).forEach(function (key) {
6131 desc[key] = descriptor[key];
6132 });
6133 desc.enumerable = !!desc.enumerable;
6134 desc.configurable = !!desc.configurable;
6135 if ('value' in desc || desc.initializer) {
6136 desc.writable = true;
6137 }
6138 desc = decorators.slice().reverse().reduce(function (desc, decorator) {
6139 return decorator(target, property, desc) || desc;
6140 }, desc);
6141 if (context && desc.initializer !== void 0) {
6142 desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
6143 desc.initializer = undefined;
6144 }
6145 if (desc.initializer === void 0) {
6146 Object.defineProperty(target, property, desc);
6147 desc = null;
6148 }
6149 return desc;
6150 }
6151 var id$1 = 0;
6152 function _classPrivateFieldLooseKey(name) {
6153 return "__private_" + id$1++ + "_" + name;
6154 }
6155 function _classPrivateFieldLooseBase(receiver, privateKey) {
6156 if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
6157 throw new TypeError("attempted to use private field on non-instance");
6158 }
6159 return receiver;
6160 }
6161 function _classPrivateFieldGet(receiver, privateMap) {
6162 var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get");
6163 return _classApplyDescriptorGet(receiver, descriptor);
6164 }
6165 function _classPrivateFieldSet(receiver, privateMap, value) {
6166 var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set");
6167 _classApplyDescriptorSet(receiver, descriptor, value);
6168 return value;
6169 }
6170 function _classPrivateFieldDestructureSet(receiver, privateMap) {
6171 var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set");
6172 return _classApplyDescriptorDestructureSet(receiver, descriptor);
6173 }
6174 function _classExtractFieldDescriptor(receiver, privateMap, action) {
6175 if (!privateMap.has(receiver)) {
6176 throw new TypeError("attempted to " + action + " private field on non-instance");
6177 }
6178 return privateMap.get(receiver);
6179 }
6180 function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) {
6181 _classCheckPrivateStaticAccess(receiver, classConstructor);
6182 _classCheckPrivateStaticFieldDescriptor(descriptor, "get");
6183 return _classApplyDescriptorGet(receiver, descriptor);
6184 }
6185 function _classStaticPrivateFieldSpecSet(receiver, classConstructor, descriptor, value) {
6186 _classCheckPrivateStaticAccess(receiver, classConstructor);
6187 _classCheckPrivateStaticFieldDescriptor(descriptor, "set");
6188 _classApplyDescriptorSet(receiver, descriptor, value);
6189 return value;
6190 }
6191 function _classStaticPrivateMethodGet(receiver, classConstructor, method) {
6192 _classCheckPrivateStaticAccess(receiver, classConstructor);
6193 return method;
6194 }
6195 function _classStaticPrivateMethodSet() {
6196 throw new TypeError("attempted to set read only static private field");
6197 }
6198 function _classApplyDescriptorGet(receiver, descriptor) {
6199 if (descriptor.get) {
6200 return descriptor.get.call(receiver);
6201 }
6202 return descriptor.value;
6203 }
6204 function _classApplyDescriptorSet(receiver, descriptor, value) {
6205 if (descriptor.set) {
6206 descriptor.set.call(receiver, value);
6207 } else {
6208 if (!descriptor.writable) {
6209 throw new TypeError("attempted to set read only private field");
6210 }
6211 descriptor.value = value;
6212 }
6213 }
6214 function _classApplyDescriptorDestructureSet(receiver, descriptor) {
6215 if (descriptor.set) {
6216 if (!("__destrObj" in descriptor)) {
6217 descriptor.__destrObj = {
6218 set value(v) {
6219 descriptor.set.call(receiver, v);
6220 }
6221 };
6222 }
6223 return descriptor.__destrObj;
6224 } else {
6225 if (!descriptor.writable) {
6226 throw new TypeError("attempted to set read only private field");
6227 }
6228 return descriptor;
6229 }
6230 }
6231 function _classStaticPrivateFieldDestructureSet(receiver, classConstructor, descriptor) {
6232 _classCheckPrivateStaticAccess(receiver, classConstructor);
6233 _classCheckPrivateStaticFieldDescriptor(descriptor, "set");
6234 return _classApplyDescriptorDestructureSet(receiver, descriptor);
6235 }
6236 function _classCheckPrivateStaticAccess(receiver, classConstructor) {
6237 if (receiver !== classConstructor) {
6238 throw new TypeError("Private static access of wrong provenance");
6239 }
6240 }
6241 function _classCheckPrivateStaticFieldDescriptor(descriptor, action) {
6242 if (descriptor === undefined) {
6243 throw new TypeError("attempted to " + action + " private static field before its declaration");
6244 }
6245 }
6246 function _decorate(decorators, factory, superClass, mixins) {
6247 var api = _getDecoratorsApi();
6248 if (mixins) {
6249 for (var i = 0; i < mixins.length; i++) {
6250 api = mixins[i](api);
6251 }
6252 }
6253 var r = factory(function initialize(O) {
6254 api.initializeInstanceElements(O, decorated.elements);
6255 }, superClass);
6256 var decorated = api.decorateClass(_coalesceClassElements(r.d.map(_createElementDescriptor)), decorators);
6257 api.initializeClassElements(r.F, decorated.elements);
6258 return api.runClassFinishers(r.F, decorated.finishers);
6259 }
6260 function _getDecoratorsApi() {
6261 _getDecoratorsApi = function () {
6262 return api;
6263 };
6264 var api = {
6265 elementsDefinitionOrder: [["method"], ["field"]],
6266 initializeInstanceElements: function (O, elements) {
6267 ["method", "field"].forEach(function (kind) {
6268 elements.forEach(function (element) {
6269 if (element.kind === kind && element.placement === "own") {
6270 this.defineClassElement(O, element);
6271 }
6272 }, this);
6273 }, this);
6274 },
6275 initializeClassElements: function (F, elements) {
6276 var proto = F.prototype;
6277 ["method", "field"].forEach(function (kind) {
6278 elements.forEach(function (element) {
6279 var placement = element.placement;
6280 if (element.kind === kind && (placement === "static" || placement === "prototype")) {
6281 var receiver = placement === "static" ? F : proto;
6282 this.defineClassElement(receiver, element);
6283 }
6284 }, this);
6285 }, this);
6286 },
6287 defineClassElement: function (receiver, element) {
6288 var descriptor = element.descriptor;
6289 if (element.kind === "field") {
6290 var initializer = element.initializer;
6291 descriptor = {
6292 enumerable: descriptor.enumerable,
6293 writable: descriptor.writable,
6294 configurable: descriptor.configurable,
6295 value: initializer === void 0 ? void 0 : initializer.call(receiver)
6296 };
6297 }
6298 Object.defineProperty(receiver, element.key, descriptor);
6299 },
6300 decorateClass: function (elements, decorators) {
6301 var newElements = [];
6302 var finishers = [];
6303 var placements = {
6304 static: [],
6305 prototype: [],
6306 own: []
6307 };
6308 elements.forEach(function (element) {
6309 this.addElementPlacement(element, placements);
6310 }, this);
6311 elements.forEach(function (element) {
6312 if (!_hasDecorators(element)) return newElements.push(element);
6313 var elementFinishersExtras = this.decorateElement(element, placements);
6314 newElements.push(elementFinishersExtras.element);
6315 newElements.push.apply(newElements, elementFinishersExtras.extras);
6316 finishers.push.apply(finishers, elementFinishersExtras.finishers);
6317 }, this);
6318 if (!decorators) {
6319 return {
6320 elements: newElements,
6321 finishers: finishers
6322 };
6323 }
6324 var result = this.decorateConstructor(newElements, decorators);
6325 finishers.push.apply(finishers, result.finishers);
6326 result.finishers = finishers;
6327 return result;
6328 },
6329 addElementPlacement: function (element, placements, silent) {
6330 var keys = placements[element.placement];
6331 if (!silent && keys.indexOf(element.key) !== -1) {
6332 throw new TypeError("Duplicated element (" + element.key + ")");
6333 }
6334 keys.push(element.key);
6335 },
6336 decorateElement: function (element, placements) {
6337 var extras = [];
6338 var finishers = [];
6339 for (var decorators = element.decorators, i = decorators.length - 1; i >= 0; i--) {
6340 var keys = placements[element.placement];
6341 keys.splice(keys.indexOf(element.key), 1);
6342 var elementObject = this.fromElementDescriptor(element);
6343 var elementFinisherExtras = this.toElementFinisherExtras((0, decorators[i])(elementObject) || elementObject);
6344 element = elementFinisherExtras.element;
6345 this.addElementPlacement(element, placements);
6346 if (elementFinisherExtras.finisher) {
6347 finishers.push(elementFinisherExtras.finisher);
6348 }
6349 var newExtras = elementFinisherExtras.extras;
6350 if (newExtras) {
6351 for (var j = 0; j < newExtras.length; j++) {
6352 this.addElementPlacement(newExtras[j], placements);
6353 }
6354 extras.push.apply(extras, newExtras);
6355 }
6356 }
6357 return {
6358 element: element,
6359 finishers: finishers,
6360 extras: extras
6361 };
6362 },
6363 decorateConstructor: function (elements, decorators) {
6364 var finishers = [];
6365 for (var i = decorators.length - 1; i >= 0; i--) {
6366 var obj = this.fromClassDescriptor(elements);
6367 var elementsAndFinisher = this.toClassDescriptor((0, decorators[i])(obj) || obj);
6368 if (elementsAndFinisher.finisher !== undefined) {
6369 finishers.push(elementsAndFinisher.finisher);
6370 }
6371 if (elementsAndFinisher.elements !== undefined) {
6372 elements = elementsAndFinisher.elements;
6373 for (var j = 0; j < elements.length - 1; j++) {
6374 for (var k = j + 1; k < elements.length; k++) {
6375 if (elements[j].key === elements[k].key && elements[j].placement === elements[k].placement) {
6376 throw new TypeError("Duplicated element (" + elements[j].key + ")");
6377 }
6378 }
6379 }
6380 }
6381 }
6382 return {
6383 elements: elements,
6384 finishers: finishers
6385 };
6386 },
6387 fromElementDescriptor: function (element) {
6388 var obj = {
6389 kind: element.kind,
6390 key: element.key,
6391 placement: element.placement,
6392 descriptor: element.descriptor
6393 };
6394 var desc = {
6395 value: "Descriptor",
6396 configurable: true
6397 };
6398 Object.defineProperty(obj, Symbol.toStringTag, desc);
6399 if (element.kind === "field") obj.initializer = element.initializer;
6400 return obj;
6401 },
6402 toElementDescriptors: function (elementObjects) {
6403 if (elementObjects === undefined) return;
6404 return _toArray(elementObjects).map(function (elementObject) {
6405 var element = this.toElementDescriptor(elementObject);
6406 this.disallowProperty(elementObject, "finisher", "An element descriptor");
6407 this.disallowProperty(elementObject, "extras", "An element descriptor");
6408 return element;
6409 }, this);
6410 },
6411 toElementDescriptor: function (elementObject) {
6412 var kind = String(elementObject.kind);
6413 if (kind !== "method" && kind !== "field") {
6414 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 + '"');
6415 }
6416 var key = _toPropertyKey(elementObject.key);
6417 var placement = String(elementObject.placement);
6418 if (placement !== "static" && placement !== "prototype" && placement !== "own") {
6419 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 + '"');
6420 }
6421 var descriptor = elementObject.descriptor;
6422 this.disallowProperty(elementObject, "elements", "An element descriptor");
6423 var element = {
6424 kind: kind,
6425 key: key,
6426 placement: placement,
6427 descriptor: Object.assign({}, descriptor)
6428 };
6429 if (kind !== "field") {
6430 this.disallowProperty(elementObject, "initializer", "A method descriptor");
6431 } else {
6432 this.disallowProperty(descriptor, "get", "The property descriptor of a field descriptor");
6433 this.disallowProperty(descriptor, "set", "The property descriptor of a field descriptor");
6434 this.disallowProperty(descriptor, "value", "The property descriptor of a field descriptor");
6435 element.initializer = elementObject.initializer;
6436 }
6437 return element;
6438 },
6439 toElementFinisherExtras: function (elementObject) {
6440 var element = this.toElementDescriptor(elementObject);
6441 var finisher = _optionalCallableProperty(elementObject, "finisher");
6442 var extras = this.toElementDescriptors(elementObject.extras);
6443 return {
6444 element: element,
6445 finisher: finisher,
6446 extras: extras
6447 };
6448 },
6449 fromClassDescriptor: function (elements) {
6450 var obj = {
6451 kind: "class",
6452 elements: elements.map(this.fromElementDescriptor, this)
6453 };
6454 var desc = {
6455 value: "Descriptor",
6456 configurable: true
6457 };
6458 Object.defineProperty(obj, Symbol.toStringTag, desc);
6459 return obj;
6460 },
6461 toClassDescriptor: function (obj) {
6462 var kind = String(obj.kind);
6463 if (kind !== "class") {
6464 throw new TypeError('A class descriptor\'s .kind property must be "class", but a decorator' + ' created a class descriptor with .kind "' + kind + '"');
6465 }
6466 this.disallowProperty(obj, "key", "A class descriptor");
6467 this.disallowProperty(obj, "placement", "A class descriptor");
6468 this.disallowProperty(obj, "descriptor", "A class descriptor");
6469 this.disallowProperty(obj, "initializer", "A class descriptor");
6470 this.disallowProperty(obj, "extras", "A class descriptor");
6471 var finisher = _optionalCallableProperty(obj, "finisher");
6472 var elements = this.toElementDescriptors(obj.elements);
6473 return {
6474 elements: elements,
6475 finisher: finisher
6476 };
6477 },
6478 runClassFinishers: function (constructor, finishers) {
6479 for (var i = 0; i < finishers.length; i++) {
6480 var newConstructor = (0, finishers[i])(constructor);
6481 if (newConstructor !== undefined) {
6482 if (typeof newConstructor !== "function") {
6483 throw new TypeError("Finishers must return a constructor.");
6484 }
6485 constructor = newConstructor;
6486 }
6487 }
6488 return constructor;
6489 },
6490 disallowProperty: function (obj, name, objectType) {
6491 if (obj[name] !== undefined) {
6492 throw new TypeError(objectType + " can't have a ." + name + " property.");
6493 }
6494 }
6495 };
6496 return api;
6497 }
6498 function _createElementDescriptor(def) {
6499 var key = _toPropertyKey(def.key);
6500 var descriptor;
6501 if (def.kind === "method") {
6502 descriptor = {
6503 value: def.value,
6504 writable: true,
6505 configurable: true,
6506 enumerable: false
6507 };
6508 } else if (def.kind === "get") {
6509 descriptor = {
6510 get: def.value,
6511 configurable: true,
6512 enumerable: false
6513 };
6514 } else if (def.kind === "set") {
6515 descriptor = {
6516 set: def.value,
6517 configurable: true,
6518 enumerable: false
6519 };
6520 } else if (def.kind === "field") {
6521 descriptor = {
6522 configurable: true,
6523 writable: true,
6524 enumerable: true
6525 };
6526 }
6527 var element = {
6528 kind: def.kind === "field" ? "field" : "method",
6529 key: key,
6530 placement: def.static ? "static" : def.kind === "field" ? "own" : "prototype",
6531 descriptor: descriptor
6532 };
6533 if (def.decorators) element.decorators = def.decorators;
6534 if (def.kind === "field") element.initializer = def.value;
6535 return element;
6536 }
6537 function _coalesceGetterSetter(element, other) {
6538 if (element.descriptor.get !== undefined) {
6539 other.descriptor.get = element.descriptor.get;
6540 } else {
6541 other.descriptor.set = element.descriptor.set;
6542 }
6543 }
6544 function _coalesceClassElements(elements) {
6545 var newElements = [];
6546 var isSameElement = function (other) {
6547 return other.kind === "method" && other.key === element.key && other.placement === element.placement;
6548 };
6549 for (var i = 0; i < elements.length; i++) {
6550 var element = elements[i];
6551 var other;
6552 if (element.kind === "method" && (other = newElements.find(isSameElement))) {
6553 if (_isDataDescriptor(element.descriptor) || _isDataDescriptor(other.descriptor)) {
6554 if (_hasDecorators(element) || _hasDecorators(other)) {
6555 throw new ReferenceError("Duplicated methods (" + element.key + ") can't be decorated.");
6556 }
6557 other.descriptor = element.descriptor;
6558 } else {
6559 if (_hasDecorators(element)) {
6560 if (_hasDecorators(other)) {
6561 throw new ReferenceError("Decorators can't be placed on different accessors with for " + "the same property (" + element.key + ").");
6562 }
6563 other.decorators = element.decorators;
6564 }
6565 _coalesceGetterSetter(element, other);
6566 }
6567 } else {
6568 newElements.push(element);
6569 }
6570 }
6571 return newElements;
6572 }
6573 function _hasDecorators(element) {
6574 return element.decorators && element.decorators.length;
6575 }
6576 function _isDataDescriptor(desc) {
6577 return desc !== undefined && !(desc.value === undefined && desc.writable === undefined);
6578 }
6579 function _optionalCallableProperty(obj, name) {
6580 var value = obj[name];
6581 if (value !== undefined && typeof value !== "function") {
6582 throw new TypeError("Expected '" + name + "' to be a function");
6583 }
6584 return value;
6585 }
6586 function _classPrivateMethodGet(receiver, privateSet, fn) {
6587 if (!privateSet.has(receiver)) {
6588 throw new TypeError("attempted to get private field on non-instance");
6589 }
6590 return fn;
6591 }
6592 function _checkPrivateRedeclaration(obj, privateCollection) {
6593 if (privateCollection.has(obj)) {
6594 throw new TypeError("Cannot initialize the same private elements twice on an object");
6595 }
6596 }
6597 function _classPrivateFieldInitSpec(obj, privateMap, value) {
6598 _checkPrivateRedeclaration(obj, privateMap);
6599 privateMap.set(obj, value);
6600 }
6601 function _classPrivateMethodInitSpec(obj, privateSet) {
6602 _checkPrivateRedeclaration(obj, privateSet);
6603 privateSet.add(obj);
6604 }
6605 function _classPrivateMethodSet() {
6606 throw new TypeError("attempted to reassign private method");
6607 }
6608 function _identity(x) {
6609 return x;
6610 }
6611 function _nullishReceiverError(r) {
6612 throw new TypeError("Cannot set property of null or undefined.");
6613 }
6614
6615 class Piece extends TrixObject {
6616 static registerType(type, constructor) {
6617 constructor.type = type;
6618 this.types[type] = constructor;
6619 }
6620 static fromJSON(pieceJSON) {
6621 const constructor = this.types[pieceJSON.type];
6622 if (constructor) {
6623 return constructor.fromJSON(pieceJSON);
6624 }
6625 }
6626 constructor(value) {
6627 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6628 super(...arguments);
6629 this.attributes = Hash.box(attributes);
6630 }
6631 copyWithAttributes(attributes) {
6632 return new this.constructor(this.getValue(), attributes);
6633 }
6634 copyWithAdditionalAttributes(attributes) {
6635 return this.copyWithAttributes(this.attributes.merge(attributes));
6636 }
6637 copyWithoutAttribute(attribute) {
6638 return this.copyWithAttributes(this.attributes.remove(attribute));
6639 }
6640 copy() {
6641 return this.copyWithAttributes(this.attributes);
6642 }
6643 getAttribute(attribute) {
6644 return this.attributes.get(attribute);
6645 }
6646 getAttributesHash() {
6647 return this.attributes;
6648 }
6649 getAttributes() {
6650 return this.attributes.toObject();
6651 }
6652 hasAttribute(attribute) {
6653 return this.attributes.has(attribute);
6654 }
6655 hasSameStringValueAsPiece(piece) {
6656 return piece && this.toString() === piece.toString();
6657 }
6658 hasSameAttributesAsPiece(piece) {
6659 return piece && (this.attributes === piece.attributes || this.attributes.isEqualTo(piece.attributes));
6660 }
6661 isBlockBreak() {
6662 return false;
6663 }
6664 isEqualTo(piece) {
6665 return super.isEqualTo(...arguments) || this.hasSameConstructorAs(piece) && this.hasSameStringValueAsPiece(piece) && this.hasSameAttributesAsPiece(piece);
6666 }
6667 isEmpty() {
6668 return this.length === 0;
6669 }
6670 isSerializable() {
6671 return true;
6672 }
6673 toJSON() {
6674 return {
6675 type: this.constructor.type,
6676 attributes: this.getAttributes()
6677 };
6678 }
6679 contentsForInspection() {
6680 return {
6681 type: this.constructor.type,
6682 attributes: this.attributes.inspect()
6683 };
6684 }
6685
6686 // Grouping
6687
6688 canBeGrouped() {
6689 return this.hasAttribute("href");
6690 }
6691 canBeGroupedWith(piece) {
6692 return this.getAttribute("href") === piece.getAttribute("href");
6693 }
6694
6695 // Splittable
6696
6697 getLength() {
6698 return this.length;
6699 }
6700 canBeConsolidatedWith(piece) {
6701 return false;
6702 }
6703 }
6704 _defineProperty(Piece, "types", {});
6705
6706 class ImagePreloadOperation extends Operation {
6707 constructor(url) {
6708 super(...arguments);
6709 this.url = url;
6710 }
6711 perform(callback) {
6712 const image = new Image();
6713 image.onload = () => {
6714 image.width = this.width = image.naturalWidth;
6715 image.height = this.height = image.naturalHeight;
6716 return callback(true, image);
6717 };
6718 image.onerror = () => callback(false);
6719 image.src = this.url;
6720 }
6721 }
6722
6723 class Attachment extends TrixObject {
6724 static attachmentForFile(file) {
6725 const attributes = this.attributesForFile(file);
6726 const attachment = new this(attributes);
6727 attachment.setFile(file);
6728 return attachment;
6729 }
6730 static attributesForFile(file) {
6731 return new Hash({
6732 filename: file.name,
6733 filesize: file.size,
6734 contentType: file.type
6735 });
6736 }
6737 static fromJSON(attachmentJSON) {
6738 return new this(attachmentJSON);
6739 }
6740 constructor() {
6741 let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6742 super(attributes);
6743 this.releaseFile = this.releaseFile.bind(this);
6744 this.attributes = Hash.box(attributes);
6745 this.didChangeAttributes();
6746 }
6747 setAttribute(attribute, value) {
6748 this.setAttributes({
6749 [attribute]: value
6750 });
6751 }
6752 getAttribute(attribute) {
6753 return this.attributes.get(attribute);
6754 }
6755 hasAttribute(attribute) {
6756 return this.attributes.has(attribute);
6757 }
6758 getAttributes() {
6759 return this.attributes.toObject();
6760 }
6761 setAttributes() {
6762 let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6763 const newAttributes = this.attributes.merge(attributes);
6764 if (!this.attributes.isEqualTo(newAttributes)) {
6765 var _this$previewDelegate, _this$previewDelegate2, _this$delegate, _this$delegate$attach;
6766 this.attributes = newAttributes;
6767 this.didChangeAttributes();
6768 (_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);
6769 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);
6770 }
6771 }
6772 didChangeAttributes() {
6773 if (this.isPreviewable()) {
6774 return this.preloadURL();
6775 }
6776 }
6777 isPending() {
6778 return this.file != null && !(this.getURL() || this.getHref());
6779 }
6780 isPreviewable() {
6781 if (this.attributes.has("previewable")) {
6782 return this.attributes.get("previewable");
6783 } else {
6784 return Attachment.previewablePattern.test(this.getContentType());
6785 }
6786 }
6787 getType() {
6788 if (this.hasContent()) {
6789 return "content";
6790 } else if (this.isPreviewable()) {
6791 return "preview";
6792 } else {
6793 return "file";
6794 }
6795 }
6796 getURL() {
6797 return this.attributes.get("url");
6798 }
6799 getHref() {
6800 return this.attributes.get("href");
6801 }
6802 getFilename() {
6803 return this.attributes.get("filename") || "";
6804 }
6805 getFilesize() {
6806 return this.attributes.get("filesize");
6807 }
6808 getFormattedFilesize() {
6809 const filesize = this.attributes.get("filesize");
6810 if (typeof filesize === "number") {
6811 return file_size_formatting.formatter(filesize);
6812 } else {
6813 return "";
6814 }
6815 }
6816 getExtension() {
6817 var _this$getFilename$mat;
6818 return (_this$getFilename$mat = this.getFilename().match(/\.(\w+)$/)) === null || _this$getFilename$mat === void 0 ? void 0 : _this$getFilename$mat[1].toLowerCase();
6819 }
6820 getContentType() {
6821 return this.attributes.get("contentType");
6822 }
6823 hasContent() {
6824 return this.attributes.has("content");
6825 }
6826 getContent() {
6827 return this.attributes.get("content");
6828 }
6829 getWidth() {
6830 return this.attributes.get("width");
6831 }
6832 getHeight() {
6833 return this.attributes.get("height");
6834 }
6835 getFile() {
6836 return this.file;
6837 }
6838 setFile(file) {
6839 this.file = file;
6840 if (this.isPreviewable()) {
6841 return this.preloadFile();
6842 }
6843 }
6844 releaseFile() {
6845 this.releasePreloadedFile();
6846 this.file = null;
6847 }
6848 getUploadProgress() {
6849 return this.uploadProgress != null ? this.uploadProgress : 0;
6850 }
6851 setUploadProgress(value) {
6852 if (this.uploadProgress !== value) {
6853 var _this$uploadProgressD, _this$uploadProgressD2;
6854 this.uploadProgress = value;
6855 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);
6856 }
6857 }
6858 toJSON() {
6859 return this.getAttributes();
6860 }
6861 getCacheKey() {
6862 return [super.getCacheKey(...arguments), this.attributes.getCacheKey(), this.getPreviewURL()].join("/");
6863 }
6864
6865 // Previewable
6866
6867 getPreviewURL() {
6868 return this.previewURL || this.preloadingURL;
6869 }
6870 setPreviewURL(url) {
6871 if (url !== this.getPreviewURL()) {
6872 var _this$previewDelegate3, _this$previewDelegate4, _this$delegate2, _this$delegate2$attac;
6873 this.previewURL = url;
6874 (_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);
6875 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);
6876 }
6877 }
6878 preloadURL() {
6879 return this.preload(this.getURL(), this.releaseFile);
6880 }
6881 preloadFile() {
6882 if (this.file) {
6883 this.fileObjectURL = URL.createObjectURL(this.file);
6884 return this.preload(this.fileObjectURL);
6885 }
6886 }
6887 releasePreloadedFile() {
6888 if (this.fileObjectURL) {
6889 URL.revokeObjectURL(this.fileObjectURL);
6890 this.fileObjectURL = null;
6891 }
6892 }
6893 preload(url, callback) {
6894 if (url && url !== this.getPreviewURL()) {
6895 this.preloadingURL = url;
6896 const operation = new ImagePreloadOperation(url);
6897 return operation.then(_ref => {
6898 let {
6899 width,
6900 height
6901 } = _ref;
6902 if (!this.getWidth() || !this.getHeight()) {
6903 this.setAttributes({
6904 width,
6905 height
6906 });
6907 }
6908 this.preloadingURL = null;
6909 this.setPreviewURL(url);
6910 return callback === null || callback === void 0 ? void 0 : callback();
6911 }).catch(() => {
6912 this.preloadingURL = null;
6913 return callback === null || callback === void 0 ? void 0 : callback();
6914 });
6915 }
6916 }
6917 }
6918 _defineProperty(Attachment, "previewablePattern", /^image(\/(gif|png|webp|jpe?g)|$)/);
6919
6920 class AttachmentPiece extends Piece {
6921 static fromJSON(pieceJSON) {
6922 return new this(Attachment.fromJSON(pieceJSON.attachment), pieceJSON.attributes);
6923 }
6924 constructor(attachment) {
6925 super(...arguments);
6926 this.attachment = attachment;
6927 this.length = 1;
6928 this.ensureAttachmentExclusivelyHasAttribute("href");
6929 if (!this.attachment.hasContent()) {
6930 this.removeProhibitedAttributes();
6931 }
6932 }
6933 ensureAttachmentExclusivelyHasAttribute(attribute) {
6934 if (this.hasAttribute(attribute)) {
6935 if (!this.attachment.hasAttribute(attribute)) {
6936 this.attachment.setAttributes(this.attributes.slice([attribute]));
6937 }
6938 this.attributes = this.attributes.remove(attribute);
6939 }
6940 }
6941 removeProhibitedAttributes() {
6942 const attributes = this.attributes.slice(AttachmentPiece.permittedAttributes);
6943 if (!attributes.isEqualTo(this.attributes)) {
6944 this.attributes = attributes;
6945 }
6946 }
6947 getValue() {
6948 return this.attachment;
6949 }
6950 isSerializable() {
6951 return !this.attachment.isPending();
6952 }
6953 getCaption() {
6954 return this.attributes.get("caption") || "";
6955 }
6956 isEqualTo(piece) {
6957 var _piece$attachment;
6958 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);
6959 }
6960 toString() {
6961 return OBJECT_REPLACEMENT_CHARACTER;
6962 }
6963 toJSON() {
6964 const json = super.toJSON(...arguments);
6965 json.attachment = this.attachment;
6966 return json;
6967 }
6968 getCacheKey() {
6969 return [super.getCacheKey(...arguments), this.attachment.getCacheKey()].join("/");
6970 }
6971 toConsole() {
6972 return JSON.stringify(this.toString());
6973 }
6974 }
6975 _defineProperty(AttachmentPiece, "permittedAttributes", ["caption", "presentation"]);
6976 Piece.registerType("attachment", AttachmentPiece);
6977
6978 class StringPiece extends Piece {
6979 static fromJSON(pieceJSON) {
6980 const attributes = {
6981 ...pieceJSON.attributes
6982 };
6983 if (attributes.href && !purify.isValidAttribute("a", "href", attributes.href)) {
6984 delete attributes.href;
6985 }
6986 return new this(pieceJSON.string, attributes);
6987 }
6988 constructor(string) {
6989 super(...arguments);
6990 this.string = normalizeNewlines(string);
6991 this.length = this.string.length;
6992 }
6993 getValue() {
6994 return this.string;
6995 }
6996 toString() {
6997 return this.string.toString();
6998 }
6999 isBlockBreak() {
7000 return this.toString() === "\n" && this.getAttribute("blockBreak") === true;
7001 }
7002 toJSON() {
7003 const result = super.toJSON(...arguments);
7004 result.string = this.string;
7005 return result;
7006 }
7007
7008 // Splittable
7009
7010 canBeConsolidatedWith(piece) {
7011 return piece && this.hasSameConstructorAs(piece) && this.hasSameAttributesAsPiece(piece);
7012 }
7013 consolidateWith(piece) {
7014 return new this.constructor(this.toString() + piece.toString(), this.attributes);
7015 }
7016 splitAtOffset(offset) {
7017 let left, right;
7018 if (offset === 0) {
7019 left = null;
7020 right = this;
7021 } else if (offset === this.length) {
7022 left = this;
7023 right = null;
7024 } else {
7025 left = new this.constructor(this.string.slice(0, offset), this.attributes);
7026 right = new this.constructor(this.string.slice(offset), this.attributes);
7027 }
7028 return [left, right];
7029 }
7030 toConsole() {
7031 let {
7032 string
7033 } = this;
7034 if (string.length > 15) {
7035 string = string.slice(0, 14) + "…";
7036 }
7037 return JSON.stringify(string.toString());
7038 }
7039 }
7040 Piece.registerType("string", StringPiece);
7041
7042 /* eslint-disable
7043 prefer-const,
7044 */
7045 class SplittableList extends TrixObject {
7046 static box(objects) {
7047 if (objects instanceof this) {
7048 return objects;
7049 } else {
7050 return new this(objects);
7051 }
7052 }
7053 constructor() {
7054 let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
7055 super(...arguments);
7056 this.objects = objects.slice(0);
7057 this.length = this.objects.length;
7058 }
7059 indexOf(object) {
7060 return this.objects.indexOf(object);
7061 }
7062 splice() {
7063 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
7064 args[_key] = arguments[_key];
7065 }
7066 return new this.constructor(spliceArray(this.objects, ...args));
7067 }
7068 eachObject(callback) {
7069 return this.objects.map((object, index) => callback(object, index));
7070 }
7071 insertObjectAtIndex(object, index) {
7072 return this.splice(index, 0, object);
7073 }
7074 insertSplittableListAtIndex(splittableList, index) {
7075 return this.splice(index, 0, ...splittableList.objects);
7076 }
7077 insertSplittableListAtPosition(splittableList, position) {
7078 const [objects, index] = this.splitObjectAtPosition(position);
7079 return new this.constructor(objects).insertSplittableListAtIndex(splittableList, index);
7080 }
7081 editObjectAtIndex(index, callback) {
7082 return this.replaceObjectAtIndex(callback(this.objects[index]), index);
7083 }
7084 replaceObjectAtIndex(object, index) {
7085 return this.splice(index, 1, object);
7086 }
7087 removeObjectAtIndex(index) {
7088 return this.splice(index, 1);
7089 }
7090 getObjectAtIndex(index) {
7091 return this.objects[index];
7092 }
7093 getSplittableListInRange(range) {
7094 const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range);
7095 return new this.constructor(objects.slice(leftIndex, rightIndex + 1));
7096 }
7097 selectSplittableList(test) {
7098 const objects = this.objects.filter(object => test(object));
7099 return new this.constructor(objects);
7100 }
7101 removeObjectsInRange(range) {
7102 const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range);
7103 return new this.constructor(objects).splice(leftIndex, rightIndex - leftIndex + 1);
7104 }
7105 transformObjectsInRange(range, transform) {
7106 const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range);
7107 const transformedObjects = objects.map((object, index) => leftIndex <= index && index <= rightIndex ? transform(object) : object);
7108 return new this.constructor(transformedObjects);
7109 }
7110 splitObjectsAtRange(range) {
7111 let rightOuterIndex;
7112 let [objects, leftInnerIndex, offset] = this.splitObjectAtPosition(startOfRange(range));
7113 [objects, rightOuterIndex] = new this.constructor(objects).splitObjectAtPosition(endOfRange(range) + offset);
7114 return [objects, leftInnerIndex, rightOuterIndex - 1];
7115 }
7116 getObjectAtPosition(position) {
7117 const {
7118 index
7119 } = this.findIndexAndOffsetAtPosition(position);
7120 return this.objects[index];
7121 }
7122 splitObjectAtPosition(position) {
7123 let splitIndex, splitOffset;
7124 const {
7125 index,
7126 offset
7127 } = this.findIndexAndOffsetAtPosition(position);
7128 const objects = this.objects.slice(0);
7129 if (index != null) {
7130 if (offset === 0) {
7131 splitIndex = index;
7132 splitOffset = 0;
7133 } else {
7134 const object = this.getObjectAtIndex(index);
7135 const [leftObject, rightObject] = object.splitAtOffset(offset);
7136 objects.splice(index, 1, leftObject, rightObject);
7137 splitIndex = index + 1;
7138 splitOffset = leftObject.getLength() - offset;
7139 }
7140 } else {
7141 splitIndex = objects.length;
7142 splitOffset = 0;
7143 }
7144 return [objects, splitIndex, splitOffset];
7145 }
7146 consolidate() {
7147 const objects = [];
7148 let pendingObject = this.objects[0];
7149 this.objects.slice(1).forEach(object => {
7150 var _pendingObject$canBeC, _pendingObject;
7151 if ((_pendingObject$canBeC = (_pendingObject = pendingObject).canBeConsolidatedWith) !== null && _pendingObject$canBeC !== void 0 && _pendingObject$canBeC.call(_pendingObject, object)) {
7152 pendingObject = pendingObject.consolidateWith(object);
7153 } else {
7154 objects.push(pendingObject);
7155 pendingObject = object;
7156 }
7157 });
7158 if (pendingObject) {
7159 objects.push(pendingObject);
7160 }
7161 return new this.constructor(objects);
7162 }
7163 consolidateFromIndexToIndex(startIndex, endIndex) {
7164 const objects = this.objects.slice(0);
7165 const objectsInRange = objects.slice(startIndex, endIndex + 1);
7166 const consolidatedInRange = new this.constructor(objectsInRange).consolidate().toArray();
7167 return this.splice(startIndex, objectsInRange.length, ...consolidatedInRange);
7168 }
7169 findIndexAndOffsetAtPosition(position) {
7170 let index;
7171 let currentPosition = 0;
7172 for (index = 0; index < this.objects.length; index++) {
7173 const object = this.objects[index];
7174 const nextPosition = currentPosition + object.getLength();
7175 if (currentPosition <= position && position < nextPosition) {
7176 return {
7177 index,
7178 offset: position - currentPosition
7179 };
7180 }
7181 currentPosition = nextPosition;
7182 }
7183 return {
7184 index: null,
7185 offset: null
7186 };
7187 }
7188 findPositionAtIndexAndOffset(index, offset) {
7189 let position = 0;
7190 for (let currentIndex = 0; currentIndex < this.objects.length; currentIndex++) {
7191 const object = this.objects[currentIndex];
7192 if (currentIndex < index) {
7193 position += object.getLength();
7194 } else if (currentIndex === index) {
7195 position += offset;
7196 break;
7197 }
7198 }
7199 return position;
7200 }
7201 getEndPosition() {
7202 if (this.endPosition == null) {
7203 this.endPosition = 0;
7204 this.objects.forEach(object => this.endPosition += object.getLength());
7205 }
7206 return this.endPosition;
7207 }
7208 toString() {
7209 return this.objects.join("");
7210 }
7211 toArray() {
7212 return this.objects.slice(0);
7213 }
7214 toJSON() {
7215 return this.toArray();
7216 }
7217 isEqualTo(splittableList) {
7218 return super.isEqualTo(...arguments) || objectArraysAreEqual(this.objects, splittableList === null || splittableList === void 0 ? void 0 : splittableList.objects);
7219 }
7220 contentsForInspection() {
7221 return {
7222 objects: "[".concat(this.objects.map(object => object.inspect()).join(", "), "]")
7223 };
7224 }
7225 }
7226 const objectArraysAreEqual = function (left) {
7227 let right = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
7228 if (left.length !== right.length) {
7229 return false;
7230 }
7231 let result = true;
7232 for (let index = 0; index < left.length; index++) {
7233 const object = left[index];
7234 if (result && !object.isEqualTo(right[index])) {
7235 result = false;
7236 }
7237 }
7238 return result;
7239 };
7240 const startOfRange = range => range[0];
7241 const endOfRange = range => range[1];
7242
7243 class Text extends TrixObject {
7244 static textForAttachmentWithAttributes(attachment, attributes) {
7245 const piece = new AttachmentPiece(attachment, attributes);
7246 return new this([piece]);
7247 }
7248 static textForStringWithAttributes(string, attributes) {
7249 const piece = new StringPiece(string, attributes);
7250 return new this([piece]);
7251 }
7252 static fromJSON(textJSON) {
7253 const pieces = Array.from(textJSON).map(pieceJSON => Piece.fromJSON(pieceJSON));
7254 return new this(pieces);
7255 }
7256 constructor() {
7257 let pieces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
7258 super(...arguments);
7259 const notEmpty = pieces.filter(piece => !piece.isEmpty());
7260 this.pieceList = new SplittableList(notEmpty);
7261 }
7262 copy() {
7263 return this.copyWithPieceList(this.pieceList);
7264 }
7265 copyWithPieceList(pieceList) {
7266 return new this.constructor(pieceList.consolidate().toArray());
7267 }
7268 copyUsingObjectMap(objectMap) {
7269 const pieces = this.getPieces().map(piece => objectMap.find(piece) || piece);
7270 return new this.constructor(pieces);
7271 }
7272 appendText(text) {
7273 return this.insertTextAtPosition(text, this.getLength());
7274 }
7275 insertTextAtPosition(text, position) {
7276 return this.copyWithPieceList(this.pieceList.insertSplittableListAtPosition(text.pieceList, position));
7277 }
7278 removeTextAtRange(range) {
7279 return this.copyWithPieceList(this.pieceList.removeObjectsInRange(range));
7280 }
7281 replaceTextAtRange(text, range) {
7282 return this.removeTextAtRange(range).insertTextAtPosition(text, range[0]);
7283 }
7284 moveTextFromRangeToPosition(range, position) {
7285 if (range[0] <= position && position <= range[1]) return;
7286 const text = this.getTextAtRange(range);
7287 const length = text.getLength();
7288 if (range[0] < position) {
7289 position -= length;
7290 }
7291 return this.removeTextAtRange(range).insertTextAtPosition(text, position);
7292 }
7293 addAttributeAtRange(attribute, value, range) {
7294 const attributes = {};
7295 attributes[attribute] = value;
7296 return this.addAttributesAtRange(attributes, range);
7297 }
7298 addAttributesAtRange(attributes, range) {
7299 return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithAdditionalAttributes(attributes)));
7300 }
7301 removeAttributeAtRange(attribute, range) {
7302 return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithoutAttribute(attribute)));
7303 }
7304 setAttributesAtRange(attributes, range) {
7305 return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithAttributes(attributes)));
7306 }
7307 getAttributesAtPosition(position) {
7308 var _this$pieceList$getOb;
7309 return ((_this$pieceList$getOb = this.pieceList.getObjectAtPosition(position)) === null || _this$pieceList$getOb === void 0 ? void 0 : _this$pieceList$getOb.getAttributes()) || {};
7310 }
7311 getCommonAttributes() {
7312 const objects = Array.from(this.pieceList.toArray()).map(piece => piece.getAttributes());
7313 return Hash.fromCommonAttributesOfObjects(objects).toObject();
7314 }
7315 getCommonAttributesAtRange(range) {
7316 return this.getTextAtRange(range).getCommonAttributes() || {};
7317 }
7318 getExpandedRangeForAttributeAtOffset(attributeName, offset) {
7319 let right;
7320 let left = right = offset;
7321 const length = this.getLength();
7322 while (left > 0 && this.getCommonAttributesAtRange([left - 1, right])[attributeName]) {
7323 left--;
7324 }
7325 while (right < length && this.getCommonAttributesAtRange([offset, right + 1])[attributeName]) {
7326 right++;
7327 }
7328 return [left, right];
7329 }
7330 getTextAtRange(range) {
7331 return this.copyWithPieceList(this.pieceList.getSplittableListInRange(range));
7332 }
7333 getStringAtRange(range) {
7334 return this.pieceList.getSplittableListInRange(range).toString();
7335 }
7336 getStringAtPosition(position) {
7337 return this.getStringAtRange([position, position + 1]);
7338 }
7339 startsWithString(string) {
7340 return this.getStringAtRange([0, string.length]) === string;
7341 }
7342 endsWithString(string) {
7343 const length = this.getLength();
7344 return this.getStringAtRange([length - string.length, length]) === string;
7345 }
7346 getAttachmentPieces() {
7347 return this.pieceList.toArray().filter(piece => !!piece.attachment);
7348 }
7349 getAttachments() {
7350 return this.getAttachmentPieces().map(piece => piece.attachment);
7351 }
7352 getAttachmentAndPositionById(attachmentId) {
7353 let position = 0;
7354 for (const piece of this.pieceList.toArray()) {
7355 var _piece$attachment;
7356 if (((_piece$attachment = piece.attachment) === null || _piece$attachment === void 0 ? void 0 : _piece$attachment.id) === attachmentId) {
7357 return {
7358 attachment: piece.attachment,
7359 position
7360 };
7361 }
7362 position += piece.length;
7363 }
7364 return {
7365 attachment: null,
7366 position: null
7367 };
7368 }
7369 getAttachmentById(attachmentId) {
7370 const {
7371 attachment
7372 } = this.getAttachmentAndPositionById(attachmentId);
7373 return attachment;
7374 }
7375 getRangeOfAttachment(attachment) {
7376 const attachmentAndPosition = this.getAttachmentAndPositionById(attachment.id);
7377 const position = attachmentAndPosition.position;
7378 attachment = attachmentAndPosition.attachment;
7379 if (attachment) {
7380 return [position, position + 1];
7381 }
7382 }
7383 updateAttributesForAttachment(attributes, attachment) {
7384 const range = this.getRangeOfAttachment(attachment);
7385 if (range) {
7386 return this.addAttributesAtRange(attributes, range);
7387 } else {
7388 return this;
7389 }
7390 }
7391 getLength() {
7392 return this.pieceList.getEndPosition();
7393 }
7394 isEmpty() {
7395 return this.getLength() === 0;
7396 }
7397 isEqualTo(text) {
7398 var _text$pieceList;
7399 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));
7400 }
7401 isBlockBreak() {
7402 return this.getLength() === 1 && this.pieceList.getObjectAtIndex(0).isBlockBreak();
7403 }
7404 eachPiece(callback) {
7405 return this.pieceList.eachObject(callback);
7406 }
7407 getPieces() {
7408 return this.pieceList.toArray();
7409 }
7410 getPieceAtPosition(position) {
7411 return this.pieceList.getObjectAtPosition(position);
7412 }
7413 contentsForInspection() {
7414 return {
7415 pieceList: this.pieceList.inspect()
7416 };
7417 }
7418 toSerializableText() {
7419 const pieceList = this.pieceList.selectSplittableList(piece => piece.isSerializable());
7420 return this.copyWithPieceList(pieceList);
7421 }
7422 toString() {
7423 return this.pieceList.toString();
7424 }
7425 toJSON() {
7426 return this.pieceList.toJSON();
7427 }
7428 toConsole() {
7429 return JSON.stringify(this.pieceList.toArray().map(piece => JSON.parse(piece.toConsole())));
7430 }
7431
7432 // BIDI
7433
7434 getDirection() {
7435 return getDirection(this.toString());
7436 }
7437 isRTL() {
7438 return this.getDirection() === "rtl";
7439 }
7440 }
7441
7442 class Block extends TrixObject {
7443 static fromJSON(blockJSON) {
7444 const text = Text.fromJSON(blockJSON.text);
7445 return new this(text, blockJSON.attributes, blockJSON.htmlAttributes);
7446 }
7447 constructor(text, attributes, htmlAttributes) {
7448 super(...arguments);
7449 this.text = applyBlockBreakToText(text || new Text());
7450 this.attributes = attributes || [];
7451 this.htmlAttributes = htmlAttributes || {};
7452 }
7453 isEmpty() {
7454 return this.text.isBlockBreak();
7455 }
7456 isEqualTo(block) {
7457 if (super.isEqualTo(block)) return true;
7458 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);
7459 }
7460 copyWithText(text) {
7461 return new Block(text, this.attributes, this.htmlAttributes);
7462 }
7463 copyWithoutText() {
7464 return this.copyWithText(null);
7465 }
7466 copyWithAttributes(attributes) {
7467 return new Block(this.text, attributes, this.htmlAttributes);
7468 }
7469 copyWithoutAttributes() {
7470 return this.copyWithAttributes(null);
7471 }
7472 copyUsingObjectMap(objectMap) {
7473 const mappedText = objectMap.find(this.text);
7474 if (mappedText) {
7475 return this.copyWithText(mappedText);
7476 } else {
7477 return this.copyWithText(this.text.copyUsingObjectMap(objectMap));
7478 }
7479 }
7480 addAttribute(attribute) {
7481 const attributes = this.attributes.concat(expandAttribute(attribute));
7482 return this.copyWithAttributes(attributes);
7483 }
7484 addHTMLAttribute(attribute, value) {
7485 const htmlAttributes = Object.assign({}, this.htmlAttributes, {
7486 [attribute]: value
7487 });
7488 return new Block(this.text, this.attributes, htmlAttributes);
7489 }
7490 removeAttribute(attribute) {
7491 const {
7492 listAttribute
7493 } = getBlockConfig(attribute);
7494 const attributes = removeLastValue(removeLastValue(this.attributes, attribute), listAttribute);
7495 return this.copyWithAttributes(attributes);
7496 }
7497 removeLastAttribute() {
7498 return this.removeAttribute(this.getLastAttribute());
7499 }
7500 getLastAttribute() {
7501 return getLastElement(this.attributes);
7502 }
7503 getAttributes() {
7504 return this.attributes.slice(0);
7505 }
7506 getAttributeLevel() {
7507 return this.attributes.length;
7508 }
7509 getAttributeAtLevel(level) {
7510 return this.attributes[level - 1];
7511 }
7512 hasAttribute(attributeName) {
7513 return this.attributes.includes(attributeName);
7514 }
7515 hasAttributes() {
7516 return this.getAttributeLevel() > 0;
7517 }
7518 getLastNestableAttribute() {
7519 return getLastElement(this.getNestableAttributes());
7520 }
7521 getNestableAttributes() {
7522 return this.attributes.filter(attribute => getBlockConfig(attribute).nestable);
7523 }
7524 getNestingLevel() {
7525 return this.getNestableAttributes().length;
7526 }
7527 decreaseNestingLevel() {
7528 const attribute = this.getLastNestableAttribute();
7529 if (attribute) {
7530 return this.removeAttribute(attribute);
7531 } else {
7532 return this;
7533 }
7534 }
7535 increaseNestingLevel() {
7536 const attribute = this.getLastNestableAttribute();
7537 if (attribute) {
7538 const index = this.attributes.lastIndexOf(attribute);
7539 const attributes = spliceArray(this.attributes, index + 1, 0, ...expandAttribute(attribute));
7540 return this.copyWithAttributes(attributes);
7541 } else {
7542 return this;
7543 }
7544 }
7545 getListItemAttributes() {
7546 return this.attributes.filter(attribute => getBlockConfig(attribute).listAttribute);
7547 }
7548 isListItem() {
7549 var _getBlockConfig;
7550 return (_getBlockConfig = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.listAttribute;
7551 }
7552 isTerminalBlock() {
7553 var _getBlockConfig2;
7554 return (_getBlockConfig2 = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig2 === void 0 ? void 0 : _getBlockConfig2.terminal;
7555 }
7556 breaksOnReturn() {
7557 var _getBlockConfig3;
7558 return (_getBlockConfig3 = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig3 === void 0 ? void 0 : _getBlockConfig3.breakOnReturn;
7559 }
7560 findLineBreakInDirectionFromPosition(direction, position) {
7561 const string = this.toString();
7562 let result;
7563 switch (direction) {
7564 case "forward":
7565 result = string.indexOf("\n", position);
7566 break;
7567 case "backward":
7568 result = string.slice(0, position).lastIndexOf("\n");
7569 }
7570 if (result !== -1) {
7571 return result;
7572 }
7573 }
7574 contentsForInspection() {
7575 return {
7576 text: this.text.inspect(),
7577 attributes: this.attributes
7578 };
7579 }
7580 toString() {
7581 return this.text.toString();
7582 }
7583 toJSON() {
7584 return {
7585 text: this.text,
7586 attributes: this.attributes,
7587 htmlAttributes: this.htmlAttributes
7588 };
7589 }
7590
7591 // BIDI
7592
7593 getDirection() {
7594 return this.text.getDirection();
7595 }
7596 isRTL() {
7597 return this.text.isRTL();
7598 }
7599
7600 // Splittable
7601
7602 getLength() {
7603 return this.text.getLength();
7604 }
7605 canBeConsolidatedWith(block) {
7606 return !this.hasAttributes() && !block.hasAttributes() && this.getDirection() === block.getDirection();
7607 }
7608 consolidateWith(block) {
7609 const newlineText = Text.textForStringWithAttributes("\n");
7610 const text = this.getTextWithoutBlockBreak().appendText(newlineText);
7611 return this.copyWithText(text.appendText(block.text));
7612 }
7613 splitAtOffset(offset) {
7614 let left, right;
7615 if (offset === 0) {
7616 left = null;
7617 right = this;
7618 } else if (offset === this.getLength()) {
7619 left = this;
7620 right = null;
7621 } else {
7622 left = this.copyWithText(this.text.getTextAtRange([0, offset]));
7623 right = this.copyWithText(this.text.getTextAtRange([offset, this.getLength()]));
7624 }
7625 return [left, right];
7626 }
7627 getBlockBreakPosition() {
7628 return this.text.getLength() - 1;
7629 }
7630 getTextWithoutBlockBreak() {
7631 if (textEndsInBlockBreak(this.text)) {
7632 return this.text.getTextAtRange([0, this.getBlockBreakPosition()]);
7633 } else {
7634 return this.text.copy();
7635 }
7636 }
7637
7638 // Grouping
7639
7640 canBeGrouped(depth) {
7641 return this.attributes[depth];
7642 }
7643 canBeGroupedWith(otherBlock, depth) {
7644 const otherAttributes = otherBlock.getAttributes();
7645 const otherAttribute = otherAttributes[depth];
7646 const attribute = this.attributes[depth];
7647 return attribute === otherAttribute && !(getBlockConfig(attribute).group === false && !getListAttributeNames().includes(otherAttributes[depth + 1])) && (this.getDirection() === otherBlock.getDirection() || otherBlock.isEmpty());
7648 }
7649 }
7650
7651 // Block breaks
7652
7653 const applyBlockBreakToText = function (text) {
7654 text = unmarkExistingInnerBlockBreaksInText(text);
7655 text = addBlockBreakToText(text);
7656 return text;
7657 };
7658 const unmarkExistingInnerBlockBreaksInText = function (text) {
7659 let modified = false;
7660 const pieces = text.getPieces();
7661 let innerPieces = pieces.slice(0, pieces.length - 1);
7662 const lastPiece = pieces[pieces.length - 1];
7663 if (!lastPiece) return text;
7664 innerPieces = innerPieces.map(piece => {
7665 if (piece.isBlockBreak()) {
7666 modified = true;
7667 return unmarkBlockBreakPiece(piece);
7668 } else {
7669 return piece;
7670 }
7671 });
7672 if (modified) {
7673 return new Text([...innerPieces, lastPiece]);
7674 } else {
7675 return text;
7676 }
7677 };
7678 const blockBreakText = Text.textForStringWithAttributes("\n", {
7679 blockBreak: true
7680 });
7681 const addBlockBreakToText = function (text) {
7682 if (textEndsInBlockBreak(text)) {
7683 return text;
7684 } else {
7685 return text.appendText(blockBreakText);
7686 }
7687 };
7688 const textEndsInBlockBreak = function (text) {
7689 const length = text.getLength();
7690 if (length === 0) {
7691 return false;
7692 }
7693 const endText = text.getTextAtRange([length - 1, length]);
7694 return endText.isBlockBreak();
7695 };
7696 const unmarkBlockBreakPiece = piece => piece.copyWithoutAttribute("blockBreak");
7697
7698 // Attributes
7699
7700 const expandAttribute = function (attribute) {
7701 const {
7702 listAttribute
7703 } = getBlockConfig(attribute);
7704 if (listAttribute) {
7705 return [listAttribute, attribute];
7706 } else {
7707 return [attribute];
7708 }
7709 };
7710
7711 // Array helpers
7712
7713 const getLastElement = array => array.slice(-1)[0];
7714 const removeLastValue = function (array, value) {
7715 const index = array.lastIndexOf(value);
7716 if (index === -1) {
7717 return array;
7718 } else {
7719 return spliceArray(array, index, 1);
7720 }
7721 };
7722
7723 class Document extends TrixObject {
7724 static fromJSON(documentJSON) {
7725 const blocks = Array.from(documentJSON).map(blockJSON => Block.fromJSON(blockJSON));
7726 return new this(blocks);
7727 }
7728 static fromString(string, textAttributes) {
7729 const text = Text.textForStringWithAttributes(string, textAttributes);
7730 return new this([new Block(text)]);
7731 }
7732 constructor() {
7733 let blocks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
7734 super(...arguments);
7735 if (blocks.length === 0) {
7736 blocks = [new Block()];
7737 }
7738 this.blockList = SplittableList.box(blocks);
7739 }
7740 isEmpty() {
7741 const block = this.getBlockAtIndex(0);
7742 return this.blockList.length === 1 && block.isEmpty() && !block.hasAttributes();
7743 }
7744 copy() {
7745 let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
7746 const blocks = options.consolidateBlocks ? this.blockList.consolidate().toArray() : this.blockList.toArray();
7747 return new this.constructor(blocks);
7748 }
7749 copyUsingObjectsFromDocument(sourceDocument) {
7750 const objectMap = new ObjectMap(sourceDocument.getObjects());
7751 return this.copyUsingObjectMap(objectMap);
7752 }
7753 copyUsingObjectMap(objectMap) {
7754 const blocks = this.getBlocks().map(block => {
7755 const mappedBlock = objectMap.find(block);
7756 return mappedBlock || block.copyUsingObjectMap(objectMap);
7757 });
7758 return new this.constructor(blocks);
7759 }
7760 copyWithBaseBlockAttributes() {
7761 let blockAttributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
7762 const blocks = this.getBlocks().map(block => {
7763 const attributes = blockAttributes.concat(block.getAttributes());
7764 return block.copyWithAttributes(attributes);
7765 });
7766 return new this.constructor(blocks);
7767 }
7768 replaceBlock(oldBlock, newBlock) {
7769 const index = this.blockList.indexOf(oldBlock);
7770 if (index === -1) {
7771 return this;
7772 }
7773 return new this.constructor(this.blockList.replaceObjectAtIndex(newBlock, index));
7774 }
7775 insertDocumentAtRange(document, range) {
7776 const {
7777 blockList
7778 } = document;
7779 range = normalizeRange(range);
7780 let [position] = range;
7781 const {
7782 index,
7783 offset
7784 } = this.locationFromPosition(position);
7785 let result = this;
7786 const block = this.getBlockAtPosition(position);
7787 if (rangeIsCollapsed(range) && block.isEmpty() && !block.hasAttributes()) {
7788 result = new this.constructor(result.blockList.removeObjectAtIndex(index));
7789 } else if (block.getBlockBreakPosition() === offset) {
7790 position++;
7791 }
7792 result = result.removeTextAtRange(range);
7793 return new this.constructor(result.blockList.insertSplittableListAtPosition(blockList, position));
7794 }
7795 mergeDocumentAtRange(document, range) {
7796 let formattedDocument, result;
7797 range = normalizeRange(range);
7798 const [startPosition] = range;
7799 const startLocation = this.locationFromPosition(startPosition);
7800 const blockAttributes = this.getBlockAtIndex(startLocation.index).getAttributes();
7801 const baseBlockAttributes = document.getBaseBlockAttributes();
7802 const trailingBlockAttributes = blockAttributes.slice(-baseBlockAttributes.length);
7803 if (arraysAreEqual(baseBlockAttributes, trailingBlockAttributes)) {
7804 const leadingBlockAttributes = blockAttributes.slice(0, -baseBlockAttributes.length);
7805 formattedDocument = document.copyWithBaseBlockAttributes(leadingBlockAttributes);
7806 } else {
7807 formattedDocument = document.copy({
7808 consolidateBlocks: true
7809 }).copyWithBaseBlockAttributes(blockAttributes);
7810 }
7811 const blockCount = formattedDocument.getBlockCount();
7812 const firstBlock = formattedDocument.getBlockAtIndex(0);
7813 if (arraysAreEqual(blockAttributes, firstBlock.getAttributes())) {
7814 const firstText = firstBlock.getTextWithoutBlockBreak();
7815 result = this.insertTextAtRange(firstText, range);
7816 if (blockCount > 1) {
7817 formattedDocument = new this.constructor(formattedDocument.getBlocks().slice(1));
7818 const position = startPosition + firstText.getLength();
7819 result = result.insertDocumentAtRange(formattedDocument, position);
7820 }
7821 } else {
7822 result = this.insertDocumentAtRange(formattedDocument, range);
7823 }
7824 return result;
7825 }
7826 insertTextAtRange(text, range) {
7827 range = normalizeRange(range);
7828 const [startPosition] = range;
7829 const {
7830 index,
7831 offset
7832 } = this.locationFromPosition(startPosition);
7833 const document = this.removeTextAtRange(range);
7834 return new this.constructor(document.blockList.editObjectAtIndex(index, block => block.copyWithText(block.text.insertTextAtPosition(text, offset))));
7835 }
7836 removeTextAtRange(range) {
7837 let blocks;
7838 range = normalizeRange(range);
7839 const [leftPosition, rightPosition] = range;
7840 if (rangeIsCollapsed(range)) {
7841 return this;
7842 }
7843 const [leftLocation, rightLocation] = Array.from(this.locationRangeFromRange(range));
7844 const leftIndex = leftLocation.index;
7845 const leftOffset = leftLocation.offset;
7846 const leftBlock = this.getBlockAtIndex(leftIndex);
7847 const rightIndex = rightLocation.index;
7848 const rightOffset = rightLocation.offset;
7849 const rightBlock = this.getBlockAtIndex(rightIndex);
7850 const removeRightNewline = rightPosition - leftPosition === 1 && leftBlock.getBlockBreakPosition() === leftOffset && rightBlock.getBlockBreakPosition() !== rightOffset && rightBlock.text.getStringAtPosition(rightOffset) === "\n";
7851 if (removeRightNewline) {
7852 blocks = this.blockList.editObjectAtIndex(rightIndex, block => block.copyWithText(block.text.removeTextAtRange([rightOffset, rightOffset + 1])));
7853 } else {
7854 let block;
7855 const leftText = leftBlock.text.getTextAtRange([0, leftOffset]);
7856 const rightText = rightBlock.text.getTextAtRange([rightOffset, rightBlock.getLength()]);
7857 const text = leftText.appendText(rightText);
7858 const removingLeftBlock = leftIndex !== rightIndex && leftOffset === 0;
7859 const useRightBlock = removingLeftBlock && leftBlock.getAttributeLevel() >= rightBlock.getAttributeLevel();
7860 if (useRightBlock) {
7861 block = rightBlock.copyWithText(text);
7862 } else {
7863 block = leftBlock.copyWithText(text);
7864 }
7865 const affectedBlockCount = rightIndex + 1 - leftIndex;
7866 blocks = this.blockList.splice(leftIndex, affectedBlockCount, block);
7867 }
7868 return new this.constructor(blocks);
7869 }
7870 moveTextFromRangeToPosition(range, position) {
7871 let text;
7872 range = normalizeRange(range);
7873 const [startPosition, endPosition] = range;
7874 if (startPosition <= position && position <= endPosition) {
7875 return this;
7876 }
7877 let document = this.getDocumentAtRange(range);
7878 let result = this.removeTextAtRange(range);
7879 const movingRightward = startPosition < position;
7880 if (movingRightward) {
7881 position -= document.getLength();
7882 }
7883 const [firstBlock, ...blocks] = document.getBlocks();
7884 if (blocks.length === 0) {
7885 text = firstBlock.getTextWithoutBlockBreak();
7886 if (movingRightward) {
7887 position += 1;
7888 }
7889 } else {
7890 text = firstBlock.text;
7891 }
7892 result = result.insertTextAtRange(text, position);
7893 if (blocks.length === 0) {
7894 return result;
7895 }
7896 document = new this.constructor(blocks);
7897 position += text.getLength();
7898 return result.insertDocumentAtRange(document, position);
7899 }
7900 addAttributeAtRange(attribute, value, range) {
7901 let {
7902 blockList
7903 } = this;
7904 this.eachBlockAtRange(range, (block, textRange, index) => blockList = blockList.editObjectAtIndex(index, function () {
7905 if (getBlockConfig(attribute)) {
7906 return block.addAttribute(attribute, value);
7907 } else {
7908 if (textRange[0] === textRange[1]) {
7909 return block;
7910 } else {
7911 return block.copyWithText(block.text.addAttributeAtRange(attribute, value, textRange));
7912 }
7913 }
7914 }));
7915 return new this.constructor(blockList);
7916 }
7917 addAttribute(attribute, value) {
7918 let {
7919 blockList
7920 } = this;
7921 this.eachBlock((block, index) => blockList = blockList.editObjectAtIndex(index, () => block.addAttribute(attribute, value)));
7922 return new this.constructor(blockList);
7923 }
7924 removeAttributeAtRange(attribute, range) {
7925 let {
7926 blockList
7927 } = this;
7928 this.eachBlockAtRange(range, function (block, textRange, index) {
7929 if (getBlockConfig(attribute)) {
7930 blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(attribute));
7931 } else if (textRange[0] !== textRange[1]) {
7932 blockList = blockList.editObjectAtIndex(index, () => block.copyWithText(block.text.removeAttributeAtRange(attribute, textRange)));
7933 }
7934 });
7935 return new this.constructor(blockList);
7936 }
7937 updateAttributesForAttachment(attributes, attachment) {
7938 const range = this.getRangeOfAttachment(attachment);
7939 const [startPosition] = Array.from(range);
7940 const {
7941 index
7942 } = this.locationFromPosition(startPosition);
7943 const text = this.getTextAtIndex(index);
7944 return new this.constructor(this.blockList.editObjectAtIndex(index, block => block.copyWithText(text.updateAttributesForAttachment(attributes, attachment))));
7945 }
7946 removeAttributeForAttachment(attribute, attachment) {
7947 const range = this.getRangeOfAttachment(attachment);
7948 return this.removeAttributeAtRange(attribute, range);
7949 }
7950 setHTMLAttributeAtPosition(position, name, value) {
7951 const block = this.getBlockAtPosition(position);
7952 const updatedBlock = block.addHTMLAttribute(name, value);
7953 return this.replaceBlock(block, updatedBlock);
7954 }
7955 insertBlockBreakAtRange(range) {
7956 let blocks;
7957 range = normalizeRange(range);
7958 const [startPosition] = range;
7959 const {
7960 offset
7961 } = this.locationFromPosition(startPosition);
7962 const document = this.removeTextAtRange(range);
7963 if (offset === 0) {
7964 blocks = [new Block()];
7965 }
7966 return new this.constructor(document.blockList.insertSplittableListAtPosition(new SplittableList(blocks), startPosition));
7967 }
7968 applyBlockAttributeAtRange(attributeName, value, range) {
7969 const expanded = this.expandRangeToLineBreaksAndSplitBlocks(range);
7970 let document = expanded.document;
7971 range = expanded.range;
7972 const blockConfig = getBlockConfig(attributeName);
7973 if (blockConfig.listAttribute) {
7974 document = document.removeLastListAttributeAtRange(range, {
7975 exceptAttributeName: attributeName
7976 });
7977 const converted = document.convertLineBreaksToBlockBreaksInRange(range);
7978 document = converted.document;
7979 range = converted.range;
7980 } else if (blockConfig.exclusive) {
7981 document = document.removeBlockAttributesAtRange(range);
7982 } else if (blockConfig.terminal) {
7983 document = document.removeLastTerminalAttributeAtRange(range);
7984 } else {
7985 document = document.consolidateBlocksAtRange(range);
7986 }
7987 return document.addAttributeAtRange(attributeName, value, range);
7988 }
7989 removeLastListAttributeAtRange(range) {
7990 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7991 let {
7992 blockList
7993 } = this;
7994 this.eachBlockAtRange(range, function (block, textRange, index) {
7995 const lastAttributeName = block.getLastAttribute();
7996 if (!lastAttributeName) {
7997 return;
7998 }
7999 if (!getBlockConfig(lastAttributeName).listAttribute) {
8000 return;
8001 }
8002 if (lastAttributeName === options.exceptAttributeName) {
8003 return;
8004 }
8005 blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(lastAttributeName));
8006 });
8007 return new this.constructor(blockList);
8008 }
8009 removeLastTerminalAttributeAtRange(range) {
8010 let {
8011 blockList
8012 } = this;
8013 this.eachBlockAtRange(range, function (block, textRange, index) {
8014 const lastAttributeName = block.getLastAttribute();
8015 if (!lastAttributeName) {
8016 return;
8017 }
8018 if (!getBlockConfig(lastAttributeName).terminal) {
8019 return;
8020 }
8021 blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(lastAttributeName));
8022 });
8023 return new this.constructor(blockList);
8024 }
8025 removeBlockAttributesAtRange(range) {
8026 let {
8027 blockList
8028 } = this;
8029 this.eachBlockAtRange(range, function (block, textRange, index) {
8030 if (block.hasAttributes()) {
8031 blockList = blockList.editObjectAtIndex(index, () => block.copyWithoutAttributes());
8032 }
8033 });
8034 return new this.constructor(blockList);
8035 }
8036 expandRangeToLineBreaksAndSplitBlocks(range) {
8037 let position;
8038 range = normalizeRange(range);
8039 let [startPosition, endPosition] = range;
8040 const startLocation = this.locationFromPosition(startPosition);
8041 const endLocation = this.locationFromPosition(endPosition);
8042 let document = this;
8043 const startBlock = document.getBlockAtIndex(startLocation.index);
8044 startLocation.offset = startBlock.findLineBreakInDirectionFromPosition("backward", startLocation.offset);
8045 if (startLocation.offset != null) {
8046 position = document.positionFromLocation(startLocation);
8047 document = document.insertBlockBreakAtRange([position, position + 1]);
8048 endLocation.index += 1;
8049 endLocation.offset -= document.getBlockAtIndex(startLocation.index).getLength();
8050 startLocation.index += 1;
8051 }
8052 startLocation.offset = 0;
8053 if (endLocation.offset === 0 && endLocation.index > startLocation.index) {
8054 endLocation.index -= 1;
8055 endLocation.offset = document.getBlockAtIndex(endLocation.index).getBlockBreakPosition();
8056 } else {
8057 const endBlock = document.getBlockAtIndex(endLocation.index);
8058 if (endBlock.text.getStringAtRange([endLocation.offset - 1, endLocation.offset]) === "\n") {
8059 endLocation.offset -= 1;
8060 } else {
8061 endLocation.offset = endBlock.findLineBreakInDirectionFromPosition("forward", endLocation.offset);
8062 }
8063 if (endLocation.offset !== endBlock.getBlockBreakPosition()) {
8064 position = document.positionFromLocation(endLocation);
8065 document = document.insertBlockBreakAtRange([position, position + 1]);
8066 }
8067 }
8068 startPosition = document.positionFromLocation(startLocation);
8069 endPosition = document.positionFromLocation(endLocation);
8070 range = normalizeRange([startPosition, endPosition]);
8071 return {
8072 document,
8073 range
8074 };
8075 }
8076 convertLineBreaksToBlockBreaksInRange(range) {
8077 range = normalizeRange(range);
8078 let [position] = range;
8079 const string = this.getStringAtRange(range).slice(0, -1);
8080 let document = this;
8081 string.replace(/.*?\n/g, function (match) {
8082 position += match.length;
8083 document = document.insertBlockBreakAtRange([position - 1, position]);
8084 });
8085 return {
8086 document,
8087 range
8088 };
8089 }
8090 consolidateBlocksAtRange(range) {
8091 range = normalizeRange(range);
8092 const [startPosition, endPosition] = range;
8093 const startIndex = this.locationFromPosition(startPosition).index;
8094 const endIndex = this.locationFromPosition(endPosition).index;
8095 return new this.constructor(this.blockList.consolidateFromIndexToIndex(startIndex, endIndex));
8096 }
8097 getDocumentAtRange(range) {
8098 range = normalizeRange(range);
8099 const blocks = this.blockList.getSplittableListInRange(range).toArray();
8100 return new this.constructor(blocks);
8101 }
8102 getStringAtRange(range) {
8103 let endIndex;
8104 const array = range = normalizeRange(range),
8105 endPosition = array[array.length - 1];
8106 if (endPosition !== this.getLength()) {
8107 endIndex = -1;
8108 }
8109 return this.getDocumentAtRange(range).toString().slice(0, endIndex);
8110 }
8111 getBlockAtIndex(index) {
8112 return this.blockList.getObjectAtIndex(index);
8113 }
8114 getBlockAtPosition(position) {
8115 const {
8116 index
8117 } = this.locationFromPosition(position);
8118 return this.getBlockAtIndex(index);
8119 }
8120 getTextAtIndex(index) {
8121 var _this$getBlockAtIndex;
8122 return (_this$getBlockAtIndex = this.getBlockAtIndex(index)) === null || _this$getBlockAtIndex === void 0 ? void 0 : _this$getBlockAtIndex.text;
8123 }
8124 getTextAtPosition(position) {
8125 const {
8126 index
8127 } = this.locationFromPosition(position);
8128 return this.getTextAtIndex(index);
8129 }
8130 getPieceAtPosition(position) {
8131 const {
8132 index,
8133 offset
8134 } = this.locationFromPosition(position);
8135 return this.getTextAtIndex(index).getPieceAtPosition(offset);
8136 }
8137 getCharacterAtPosition(position) {
8138 const {
8139 index,
8140 offset
8141 } = this.locationFromPosition(position);
8142 return this.getTextAtIndex(index).getStringAtRange([offset, offset + 1]);
8143 }
8144 getLength() {
8145 return this.blockList.getEndPosition();
8146 }
8147 getBlocks() {
8148 return this.blockList.toArray();
8149 }
8150 getBlockCount() {
8151 return this.blockList.length;
8152 }
8153 getEditCount() {
8154 return this.editCount;
8155 }
8156 eachBlock(callback) {
8157 return this.blockList.eachObject(callback);
8158 }
8159 eachBlockAtRange(range, callback) {
8160 let block, textRange;
8161 range = normalizeRange(range);
8162 const [startPosition, endPosition] = range;
8163 const startLocation = this.locationFromPosition(startPosition);
8164 const endLocation = this.locationFromPosition(endPosition);
8165 if (startLocation.index === endLocation.index) {
8166 block = this.getBlockAtIndex(startLocation.index);
8167 textRange = [startLocation.offset, endLocation.offset];
8168 return callback(block, textRange, startLocation.index);
8169 } else {
8170 for (let index = startLocation.index; index <= endLocation.index; index++) {
8171 block = this.getBlockAtIndex(index);
8172 if (block) {
8173 switch (index) {
8174 case startLocation.index:
8175 textRange = [startLocation.offset, block.text.getLength()];
8176 break;
8177 case endLocation.index:
8178 textRange = [0, endLocation.offset];
8179 break;
8180 default:
8181 textRange = [0, block.text.getLength()];
8182 }
8183 callback(block, textRange, index);
8184 }
8185 }
8186 }
8187 }
8188 getCommonAttributesAtRange(range) {
8189 range = normalizeRange(range);
8190 const [startPosition] = range;
8191 if (rangeIsCollapsed(range)) {
8192 return this.getCommonAttributesAtPosition(startPosition);
8193 } else {
8194 const textAttributes = [];
8195 const blockAttributes = [];
8196 this.eachBlockAtRange(range, function (block, textRange) {
8197 if (textRange[0] !== textRange[1]) {
8198 textAttributes.push(block.text.getCommonAttributesAtRange(textRange));
8199 return blockAttributes.push(attributesForBlock(block));
8200 }
8201 });
8202 return Hash.fromCommonAttributesOfObjects(textAttributes).merge(Hash.fromCommonAttributesOfObjects(blockAttributes)).toObject();
8203 }
8204 }
8205 getCommonAttributesAtPosition(position) {
8206 let key, value;
8207 const {
8208 index,
8209 offset
8210 } = this.locationFromPosition(position);
8211 const block = this.getBlockAtIndex(index);
8212 if (!block) {
8213 return {};
8214 }
8215 const commonAttributes = attributesForBlock(block);
8216 const attributes = block.text.getAttributesAtPosition(offset);
8217 const attributesLeft = block.text.getAttributesAtPosition(offset - 1);
8218 const inheritableAttributes = Object.keys(text_attributes).filter(key => {
8219 return text_attributes[key].inheritable;
8220 });
8221 for (key in attributesLeft) {
8222 value = attributesLeft[key];
8223 if (value === attributes[key] || inheritableAttributes.includes(key)) {
8224 commonAttributes[key] = value;
8225 }
8226 }
8227 return commonAttributes;
8228 }
8229 getRangeOfCommonAttributeAtPosition(attributeName, position) {
8230 const {
8231 index,
8232 offset
8233 } = this.locationFromPosition(position);
8234 const text = this.getTextAtIndex(index);
8235 const [startOffset, endOffset] = Array.from(text.getExpandedRangeForAttributeAtOffset(attributeName, offset));
8236 const start = this.positionFromLocation({
8237 index,
8238 offset: startOffset
8239 });
8240 const end = this.positionFromLocation({
8241 index,
8242 offset: endOffset
8243 });
8244 return normalizeRange([start, end]);
8245 }
8246 getBaseBlockAttributes() {
8247 let baseBlockAttributes = this.getBlockAtIndex(0).getAttributes();
8248 for (let blockIndex = 1; blockIndex < this.getBlockCount(); blockIndex++) {
8249 const blockAttributes = this.getBlockAtIndex(blockIndex).getAttributes();
8250 const lastAttributeIndex = Math.min(baseBlockAttributes.length, blockAttributes.length);
8251 baseBlockAttributes = (() => {
8252 const result = [];
8253 for (let index = 0; index < lastAttributeIndex; index++) {
8254 if (blockAttributes[index] !== baseBlockAttributes[index]) {
8255 break;
8256 }
8257 result.push(blockAttributes[index]);
8258 }
8259 return result;
8260 })();
8261 }
8262 return baseBlockAttributes;
8263 }
8264 getAttachmentById(attachmentId) {
8265 for (const attachment of this.getAttachments()) {
8266 if (attachment.id === attachmentId) {
8267 return attachment;
8268 }
8269 }
8270 }
8271 getAttachmentPieces() {
8272 let attachmentPieces = [];
8273 this.blockList.eachObject(_ref => {
8274 let {
8275 text
8276 } = _ref;
8277 return attachmentPieces = attachmentPieces.concat(text.getAttachmentPieces());
8278 });
8279 return attachmentPieces;
8280 }
8281 getAttachments() {
8282 return this.getAttachmentPieces().map(piece => piece.attachment);
8283 }
8284 getRangeOfAttachment(attachment) {
8285 let position = 0;
8286 const iterable = this.blockList.toArray();
8287 for (let index = 0; index < iterable.length; index++) {
8288 const {
8289 text
8290 } = iterable[index];
8291 const textRange = text.getRangeOfAttachment(attachment);
8292 if (textRange) {
8293 return normalizeRange([position + textRange[0], position + textRange[1]]);
8294 }
8295 position += text.getLength();
8296 }
8297 }
8298 getLocationRangeOfAttachment(attachment) {
8299 const range = this.getRangeOfAttachment(attachment);
8300 return this.locationRangeFromRange(range);
8301 }
8302 getAttachmentPieceForAttachment(attachment) {
8303 for (const piece of this.getAttachmentPieces()) {
8304 if (piece.attachment === attachment) {
8305 return piece;
8306 }
8307 }
8308 }
8309 findRangesForBlockAttribute(attributeName) {
8310 let position = 0;
8311 const ranges = [];
8312 this.getBlocks().forEach(block => {
8313 const length = block.getLength();
8314 if (block.hasAttribute(attributeName)) {
8315 ranges.push([position, position + length]);
8316 }
8317 position += length;
8318 });
8319 return ranges;
8320 }
8321 findRangesForTextAttribute(attributeName) {
8322 let {
8323 withValue
8324 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8325 let position = 0;
8326 let range = [];
8327 const ranges = [];
8328 const match = function (piece) {
8329 if (withValue) {
8330 return piece.getAttribute(attributeName) === withValue;
8331 } else {
8332 return piece.hasAttribute(attributeName);
8333 }
8334 };
8335 this.getPieces().forEach(piece => {
8336 const length = piece.getLength();
8337 if (match(piece)) {
8338 if (range[1] === position) {
8339 range[1] = position + length;
8340 } else {
8341 ranges.push(range = [position, position + length]);
8342 }
8343 }
8344 position += length;
8345 });
8346 return ranges;
8347 }
8348 locationFromPosition(position) {
8349 const location = this.blockList.findIndexAndOffsetAtPosition(Math.max(0, position));
8350 if (location.index != null) {
8351 return location;
8352 } else {
8353 const blocks = this.getBlocks();
8354 return {
8355 index: blocks.length - 1,
8356 offset: blocks[blocks.length - 1].getLength()
8357 };
8358 }
8359 }
8360 positionFromLocation(location) {
8361 return this.blockList.findPositionAtIndexAndOffset(location.index, location.offset);
8362 }
8363 locationRangeFromPosition(position) {
8364 return normalizeRange(this.locationFromPosition(position));
8365 }
8366 locationRangeFromRange(range) {
8367 range = normalizeRange(range);
8368 if (!range) return;
8369 const [startPosition, endPosition] = Array.from(range);
8370 const startLocation = this.locationFromPosition(startPosition);
8371 const endLocation = this.locationFromPosition(endPosition);
8372 return normalizeRange([startLocation, endLocation]);
8373 }
8374 rangeFromLocationRange(locationRange) {
8375 let rightPosition;
8376 locationRange = normalizeRange(locationRange);
8377 const leftPosition = this.positionFromLocation(locationRange[0]);
8378 if (!rangeIsCollapsed(locationRange)) {
8379 rightPosition = this.positionFromLocation(locationRange[1]);
8380 }
8381 return normalizeRange([leftPosition, rightPosition]);
8382 }
8383 isEqualTo(document) {
8384 return this.blockList.isEqualTo(document === null || document === void 0 ? void 0 : document.blockList);
8385 }
8386 getTexts() {
8387 return this.getBlocks().map(block => block.text);
8388 }
8389 getPieces() {
8390 const pieces = [];
8391 Array.from(this.getTexts()).forEach(text => {
8392 pieces.push(...Array.from(text.getPieces() || []));
8393 });
8394 return pieces;
8395 }
8396 getObjects() {
8397 return this.getBlocks().concat(this.getTexts()).concat(this.getPieces());
8398 }
8399 toSerializableDocument() {
8400 const blocks = [];
8401 this.blockList.eachObject(block => blocks.push(block.copyWithText(block.text.toSerializableText())));
8402 return new this.constructor(blocks);
8403 }
8404 toString() {
8405 return this.blockList.toString();
8406 }
8407 toJSON() {
8408 return this.blockList.toJSON();
8409 }
8410 toConsole() {
8411 return JSON.stringify(this.blockList.toArray().map(block => JSON.parse(block.text.toConsole())));
8412 }
8413 }
8414 const attributesForBlock = function (block) {
8415 const attributes = {};
8416 const attributeName = block.getLastAttribute();
8417 if (attributeName) {
8418 attributes[attributeName] = true;
8419 }
8420 return attributes;
8421 };
8422
8423 /* eslint-disable
8424 no-case-declarations,
8425 no-irregular-whitespace,
8426 */
8427 const pieceForString = function (string) {
8428 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8429 const type = "string";
8430 string = normalizeSpaces(string);
8431 return {
8432 string,
8433 attributes,
8434 type
8435 };
8436 };
8437 const pieceForAttachment = function (attachment) {
8438 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8439 const type = "attachment";
8440 return {
8441 attachment,
8442 attributes,
8443 type
8444 };
8445 };
8446 const blockForAttributes = function () {
8447 let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
8448 let htmlAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8449 const text = [];
8450 return {
8451 text,
8452 attributes,
8453 htmlAttributes
8454 };
8455 };
8456 const parseTrixDataAttribute = (element, name) => {
8457 try {
8458 return JSON.parse(element.getAttribute("data-trix-".concat(name)));
8459 } catch (error) {
8460 return {};
8461 }
8462 };
8463 const getImageDimensions = element => {
8464 const width = element.getAttribute("width");
8465 const height = element.getAttribute("height");
8466 const dimensions = {};
8467 if (width) {
8468 dimensions.width = parseInt(width, 10);
8469 }
8470 if (height) {
8471 dimensions.height = parseInt(height, 10);
8472 }
8473 return dimensions;
8474 };
8475 class HTMLParser extends BasicObject {
8476 static parse(html, options) {
8477 const parser = new this(html, options);
8478 parser.parse();
8479 return parser;
8480 }
8481 constructor(html) {
8482 let {
8483 referenceElement,
8484 purifyOptions
8485 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8486 super(...arguments);
8487 this.html = html;
8488 this.referenceElement = referenceElement;
8489 this.purifyOptions = purifyOptions;
8490 this.blocks = [];
8491 this.blockElements = [];
8492 this.processedElements = [];
8493 }
8494 getDocument() {
8495 return Document.fromJSON(this.blocks);
8496 }
8497
8498 // HTML parsing
8499
8500 parse() {
8501 try {
8502 this.createHiddenContainer();
8503 HTMLSanitizer.setHTML(this.containerElement, this.html, {
8504 purifyOptions: this.purifyOptions
8505 });
8506 const walker = walkTree(this.containerElement, {
8507 usingFilter: nodeFilter
8508 });
8509 while (walker.nextNode()) {
8510 this.processNode(walker.currentNode);
8511 }
8512 return this.translateBlockElementMarginsToNewlines();
8513 } finally {
8514 this.removeHiddenContainer();
8515 }
8516 }
8517 createHiddenContainer() {
8518 if (this.referenceElement) {
8519 this.containerElement = this.referenceElement.cloneNode(false);
8520 this.containerElement.removeAttribute("id");
8521 this.containerElement.setAttribute("data-trix-internal", "");
8522 this.containerElement.style.display = "none";
8523 return this.referenceElement.parentNode.insertBefore(this.containerElement, this.referenceElement.nextSibling);
8524 } else {
8525 this.containerElement = makeElement({
8526 tagName: "div",
8527 style: {
8528 display: "none"
8529 }
8530 });
8531 return document.body.appendChild(this.containerElement);
8532 }
8533 }
8534 removeHiddenContainer() {
8535 return removeNode(this.containerElement);
8536 }
8537 processNode(node) {
8538 switch (node.nodeType) {
8539 case Node.TEXT_NODE:
8540 if (!this.isInsignificantTextNode(node)) {
8541 this.appendBlockForTextNode(node);
8542 return this.processTextNode(node);
8543 }
8544 break;
8545 case Node.ELEMENT_NODE:
8546 this.appendBlockForElement(node);
8547 return this.processElement(node);
8548 }
8549 }
8550 appendBlockForTextNode(node) {
8551 const element = node.parentNode;
8552 if (element === this.currentBlockElement && this.isBlockElement(node.previousSibling)) {
8553 return this.appendStringWithAttributes("\n");
8554 } else if (element === this.containerElement || this.isBlockElement(element)) {
8555 var _this$currentBlock;
8556 const attributes = this.getBlockAttributes(element);
8557 const htmlAttributes = this.getBlockHTMLAttributes(element);
8558 if (!arraysAreEqual(attributes, (_this$currentBlock = this.currentBlock) === null || _this$currentBlock === void 0 ? void 0 : _this$currentBlock.attributes)) {
8559 this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
8560 this.currentBlockElement = element;
8561 }
8562 }
8563 }
8564 appendBlockForElement(element) {
8565 const elementIsBlockElement = this.isBlockElement(element);
8566 const currentBlockContainsElement = elementContainsNode(this.currentBlockElement, element);
8567 if (elementIsBlockElement && !this.isBlockElement(element.firstChild)) {
8568 if (!this.isInsignificantTextNode(element.firstChild) || !this.isBlockElement(element.firstElementChild)) {
8569 const attributes = this.getBlockAttributes(element);
8570 const htmlAttributes = this.getBlockHTMLAttributes(element);
8571 if (element.firstChild) {
8572 if (!(currentBlockContainsElement && arraysAreEqual(attributes, this.currentBlock.attributes))) {
8573 this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
8574 this.currentBlockElement = element;
8575 } else {
8576 return this.appendStringWithAttributes("\n");
8577 }
8578 }
8579 }
8580 } else if (this.currentBlockElement && !currentBlockContainsElement && !elementIsBlockElement) {
8581 const parentBlockElement = this.findParentBlockElement(element);
8582 if (parentBlockElement) {
8583 return this.appendBlockForElement(parentBlockElement);
8584 } else {
8585 this.currentBlock = this.appendEmptyBlock();
8586 this.currentBlockElement = null;
8587 }
8588 }
8589 }
8590 findParentBlockElement(element) {
8591 let {
8592 parentElement
8593 } = element;
8594 while (parentElement && parentElement !== this.containerElement) {
8595 if (this.isBlockElement(parentElement) && this.blockElements.includes(parentElement)) {
8596 return parentElement;
8597 } else {
8598 parentElement = parentElement.parentElement;
8599 }
8600 }
8601 return null;
8602 }
8603 processTextNode(node) {
8604 let string = node.data;
8605 if (!elementCanDisplayPreformattedText(node.parentNode)) {
8606 var _node$previousSibling;
8607 string = squishBreakableWhitespace(string);
8608 if (stringEndsWithWhitespace((_node$previousSibling = node.previousSibling) === null || _node$previousSibling === void 0 ? void 0 : _node$previousSibling.textContent)) {
8609 string = leftTrimBreakableWhitespace(string);
8610 }
8611 }
8612 return this.appendStringWithAttributes(string, this.getTextAttributes(node.parentNode));
8613 }
8614 processElement(element) {
8615 let attributes;
8616 if (nodeIsAttachmentElement(element)) {
8617 attributes = parseTrixDataAttribute(element, "attachment");
8618 if (Object.keys(attributes).length) {
8619 const textAttributes = this.getTextAttributes(element);
8620 this.appendAttachmentWithAttributes(attributes, textAttributes);
8621 // We have everything we need so avoid processing inner nodes
8622 element.innerHTML = "";
8623 }
8624 return this.processedElements.push(element);
8625 } else {
8626 switch (tagName(element)) {
8627 case "br":
8628 if (!this.isExtraBR(element) && !this.isBlockElement(element.nextSibling)) {
8629 this.appendStringWithAttributes("\n", this.getTextAttributes(element));
8630 }
8631 return this.processedElements.push(element);
8632 case "img":
8633 attributes = {
8634 url: element.getAttribute("src"),
8635 contentType: "image"
8636 };
8637 const object = getImageDimensions(element);
8638 for (const key in object) {
8639 const value = object[key];
8640 attributes[key] = value;
8641 }
8642 this.appendAttachmentWithAttributes(attributes, this.getTextAttributes(element));
8643 return this.processedElements.push(element);
8644 case "tr":
8645 if (this.needsTableSeparator(element)) {
8646 return this.appendStringWithAttributes(parser.tableRowSeparator);
8647 }
8648 break;
8649 case "td":
8650 if (this.needsTableSeparator(element)) {
8651 return this.appendStringWithAttributes(parser.tableCellSeparator);
8652 }
8653 break;
8654 }
8655 }
8656 }
8657
8658 // Document construction
8659
8660 appendBlockForAttributesWithElement(attributes, element) {
8661 let htmlAttributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
8662 this.blockElements.push(element);
8663 const block = blockForAttributes(attributes, htmlAttributes);
8664 this.blocks.push(block);
8665 return block;
8666 }
8667 appendEmptyBlock() {
8668 return this.appendBlockForAttributesWithElement([], null);
8669 }
8670 appendStringWithAttributes(string, attributes) {
8671 return this.appendPiece(pieceForString(string, attributes));
8672 }
8673 appendAttachmentWithAttributes(attachment, attributes) {
8674 return this.appendPiece(pieceForAttachment(attachment, attributes));
8675 }
8676 appendPiece(piece) {
8677 if (this.blocks.length === 0) {
8678 this.appendEmptyBlock();
8679 }
8680 return this.blocks[this.blocks.length - 1].text.push(piece);
8681 }
8682 appendStringToTextAtIndex(string, index) {
8683 const {
8684 text
8685 } = this.blocks[index];
8686 const piece = text[text.length - 1];
8687 if ((piece === null || piece === void 0 ? void 0 : piece.type) === "string") {
8688 piece.string += string;
8689 } else {
8690 return text.push(pieceForString(string));
8691 }
8692 }
8693 prependStringToTextAtIndex(string, index) {
8694 const {
8695 text
8696 } = this.blocks[index];
8697 const piece = text[0];
8698 if ((piece === null || piece === void 0 ? void 0 : piece.type) === "string") {
8699 piece.string = string + piece.string;
8700 } else {
8701 return text.unshift(pieceForString(string));
8702 }
8703 }
8704
8705 // Attribute parsing
8706
8707 getTextAttributes(element) {
8708 let value;
8709 const attributes = {};
8710 for (const attribute in text_attributes) {
8711 const configAttr = text_attributes[attribute];
8712 if (configAttr.tagName && findClosestElementFromNode(element, {
8713 matchingSelector: configAttr.tagName,
8714 untilNode: this.containerElement
8715 })) {
8716 attributes[attribute] = true;
8717 } else if (configAttr.parser) {
8718 value = configAttr.parser(element);
8719 if (value) {
8720 let attributeInheritedFromBlock = false;
8721 for (const blockElement of this.findBlockElementAncestors(element)) {
8722 if (configAttr.parser(blockElement) === value) {
8723 attributeInheritedFromBlock = true;
8724 break;
8725 }
8726 }
8727 if (!attributeInheritedFromBlock) {
8728 attributes[attribute] = value;
8729 }
8730 }
8731 } else if (configAttr.styleProperty) {
8732 value = element.style[configAttr.styleProperty];
8733 if (value) {
8734 attributes[attribute] = value;
8735 }
8736 }
8737 }
8738 if (nodeIsAttachmentElement(element)) {
8739 const object = parseTrixDataAttribute(element, "attributes");
8740 for (const key in object) {
8741 value = object[key];
8742 attributes[key] = value;
8743 }
8744 }
8745 return attributes;
8746 }
8747 getBlockAttributes(element) {
8748 const attributes$1 = [];
8749 while (element && element !== this.containerElement) {
8750 for (const attribute in attributes) {
8751 const attrConfig = attributes[attribute];
8752 if (attrConfig.parse !== false) {
8753 if (tagName(element) === attrConfig.tagName) {
8754 var _attrConfig$test;
8755 if ((_attrConfig$test = attrConfig.test) !== null && _attrConfig$test !== void 0 && _attrConfig$test.call(attrConfig, element) || !attrConfig.test) {
8756 attributes$1.push(attribute);
8757 if (attrConfig.listAttribute) {
8758 attributes$1.push(attrConfig.listAttribute);
8759 }
8760 }
8761 }
8762 }
8763 }
8764 element = element.parentNode;
8765 }
8766 return attributes$1.reverse();
8767 }
8768 getBlockHTMLAttributes(element) {
8769 const attributes$1 = {};
8770 const blockConfig = Object.values(attributes).find(settings => settings.tagName === tagName(element));
8771 const allowedAttributes = (blockConfig === null || blockConfig === void 0 ? void 0 : blockConfig.htmlAttributes) || [];
8772 allowedAttributes.forEach(attribute => {
8773 if (element.hasAttribute(attribute)) {
8774 attributes$1[attribute] = element.getAttribute(attribute);
8775 }
8776 });
8777 return attributes$1;
8778 }
8779 findBlockElementAncestors(element) {
8780 const ancestors = [];
8781 while (element && element !== this.containerElement) {
8782 const tag = tagName(element);
8783 if (getBlockTagNames().includes(tag)) {
8784 ancestors.push(element);
8785 }
8786 element = element.parentNode;
8787 }
8788 return ancestors;
8789 }
8790
8791 // Element inspection
8792
8793 isBlockElement(element) {
8794 if ((element === null || element === void 0 ? void 0 : element.nodeType) !== Node.ELEMENT_NODE) return;
8795 if (nodeIsAttachmentElement(element)) return;
8796 if (findClosestElementFromNode(element, {
8797 matchingSelector: "td",
8798 untilNode: this.containerElement
8799 })) return;
8800 return getBlockTagNames().includes(tagName(element)) || window.getComputedStyle(element).display === "block";
8801 }
8802 isInsignificantTextNode(node) {
8803 if ((node === null || node === void 0 ? void 0 : node.nodeType) !== Node.TEXT_NODE) return;
8804 if (!stringIsAllBreakableWhitespace(node.data)) return;
8805 const {
8806 parentNode,
8807 previousSibling,
8808 nextSibling
8809 } = node;
8810 if (nodeEndsWithNonWhitespace(parentNode.previousSibling) && !this.isBlockElement(parentNode.previousSibling)) return;
8811 if (elementCanDisplayPreformattedText(parentNode)) return;
8812 return !previousSibling || this.isBlockElement(previousSibling) || !nextSibling || this.isBlockElement(nextSibling);
8813 }
8814 isExtraBR(element) {
8815 return tagName(element) === "br" && this.isBlockElement(element.parentNode) && element.parentNode.lastChild === element;
8816 }
8817 needsTableSeparator(element) {
8818 if (parser.removeBlankTableCells) {
8819 var _element$previousSibl;
8820 const content = (_element$previousSibl = element.previousSibling) === null || _element$previousSibl === void 0 ? void 0 : _element$previousSibl.textContent;
8821 return content && /\S/.test(content);
8822 } else {
8823 return element.previousSibling;
8824 }
8825 }
8826
8827 // Margin translation
8828
8829 translateBlockElementMarginsToNewlines() {
8830 const defaultMargin = this.getMarginOfDefaultBlockElement();
8831 for (let index = 0; index < this.blocks.length; index++) {
8832 const margin = this.getMarginOfBlockElementAtIndex(index);
8833 if (margin) {
8834 if (margin.top > defaultMargin.top * 2) {
8835 this.prependStringToTextAtIndex("\n", index);
8836 }
8837 if (margin.bottom > defaultMargin.bottom * 2) {
8838 this.appendStringToTextAtIndex("\n", index);
8839 }
8840 }
8841 }
8842 }
8843 getMarginOfBlockElementAtIndex(index) {
8844 const element = this.blockElements[index];
8845 if (element) {
8846 if (element.textContent) {
8847 if (!getBlockTagNames().includes(tagName(element)) && !this.processedElements.includes(element)) {
8848 return getBlockElementMargin(element);
8849 }
8850 }
8851 }
8852 }
8853 getMarginOfDefaultBlockElement() {
8854 const element = makeElement(attributes.default.tagName);
8855 this.containerElement.appendChild(element);
8856 return getBlockElementMargin(element);
8857 }
8858 }
8859
8860 // Helpers
8861
8862 const elementCanDisplayPreformattedText = function (element) {
8863 const {
8864 whiteSpace
8865 } = window.getComputedStyle(element);
8866 return ["pre", "pre-wrap", "pre-line"].includes(whiteSpace);
8867 };
8868 const nodeEndsWithNonWhitespace = node => node && !stringEndsWithWhitespace(node.textContent);
8869 const getBlockElementMargin = function (element) {
8870 const style = window.getComputedStyle(element);
8871 if (style.display === "block") {
8872 return {
8873 top: parseInt(style.marginTop),
8874 bottom: parseInt(style.marginBottom)
8875 };
8876 }
8877 };
8878 const nodeFilter = function (node) {
8879 if (tagName(node) === "style") {
8880 return NodeFilter.FILTER_REJECT;
8881 } else {
8882 return NodeFilter.FILTER_ACCEPT;
8883 }
8884 };
8885
8886 // Whitespace
8887
8888 const leftTrimBreakableWhitespace = string => string.replace(new RegExp("^".concat(breakableWhitespacePattern.source, "+")), "");
8889 const stringIsAllBreakableWhitespace = string => new RegExp("^".concat(breakableWhitespacePattern.source, "*$")).test(string);
8890 const stringEndsWithWhitespace = string => /\s$/.test(string);
8891
8892 /* eslint-disable
8893 no-empty,
8894 */
8895 const unserializableElementSelector = "[data-trix-serialize=false]";
8896 const unserializableAttributeNames = ["contenteditable", "data-trix-id", "data-trix-store-key", "data-trix-mutable", "data-trix-placeholder", "tabindex"];
8897 const serializedAttributesAttribute = "data-trix-serialized-attributes";
8898 const serializedAttributesSelector = "[".concat(serializedAttributesAttribute, "]");
8899 const blockCommentPattern = new RegExp("<!--block-->", "g");
8900 const serializers = {
8901 "application/json": function (serializable) {
8902 let document;
8903 if (serializable instanceof Document) {
8904 document = serializable;
8905 } else if (serializable instanceof HTMLElement) {
8906 document = HTMLParser.parse(serializable.innerHTML).getDocument();
8907 } else {
8908 throw new Error("unserializable object");
8909 }
8910 return document.toSerializableDocument().toJSONString();
8911 },
8912 "text/html": function (serializable) {
8913 let element;
8914 if (serializable instanceof Document) {
8915 element = DocumentView.render(serializable);
8916 } else if (serializable instanceof HTMLElement) {
8917 element = serializable.cloneNode(true);
8918 } else {
8919 throw new Error("unserializable object");
8920 }
8921
8922 // Remove unserializable elements
8923 Array.from(element.querySelectorAll(unserializableElementSelector)).forEach(el => {
8924 removeNode(el);
8925 });
8926
8927 // Remove unserializable attributes
8928 unserializableAttributeNames.forEach(attribute => {
8929 Array.from(element.querySelectorAll("[".concat(attribute, "]"))).forEach(el => {
8930 el.removeAttribute(attribute);
8931 });
8932 });
8933
8934 // Rewrite elements with serialized attribute overrides
8935 Array.from(element.querySelectorAll(serializedAttributesSelector)).forEach(el => {
8936 try {
8937 const attributes = JSON.parse(el.getAttribute(serializedAttributesAttribute));
8938 el.removeAttribute(serializedAttributesAttribute);
8939 for (const name in attributes) {
8940 const value = attributes[name];
8941 el.setAttribute(name, value);
8942 }
8943 } catch (error) {}
8944 });
8945 return element.innerHTML.replace(blockCommentPattern, "");
8946 }
8947 };
8948 const deserializers = {
8949 "application/json": function (string) {
8950 return Document.fromJSONString(string);
8951 },
8952 "text/html": function (string) {
8953 return HTMLParser.parse(string).getDocument();
8954 }
8955 };
8956 const serializeToContentType = function (serializable, contentType) {
8957 const serializer = serializers[contentType];
8958 if (serializer) {
8959 return serializer(serializable);
8960 } else {
8961 throw new Error("unknown content type: ".concat(contentType));
8962 }
8963 };
8964 const deserializeFromContentType = function (string, contentType) {
8965 const deserializer = deserializers[contentType];
8966 if (deserializer) {
8967 return deserializer(string);
8968 } else {
8969 throw new Error("unknown content type: ".concat(contentType));
8970 }
8971 };
8972
8973 var core = /*#__PURE__*/Object.freeze({
8974 __proto__: null
8975 });
8976
8977 class ManagedAttachment extends BasicObject {
8978 constructor(attachmentManager, attachment) {
8979 super(...arguments);
8980 this.attachmentManager = attachmentManager;
8981 this.attachment = attachment;
8982 this.id = this.attachment.id;
8983 this.file = this.attachment.file;
8984 }
8985 remove() {
8986 return this.attachmentManager.requestRemovalOfAttachment(this.attachment);
8987 }
8988 }
8989 ManagedAttachment.proxyMethod("attachment.getAttribute");
8990 ManagedAttachment.proxyMethod("attachment.hasAttribute");
8991 ManagedAttachment.proxyMethod("attachment.setAttribute");
8992 ManagedAttachment.proxyMethod("attachment.getAttributes");
8993 ManagedAttachment.proxyMethod("attachment.setAttributes");
8994 ManagedAttachment.proxyMethod("attachment.isPending");
8995 ManagedAttachment.proxyMethod("attachment.isPreviewable");
8996 ManagedAttachment.proxyMethod("attachment.getURL");
8997 ManagedAttachment.proxyMethod("attachment.getPreviewURL");
8998 ManagedAttachment.proxyMethod("attachment.setPreviewURL");
8999 ManagedAttachment.proxyMethod("attachment.getHref");
9000 ManagedAttachment.proxyMethod("attachment.getFilename");
9001 ManagedAttachment.proxyMethod("attachment.getFilesize");
9002 ManagedAttachment.proxyMethod("attachment.getFormattedFilesize");
9003 ManagedAttachment.proxyMethod("attachment.getExtension");
9004 ManagedAttachment.proxyMethod("attachment.getContentType");
9005 ManagedAttachment.proxyMethod("attachment.getFile");
9006 ManagedAttachment.proxyMethod("attachment.setFile");
9007 ManagedAttachment.proxyMethod("attachment.releaseFile");
9008 ManagedAttachment.proxyMethod("attachment.getUploadProgress");
9009 ManagedAttachment.proxyMethod("attachment.setUploadProgress");
9010
9011 class AttachmentManager extends BasicObject {
9012 constructor() {
9013 let attachments = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
9014 super(...arguments);
9015 this.managedAttachments = {};
9016 Array.from(attachments).forEach(attachment => {
9017 this.manageAttachment(attachment);
9018 });
9019 }
9020 getAttachments() {
9021 const result = [];
9022 for (const id in this.managedAttachments) {
9023 const attachment = this.managedAttachments[id];
9024 result.push(attachment);
9025 }
9026 return result;
9027 }
9028 manageAttachment(attachment) {
9029 if (!this.managedAttachments[attachment.id]) {
9030 this.managedAttachments[attachment.id] = new ManagedAttachment(this, attachment);
9031 }
9032 return this.managedAttachments[attachment.id];
9033 }
9034 attachmentIsManaged(attachment) {
9035 return attachment.id in this.managedAttachments;
9036 }
9037 requestRemovalOfAttachment(attachment) {
9038 if (this.attachmentIsManaged(attachment)) {
9039 var _this$delegate, _this$delegate$attach;
9040 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);
9041 }
9042 }
9043 unmanageAttachment(attachment) {
9044 const managedAttachment = this.managedAttachments[attachment.id];
9045 delete this.managedAttachments[attachment.id];
9046 return managedAttachment;
9047 }
9048 }
9049
9050 class LineBreakInsertion {
9051 constructor(composition) {
9052 this.composition = composition;
9053 this.document = this.composition.document;
9054 const selectedRange = this.composition.getSelectedRange();
9055 this.startPosition = selectedRange[0];
9056 this.endPosition = selectedRange[1];
9057 this.startLocation = this.document.locationFromPosition(this.startPosition);
9058 this.endLocation = this.document.locationFromPosition(this.endPosition);
9059 this.block = this.document.getBlockAtIndex(this.endLocation.index);
9060 this.breaksOnReturn = this.block.breaksOnReturn();
9061 this.previousCharacter = this.block.text.getStringAtPosition(this.endLocation.offset - 1);
9062 this.nextCharacter = this.block.text.getStringAtPosition(this.endLocation.offset);
9063 }
9064 shouldInsertBlockBreak() {
9065 if (this.block.hasAttributes() && this.block.isListItem() && !this.block.isEmpty()) {
9066 return this.startLocation.offset !== 0;
9067 } else {
9068 return this.breaksOnReturn && this.nextCharacter !== "\n";
9069 }
9070 }
9071 shouldBreakFormattedBlock() {
9072 return this.block.hasAttributes() && !this.block.isListItem() && (this.breaksOnReturn && this.nextCharacter === "\n" || this.previousCharacter === "\n");
9073 }
9074 shouldDecreaseListLevel() {
9075 return this.block.hasAttributes() && this.block.isListItem() && this.block.isEmpty();
9076 }
9077 shouldPrependListItem() {
9078 return this.block.isListItem() && this.startLocation.offset === 0 && !this.block.isEmpty();
9079 }
9080 shouldRemoveLastBlockAttribute() {
9081 return this.block.hasAttributes() && !this.block.isListItem() && this.block.isEmpty();
9082 }
9083 }
9084
9085 const PLACEHOLDER = " ";
9086 class Composition extends BasicObject {
9087 constructor() {
9088 super(...arguments);
9089 this.document = new Document();
9090 this.attachments = [];
9091 this.currentAttributes = {};
9092 this.revision = 0;
9093 }
9094 setDocument(document) {
9095 if (!document.isEqualTo(this.document)) {
9096 var _this$delegate, _this$delegate$compos;
9097 this.document = document;
9098 this.refreshAttachments();
9099 this.revision++;
9100 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);
9101 }
9102 }
9103
9104 // Snapshots
9105
9106 getSnapshot() {
9107 return {
9108 document: this.document,
9109 selectedRange: this.getSelectedRange()
9110 };
9111 }
9112 loadSnapshot(_ref) {
9113 var _this$delegate2, _this$delegate2$compo, _this$delegate3, _this$delegate3$compo;
9114 let {
9115 document,
9116 selectedRange
9117 } = _ref;
9118 (_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);
9119 this.setDocument(document != null ? document : new Document());
9120 this.setSelection(selectedRange != null ? selectedRange : [0, 0]);
9121 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);
9122 }
9123
9124 // Responder protocol
9125
9126 insertText(text) {
9127 let {
9128 updatePosition
9129 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
9130 updatePosition: true
9131 };
9132 const selectedRange = this.getSelectedRange();
9133 this.setDocument(this.document.insertTextAtRange(text, selectedRange));
9134 const startPosition = selectedRange[0];
9135 const endPosition = startPosition + text.getLength();
9136 if (updatePosition) {
9137 this.setSelection(endPosition);
9138 }
9139 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
9140 }
9141 insertBlock() {
9142 let block = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Block();
9143 const document = new Document([block]);
9144 return this.insertDocument(document);
9145 }
9146 insertDocument() {
9147 let document = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Document();
9148 const selectedRange = this.getSelectedRange();
9149 this.setDocument(this.document.insertDocumentAtRange(document, selectedRange));
9150 const startPosition = selectedRange[0];
9151 const endPosition = startPosition + document.getLength();
9152 this.setSelection(endPosition);
9153 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
9154 }
9155 insertString(string, options) {
9156 const attributes = this.getCurrentTextAttributes();
9157 const text = Text.textForStringWithAttributes(string, attributes);
9158 return this.insertText(text, options);
9159 }
9160 insertBlockBreak() {
9161 const selectedRange = this.getSelectedRange();
9162 this.setDocument(this.document.insertBlockBreakAtRange(selectedRange));
9163 const startPosition = selectedRange[0];
9164 const endPosition = startPosition + 1;
9165 this.setSelection(endPosition);
9166 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
9167 }
9168 insertLineBreak() {
9169 const insertion = new LineBreakInsertion(this);
9170 if (insertion.shouldDecreaseListLevel()) {
9171 this.decreaseListLevel();
9172 return this.setSelection(insertion.startPosition);
9173 } else if (insertion.shouldPrependListItem()) {
9174 const document = new Document([insertion.block.copyWithoutText()]);
9175 return this.insertDocument(document);
9176 } else if (insertion.shouldInsertBlockBreak()) {
9177 return this.insertBlockBreak();
9178 } else if (insertion.shouldRemoveLastBlockAttribute()) {
9179 return this.removeLastBlockAttribute();
9180 } else if (insertion.shouldBreakFormattedBlock()) {
9181 return this.breakFormattedBlock(insertion);
9182 } else {
9183 return this.insertString("\n");
9184 }
9185 }
9186 insertHTML(html) {
9187 const document = HTMLParser.parse(html, {
9188 purifyOptions: {
9189 SAFE_FOR_XML: true
9190 }
9191 }).getDocument();
9192 const selectedRange = this.getSelectedRange();
9193 this.setDocument(this.document.mergeDocumentAtRange(document, selectedRange));
9194 const startPosition = selectedRange[0];
9195 const endPosition = startPosition + document.getLength() - 1;
9196 this.setSelection(endPosition);
9197 return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
9198 }
9199 replaceHTML(html) {
9200 const document = HTMLParser.parse(html).getDocument().copyUsingObjectsFromDocument(this.document);
9201 const locationRange = this.getLocationRange({
9202 strict: false
9203 });
9204 const selectedRange = this.document.rangeFromLocationRange(locationRange);
9205 this.setDocument(document);
9206 return this.setSelection(selectedRange);
9207 }
9208 insertFile(file) {
9209 return this.insertFiles([file]);
9210 }
9211 insertFiles(files) {
9212 const attachments = [];
9213 Array.from(files).forEach(file => {
9214 var _this$delegate4;
9215 if ((_this$delegate4 = this.delegate) !== null && _this$delegate4 !== void 0 && _this$delegate4.compositionShouldAcceptFile(file)) {
9216 const attachment = Attachment.attachmentForFile(file);
9217 attachments.push(attachment);
9218 }
9219 });
9220 return this.insertAttachments(attachments);
9221 }
9222 insertAttachment(attachment) {
9223 return this.insertAttachments([attachment]);
9224 }
9225 insertAttachments(attachments$1) {
9226 let text = new Text();
9227 Array.from(attachments$1).forEach(attachment => {
9228 var _config$attachments$t;
9229 const type = attachment.getType();
9230 const presentation = (_config$attachments$t = attachments[type]) === null || _config$attachments$t === void 0 ? void 0 : _config$attachments$t.presentation;
9231 const attributes = this.getCurrentTextAttributes();
9232 if (presentation) {
9233 attributes.presentation = presentation;
9234 }
9235 const attachmentText = Text.textForAttachmentWithAttributes(attachment, attributes);
9236 text = text.appendText(attachmentText);
9237 });
9238 return this.insertText(text);
9239 }
9240 shouldManageDeletingInDirection(direction) {
9241 const locationRange = this.getLocationRange();
9242 if (rangeIsCollapsed(locationRange)) {
9243 if (direction === "backward" && locationRange[0].offset === 0) {
9244 return true;
9245 }
9246 if (this.shouldManageMovingCursorInDirection(direction)) {
9247 return true;
9248 }
9249 } else {
9250 if (locationRange[0].index !== locationRange[1].index) {
9251 return true;
9252 }
9253 }
9254 return false;
9255 }
9256 deleteInDirection(direction) {
9257 let {
9258 length
9259 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9260 let attachment, deletingIntoPreviousBlock, selectionSpansBlocks;
9261 const locationRange = this.getLocationRange();
9262 let range = this.getSelectedRange();
9263 const selectionIsCollapsed = rangeIsCollapsed(range);
9264 if (selectionIsCollapsed) {
9265 deletingIntoPreviousBlock = direction === "backward" && locationRange[0].offset === 0;
9266 } else {
9267 selectionSpansBlocks = locationRange[0].index !== locationRange[1].index;
9268 }
9269 if (deletingIntoPreviousBlock) {
9270 if (this.canDecreaseBlockAttributeLevel()) {
9271 const block = this.getBlock();
9272 if (block.isListItem()) {
9273 this.decreaseListLevel();
9274 } else {
9275 this.decreaseBlockAttributeLevel();
9276 }
9277 this.setSelection(range[0]);
9278 if (block.isEmpty()) {
9279 return false;
9280 }
9281 }
9282 }
9283 if (selectionIsCollapsed) {
9284 range = this.getExpandedRangeInDirection(direction, {
9285 length
9286 });
9287 if (direction === "backward") {
9288 attachment = this.getAttachmentAtRange(range);
9289 }
9290 }
9291 if (attachment) {
9292 this.editAttachment(attachment);
9293 return false;
9294 } else {
9295 this.setDocument(this.document.removeTextAtRange(range));
9296 this.setSelection(range[0]);
9297 if (deletingIntoPreviousBlock || selectionSpansBlocks) {
9298 return false;
9299 }
9300 }
9301 }
9302 moveTextFromRange(range) {
9303 const [position] = Array.from(this.getSelectedRange());
9304 this.setDocument(this.document.moveTextFromRangeToPosition(range, position));
9305 return this.setSelection(position);
9306 }
9307 removeAttachment(attachment) {
9308 const range = this.document.getRangeOfAttachment(attachment);
9309 if (range) {
9310 this.stopEditingAttachment();
9311 this.setDocument(this.document.removeTextAtRange(range));
9312 return this.setSelection(range[0]);
9313 }
9314 }
9315 removeLastBlockAttribute() {
9316 const [startPosition, endPosition] = Array.from(this.getSelectedRange());
9317 const block = this.document.getBlockAtPosition(endPosition);
9318 this.removeCurrentAttribute(block.getLastAttribute());
9319 return this.setSelection(startPosition);
9320 }
9321 insertPlaceholder() {
9322 this.placeholderPosition = this.getPosition();
9323 return this.insertString(PLACEHOLDER);
9324 }
9325 selectPlaceholder() {
9326 if (this.placeholderPosition != null) {
9327 this.setSelectedRange([this.placeholderPosition, this.placeholderPosition + PLACEHOLDER.length]);
9328 return this.getSelectedRange();
9329 }
9330 }
9331 forgetPlaceholder() {
9332 this.placeholderPosition = null;
9333 }
9334
9335 // Current attributes
9336
9337 hasCurrentAttribute(attributeName) {
9338 const value = this.currentAttributes[attributeName];
9339 return value != null && value !== false;
9340 }
9341 toggleCurrentAttribute(attributeName) {
9342 const value = !this.currentAttributes[attributeName];
9343 if (value) {
9344 return this.setCurrentAttribute(attributeName, value);
9345 } else {
9346 return this.removeCurrentAttribute(attributeName);
9347 }
9348 }
9349 canSetCurrentAttribute(attributeName) {
9350 if (getBlockConfig(attributeName)) {
9351 return this.canSetCurrentBlockAttribute(attributeName);
9352 } else {
9353 return this.canSetCurrentTextAttribute(attributeName);
9354 }
9355 }
9356 canSetCurrentTextAttribute(attributeName) {
9357 const document = this.getSelectedDocument();
9358 if (!document) return;
9359 for (const attachment of Array.from(document.getAttachments())) {
9360 if (!attachment.hasContent()) {
9361 return false;
9362 }
9363 }
9364 return true;
9365 }
9366 canSetCurrentBlockAttribute(attributeName) {
9367 const block = this.getBlock();
9368 if (!block) return;
9369 return !block.isTerminalBlock();
9370 }
9371 setCurrentAttribute(attributeName, value) {
9372 if (getBlockConfig(attributeName)) {
9373 return this.setBlockAttribute(attributeName, value);
9374 } else {
9375 this.setTextAttribute(attributeName, value);
9376 this.currentAttributes[attributeName] = value;
9377 return this.notifyDelegateOfCurrentAttributesChange();
9378 }
9379 }
9380 setHTMLAtributeAtPosition(position, attributeName, value) {
9381 var _getBlockConfig;
9382 const block = this.document.getBlockAtPosition(position);
9383 const allowedHTMLAttributes = (_getBlockConfig = getBlockConfig(block.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.htmlAttributes;
9384 if (block && allowedHTMLAttributes !== null && allowedHTMLAttributes !== void 0 && allowedHTMLAttributes.includes(attributeName)) {
9385 const newDocument = this.document.setHTMLAttributeAtPosition(position, attributeName, value);
9386 this.setDocument(newDocument);
9387 }
9388 }
9389 setTextAttribute(attributeName, value) {
9390 const selectedRange = this.getSelectedRange();
9391 if (!selectedRange) return;
9392 const [startPosition, endPosition] = Array.from(selectedRange);
9393 if (startPosition === endPosition) {
9394 if (attributeName === "href") {
9395 const text = Text.textForStringWithAttributes(value, {
9396 href: value
9397 });
9398 return this.insertText(text);
9399 }
9400 } else {
9401 return this.setDocument(this.document.addAttributeAtRange(attributeName, value, selectedRange));
9402 }
9403 }
9404 setBlockAttribute(attributeName, value) {
9405 const selectedRange = this.getSelectedRange();
9406 if (this.canSetCurrentAttribute(attributeName)) {
9407 this.setDocument(this.document.applyBlockAttributeAtRange(attributeName, value, selectedRange));
9408 return this.setSelection(selectedRange);
9409 }
9410 }
9411 removeCurrentAttribute(attributeName) {
9412 if (getBlockConfig(attributeName)) {
9413 this.removeBlockAttribute(attributeName);
9414 return this.updateCurrentAttributes();
9415 } else {
9416 this.removeTextAttribute(attributeName);
9417 delete this.currentAttributes[attributeName];
9418 return this.notifyDelegateOfCurrentAttributesChange();
9419 }
9420 }
9421 removeTextAttribute(attributeName) {
9422 const selectedRange = this.getSelectedRange();
9423 if (!selectedRange) return;
9424 return this.setDocument(this.document.removeAttributeAtRange(attributeName, selectedRange));
9425 }
9426 removeBlockAttribute(attributeName) {
9427 const selectedRange = this.getSelectedRange();
9428 if (!selectedRange) return;
9429 return this.setDocument(this.document.removeAttributeAtRange(attributeName, selectedRange));
9430 }
9431 canDecreaseNestingLevel() {
9432 var _this$getBlock;
9433 return ((_this$getBlock = this.getBlock()) === null || _this$getBlock === void 0 ? void 0 : _this$getBlock.getNestingLevel()) > 0;
9434 }
9435 canIncreaseNestingLevel() {
9436 var _getBlockConfig2;
9437 const block = this.getBlock();
9438 if (!block) return;
9439 if ((_getBlockConfig2 = getBlockConfig(block.getLastNestableAttribute())) !== null && _getBlockConfig2 !== void 0 && _getBlockConfig2.listAttribute) {
9440 const previousBlock = this.getPreviousBlock();
9441 if (previousBlock) {
9442 return arrayStartsWith(previousBlock.getListItemAttributes(), block.getListItemAttributes());
9443 }
9444 } else {
9445 return block.getNestingLevel() > 0;
9446 }
9447 }
9448 decreaseNestingLevel() {
9449 const block = this.getBlock();
9450 if (!block) return;
9451 return this.setDocument(this.document.replaceBlock(block, block.decreaseNestingLevel()));
9452 }
9453 increaseNestingLevel() {
9454 const block = this.getBlock();
9455 if (!block) return;
9456 return this.setDocument(this.document.replaceBlock(block, block.increaseNestingLevel()));
9457 }
9458 canDecreaseBlockAttributeLevel() {
9459 var _this$getBlock2;
9460 return ((_this$getBlock2 = this.getBlock()) === null || _this$getBlock2 === void 0 ? void 0 : _this$getBlock2.getAttributeLevel()) > 0;
9461 }
9462 decreaseBlockAttributeLevel() {
9463 var _this$getBlock3;
9464 const attribute = (_this$getBlock3 = this.getBlock()) === null || _this$getBlock3 === void 0 ? void 0 : _this$getBlock3.getLastAttribute();
9465 if (attribute) {
9466 return this.removeCurrentAttribute(attribute);
9467 }
9468 }
9469 decreaseListLevel() {
9470 let [startPosition] = Array.from(this.getSelectedRange());
9471 const {
9472 index
9473 } = this.document.locationFromPosition(startPosition);
9474 let endIndex = index;
9475 const attributeLevel = this.getBlock().getAttributeLevel();
9476 let block = this.document.getBlockAtIndex(endIndex + 1);
9477 while (block) {
9478 if (!block.isListItem() || block.getAttributeLevel() <= attributeLevel) {
9479 break;
9480 }
9481 endIndex++;
9482 block = this.document.getBlockAtIndex(endIndex + 1);
9483 }
9484 startPosition = this.document.positionFromLocation({
9485 index,
9486 offset: 0
9487 });
9488 const endPosition = this.document.positionFromLocation({
9489 index: endIndex,
9490 offset: 0
9491 });
9492 return this.setDocument(this.document.removeLastListAttributeAtRange([startPosition, endPosition]));
9493 }
9494 updateCurrentAttributes() {
9495 const selectedRange = this.getSelectedRange({
9496 ignoreLock: true
9497 });
9498 if (selectedRange) {
9499 const currentAttributes = this.document.getCommonAttributesAtRange(selectedRange);
9500 Array.from(getAllAttributeNames()).forEach(attributeName => {
9501 if (!currentAttributes[attributeName]) {
9502 if (!this.canSetCurrentAttribute(attributeName)) {
9503 currentAttributes[attributeName] = false;
9504 }
9505 }
9506 });
9507 if (!objectsAreEqual(currentAttributes, this.currentAttributes)) {
9508 this.currentAttributes = currentAttributes;
9509 return this.notifyDelegateOfCurrentAttributesChange();
9510 }
9511 }
9512 }
9513 getCurrentAttributes() {
9514 return extend.call({}, this.currentAttributes);
9515 }
9516 getCurrentTextAttributes() {
9517 const attributes = {};
9518 for (const key in this.currentAttributes) {
9519 const value = this.currentAttributes[key];
9520 if (value !== false) {
9521 if (getTextConfig(key)) {
9522 attributes[key] = value;
9523 }
9524 }
9525 }
9526 return attributes;
9527 }
9528
9529 // Selection freezing
9530
9531 freezeSelection() {
9532 return this.setCurrentAttribute("frozen", true);
9533 }
9534 thawSelection() {
9535 return this.removeCurrentAttribute("frozen");
9536 }
9537 hasFrozenSelection() {
9538 return this.hasCurrentAttribute("frozen");
9539 }
9540 setSelection(selectedRange) {
9541 var _this$delegate5;
9542 const locationRange = this.document.locationRangeFromRange(selectedRange);
9543 return (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 ? void 0 : _this$delegate5.compositionDidRequestChangingSelectionToLocationRange(locationRange);
9544 }
9545 getSelectedRange() {
9546 const locationRange = this.getLocationRange();
9547 if (locationRange) {
9548 return this.document.rangeFromLocationRange(locationRange);
9549 }
9550 }
9551 setSelectedRange(selectedRange) {
9552 const locationRange = this.document.locationRangeFromRange(selectedRange);
9553 return this.getSelectionManager().setLocationRange(locationRange);
9554 }
9555 getPosition() {
9556 const locationRange = this.getLocationRange();
9557 if (locationRange) {
9558 return this.document.positionFromLocation(locationRange[0]);
9559 }
9560 }
9561 getLocationRange(options) {
9562 if (this.targetLocationRange) {
9563 return this.targetLocationRange;
9564 } else {
9565 return this.getSelectionManager().getLocationRange(options) || normalizeRange({
9566 index: 0,
9567 offset: 0
9568 });
9569 }
9570 }
9571 withTargetLocationRange(locationRange, fn) {
9572 let result;
9573 this.targetLocationRange = locationRange;
9574 try {
9575 result = fn();
9576 } finally {
9577 this.targetLocationRange = null;
9578 }
9579 return result;
9580 }
9581 withTargetRange(range, fn) {
9582 const locationRange = this.document.locationRangeFromRange(range);
9583 return this.withTargetLocationRange(locationRange, fn);
9584 }
9585 withTargetDOMRange(domRange, fn) {
9586 const locationRange = this.createLocationRangeFromDOMRange(domRange, {
9587 strict: false
9588 });
9589 return this.withTargetLocationRange(locationRange, fn);
9590 }
9591 getExpandedRangeInDirection(direction) {
9592 let {
9593 length
9594 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9595 let [startPosition, endPosition] = Array.from(this.getSelectedRange());
9596 if (direction === "backward") {
9597 if (length) {
9598 startPosition -= length;
9599 } else {
9600 startPosition = this.translateUTF16PositionFromOffset(startPosition, -1);
9601 }
9602 } else {
9603 if (length) {
9604 endPosition += length;
9605 } else {
9606 endPosition = this.translateUTF16PositionFromOffset(endPosition, 1);
9607 }
9608 }
9609 return normalizeRange([startPosition, endPosition]);
9610 }
9611 shouldManageMovingCursorInDirection(direction) {
9612 if (this.editingAttachment) {
9613 return true;
9614 }
9615 const range = this.getExpandedRangeInDirection(direction);
9616 return this.getAttachmentAtRange(range) != null;
9617 }
9618 moveCursorInDirection(direction) {
9619 let canEditAttachment, range;
9620 if (this.editingAttachment) {
9621 range = this.document.getRangeOfAttachment(this.editingAttachment);
9622 } else {
9623 const selectedRange = this.getSelectedRange();
9624 range = this.getExpandedRangeInDirection(direction);
9625 canEditAttachment = !rangesAreEqual(selectedRange, range);
9626 }
9627 if (direction === "backward") {
9628 this.setSelectedRange(range[0]);
9629 } else {
9630 this.setSelectedRange(range[1]);
9631 }
9632 if (canEditAttachment) {
9633 const attachment = this.getAttachmentAtRange(range);
9634 if (attachment) {
9635 return this.editAttachment(attachment);
9636 }
9637 }
9638 }
9639 expandSelectionInDirection(direction) {
9640 let {
9641 length
9642 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9643 const range = this.getExpandedRangeInDirection(direction, {
9644 length
9645 });
9646 return this.setSelectedRange(range);
9647 }
9648 expandSelectionForEditing() {
9649 if (this.hasCurrentAttribute("href")) {
9650 return this.expandSelectionAroundCommonAttribute("href");
9651 }
9652 }
9653 expandSelectionAroundCommonAttribute(attributeName) {
9654 const position = this.getPosition();
9655 const range = this.document.getRangeOfCommonAttributeAtPosition(attributeName, position);
9656 return this.setSelectedRange(range);
9657 }
9658 selectionContainsAttachments() {
9659 var _this$getSelectedAtta;
9660 return ((_this$getSelectedAtta = this.getSelectedAttachments()) === null || _this$getSelectedAtta === void 0 ? void 0 : _this$getSelectedAtta.length) > 0;
9661 }
9662 selectionIsInCursorTarget() {
9663 return this.editingAttachment || this.positionIsCursorTarget(this.getPosition());
9664 }
9665 positionIsCursorTarget(position) {
9666 const location = this.document.locationFromPosition(position);
9667 if (location) {
9668 return this.locationIsCursorTarget(location);
9669 }
9670 }
9671 positionIsBlockBreak(position) {
9672 var _this$document$getPie;
9673 return (_this$document$getPie = this.document.getPieceAtPosition(position)) === null || _this$document$getPie === void 0 ? void 0 : _this$document$getPie.isBlockBreak();
9674 }
9675 getSelectedDocument() {
9676 const selectedRange = this.getSelectedRange();
9677 if (selectedRange) {
9678 return this.document.getDocumentAtRange(selectedRange);
9679 }
9680 }
9681 getSelectedAttachments() {
9682 var _this$getSelectedDocu;
9683 return (_this$getSelectedDocu = this.getSelectedDocument()) === null || _this$getSelectedDocu === void 0 ? void 0 : _this$getSelectedDocu.getAttachments();
9684 }
9685
9686 // Attachments
9687
9688 getAttachments() {
9689 return this.attachments.slice(0);
9690 }
9691 refreshAttachments() {
9692 const attachments = this.document.getAttachments();
9693 const {
9694 added,
9695 removed
9696 } = summarizeArrayChange(this.attachments, attachments);
9697 this.attachments = attachments;
9698 Array.from(removed).forEach(attachment => {
9699 var _this$delegate6, _this$delegate6$compo;
9700 attachment.delegate = null;
9701 (_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);
9702 });
9703 return (() => {
9704 const result = [];
9705 Array.from(added).forEach(attachment => {
9706 var _this$delegate7, _this$delegate7$compo;
9707 attachment.delegate = this;
9708 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));
9709 });
9710 return result;
9711 })();
9712 }
9713
9714 // Attachment delegate
9715
9716 attachmentDidChangeAttributes(attachment) {
9717 var _this$delegate8, _this$delegate8$compo;
9718 this.revision++;
9719 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);
9720 }
9721 attachmentDidChangePreviewURL(attachment) {
9722 var _this$delegate9, _this$delegate9$compo;
9723 this.revision++;
9724 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);
9725 }
9726
9727 // Attachment editing
9728
9729 editAttachment(attachment, options) {
9730 var _this$delegate10, _this$delegate10$comp;
9731 if (attachment === this.editingAttachment) return;
9732 this.stopEditingAttachment();
9733 this.editingAttachment = attachment;
9734 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);
9735 }
9736 stopEditingAttachment() {
9737 var _this$delegate11, _this$delegate11$comp;
9738 if (!this.editingAttachment) return;
9739 (_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);
9740 this.editingAttachment = null;
9741 }
9742 updateAttributesForAttachment(attributes, attachment) {
9743 return this.setDocument(this.document.updateAttributesForAttachment(attributes, attachment));
9744 }
9745 removeAttributeForAttachment(attribute, attachment) {
9746 return this.setDocument(this.document.removeAttributeForAttachment(attribute, attachment));
9747 }
9748
9749 // Private
9750
9751 breakFormattedBlock(insertion) {
9752 let {
9753 document
9754 } = insertion;
9755 const {
9756 block
9757 } = insertion;
9758 let position = insertion.startPosition;
9759 let range = [position - 1, position];
9760 if (block.getBlockBreakPosition() === insertion.startLocation.offset) {
9761 if (block.breaksOnReturn() && insertion.nextCharacter === "\n") {
9762 position += 1;
9763 } else {
9764 document = document.removeTextAtRange(range);
9765 }
9766 range = [position, position];
9767 } else if (insertion.nextCharacter === "\n") {
9768 if (insertion.previousCharacter === "\n") {
9769 range = [position - 1, position + 1];
9770 } else {
9771 range = [position, position + 1];
9772 position += 1;
9773 }
9774 } else if (insertion.startLocation.offset - 1 !== 0) {
9775 position += 1;
9776 }
9777 const newDocument = new Document([block.removeLastAttribute().copyWithoutText()]);
9778 this.setDocument(document.insertDocumentAtRange(newDocument, range));
9779 return this.setSelection(position);
9780 }
9781 getPreviousBlock() {
9782 const locationRange = this.getLocationRange();
9783 if (locationRange) {
9784 const {
9785 index
9786 } = locationRange[0];
9787 if (index > 0) {
9788 return this.document.getBlockAtIndex(index - 1);
9789 }
9790 }
9791 }
9792 getBlock() {
9793 const locationRange = this.getLocationRange();
9794 if (locationRange) {
9795 return this.document.getBlockAtIndex(locationRange[0].index);
9796 }
9797 }
9798 getAttachmentAtRange(range) {
9799 const document = this.document.getDocumentAtRange(range);
9800 if (document.toString() === "".concat(OBJECT_REPLACEMENT_CHARACTER, "\n")) {
9801 return document.getAttachments()[0];
9802 }
9803 }
9804 notifyDelegateOfCurrentAttributesChange() {
9805 var _this$delegate12, _this$delegate12$comp;
9806 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);
9807 }
9808 notifyDelegateOfInsertionAtRange(range) {
9809 var _this$delegate13, _this$delegate13$comp;
9810 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);
9811 }
9812 translateUTF16PositionFromOffset(position, offset) {
9813 const utf16string = this.document.toUTF16String();
9814 const utf16position = utf16string.offsetFromUCS2Offset(position);
9815 return utf16string.offsetToUCS2Offset(utf16position + offset);
9816 }
9817 }
9818 Composition.proxyMethod("getSelectionManager().getPointRange");
9819 Composition.proxyMethod("getSelectionManager().setLocationRangeFromPointRange");
9820 Composition.proxyMethod("getSelectionManager().createLocationRangeFromDOMRange");
9821 Composition.proxyMethod("getSelectionManager().locationIsCursorTarget");
9822 Composition.proxyMethod("getSelectionManager().selectionIsExpanded");
9823 Composition.proxyMethod("delegate?.getSelectionManager");
9824
9825 class UndoManager extends BasicObject {
9826 constructor(composition) {
9827 super(...arguments);
9828 this.composition = composition;
9829 this.undoEntries = [];
9830 this.redoEntries = [];
9831 }
9832 recordUndoEntry(description) {
9833 let {
9834 context,
9835 consolidatable
9836 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9837 const previousEntry = this.undoEntries.slice(-1)[0];
9838 if (!consolidatable || !entryHasDescriptionAndContext(previousEntry, description, context)) {
9839 const undoEntry = this.createEntry({
9840 description,
9841 context
9842 });
9843 this.undoEntries.push(undoEntry);
9844 this.redoEntries = [];
9845 }
9846 }
9847 undo() {
9848 const undoEntry = this.undoEntries.pop();
9849 if (undoEntry) {
9850 const redoEntry = this.createEntry(undoEntry);
9851 this.redoEntries.push(redoEntry);
9852 return this.composition.loadSnapshot(undoEntry.snapshot);
9853 }
9854 }
9855 redo() {
9856 const redoEntry = this.redoEntries.pop();
9857 if (redoEntry) {
9858 const undoEntry = this.createEntry(redoEntry);
9859 this.undoEntries.push(undoEntry);
9860 return this.composition.loadSnapshot(redoEntry.snapshot);
9861 }
9862 }
9863 canUndo() {
9864 return this.undoEntries.length > 0;
9865 }
9866 canRedo() {
9867 return this.redoEntries.length > 0;
9868 }
9869
9870 // Private
9871
9872 createEntry() {
9873 let {
9874 description,
9875 context
9876 } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
9877 return {
9878 description: description === null || description === void 0 ? void 0 : description.toString(),
9879 context: JSON.stringify(context),
9880 snapshot: this.composition.getSnapshot()
9881 };
9882 }
9883 }
9884 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);
9885
9886 const BLOCK_ATTRIBUTE_NAME = "attachmentGallery";
9887 const TEXT_ATTRIBUTE_NAME = "presentation";
9888 const TEXT_ATTRIBUTE_VALUE = "gallery";
9889 class Filter {
9890 constructor(snapshot) {
9891 this.document = snapshot.document;
9892 this.selectedRange = snapshot.selectedRange;
9893 }
9894 perform() {
9895 this.removeBlockAttribute();
9896 return this.applyBlockAttribute();
9897 }
9898 getSnapshot() {
9899 return {
9900 document: this.document,
9901 selectedRange: this.selectedRange
9902 };
9903 }
9904
9905 // Private
9906
9907 removeBlockAttribute() {
9908 return this.findRangesOfBlocks().map(range => this.document = this.document.removeAttributeAtRange(BLOCK_ATTRIBUTE_NAME, range));
9909 }
9910 applyBlockAttribute() {
9911 let offset = 0;
9912 this.findRangesOfPieces().forEach(range => {
9913 if (range[1] - range[0] > 1) {
9914 range[0] += offset;
9915 range[1] += offset;
9916 if (this.document.getCharacterAtPosition(range[1]) !== "\n") {
9917 this.document = this.document.insertBlockBreakAtRange(range[1]);
9918 if (range[1] < this.selectedRange[1]) {
9919 this.moveSelectedRangeForward();
9920 }
9921 range[1]++;
9922 offset++;
9923 }
9924 if (range[0] !== 0) {
9925 if (this.document.getCharacterAtPosition(range[0] - 1) !== "\n") {
9926 this.document = this.document.insertBlockBreakAtRange(range[0]);
9927 if (range[0] < this.selectedRange[0]) {
9928 this.moveSelectedRangeForward();
9929 }
9930 range[0]++;
9931 offset++;
9932 }
9933 }
9934 this.document = this.document.applyBlockAttributeAtRange(BLOCK_ATTRIBUTE_NAME, true, range);
9935 }
9936 });
9937 }
9938 findRangesOfBlocks() {
9939 return this.document.findRangesForBlockAttribute(BLOCK_ATTRIBUTE_NAME);
9940 }
9941 findRangesOfPieces() {
9942 return this.document.findRangesForTextAttribute(TEXT_ATTRIBUTE_NAME, {
9943 withValue: TEXT_ATTRIBUTE_VALUE
9944 });
9945 }
9946 moveSelectedRangeForward() {
9947 this.selectedRange[0] += 1;
9948 this.selectedRange[1] += 1;
9949 }
9950 }
9951
9952 const attachmentGalleryFilter = function (snapshot) {
9953 const filter = new Filter(snapshot);
9954 filter.perform();
9955 return filter.getSnapshot();
9956 };
9957
9958 const DEFAULT_FILTERS = [attachmentGalleryFilter];
9959 class Editor {
9960 constructor(composition, selectionManager, element) {
9961 this.insertFiles = this.insertFiles.bind(this);
9962 this.composition = composition;
9963 this.selectionManager = selectionManager;
9964 this.element = element;
9965 this.undoManager = new UndoManager(this.composition);
9966 this.filters = DEFAULT_FILTERS.slice(0);
9967 }
9968 loadDocument(document) {
9969 return this.loadSnapshot({
9970 document,
9971 selectedRange: [0, 0]
9972 });
9973 }
9974 loadHTML() {
9975 let html = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
9976 const document = HTMLParser.parse(html, {
9977 referenceElement: this.element
9978 }).getDocument();
9979 return this.loadDocument(document);
9980 }
9981 loadJSON(_ref) {
9982 let {
9983 document,
9984 selectedRange
9985 } = _ref;
9986 document = Document.fromJSON(document);
9987 return this.loadSnapshot({
9988 document,
9989 selectedRange
9990 });
9991 }
9992 loadSnapshot(snapshot) {
9993 this.undoManager = new UndoManager(this.composition);
9994 return this.composition.loadSnapshot(snapshot);
9995 }
9996 getDocument() {
9997 return this.composition.document;
9998 }
9999 getSelectedDocument() {
10000 return this.composition.getSelectedDocument();
10001 }
10002 getSnapshot() {
10003 return this.composition.getSnapshot();
10004 }
10005 toJSON() {
10006 return this.getSnapshot();
10007 }
10008
10009 // Document manipulation
10010
10011 deleteInDirection(direction) {
10012 return this.composition.deleteInDirection(direction);
10013 }
10014 insertAttachment(attachment) {
10015 return this.composition.insertAttachment(attachment);
10016 }
10017 insertAttachments(attachments) {
10018 return this.composition.insertAttachments(attachments);
10019 }
10020 insertDocument(document) {
10021 return this.composition.insertDocument(document);
10022 }
10023 insertFile(file) {
10024 return this.composition.insertFile(file);
10025 }
10026 insertFiles(files) {
10027 return this.composition.insertFiles(files);
10028 }
10029 insertHTML(html) {
10030 return this.composition.insertHTML(html);
10031 }
10032 insertString(string) {
10033 return this.composition.insertString(string);
10034 }
10035 insertText(text) {
10036 return this.composition.insertText(text);
10037 }
10038 insertLineBreak() {
10039 return this.composition.insertLineBreak();
10040 }
10041
10042 // Selection
10043
10044 getSelectedRange() {
10045 return this.composition.getSelectedRange();
10046 }
10047 getPosition() {
10048 return this.composition.getPosition();
10049 }
10050 getClientRectAtPosition(position) {
10051 const locationRange = this.getDocument().locationRangeFromRange([position, position + 1]);
10052 return this.selectionManager.getClientRectAtLocationRange(locationRange);
10053 }
10054 expandSelectionInDirection(direction) {
10055 return this.composition.expandSelectionInDirection(direction);
10056 }
10057 moveCursorInDirection(direction) {
10058 return this.composition.moveCursorInDirection(direction);
10059 }
10060 setSelectedRange(selectedRange) {
10061 return this.composition.setSelectedRange(selectedRange);
10062 }
10063
10064 // Attributes
10065
10066 activateAttribute(name) {
10067 let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
10068 return this.composition.setCurrentAttribute(name, value);
10069 }
10070 attributeIsActive(name) {
10071 return this.composition.hasCurrentAttribute(name);
10072 }
10073 canActivateAttribute(name) {
10074 return this.composition.canSetCurrentAttribute(name);
10075 }
10076 deactivateAttribute(name) {
10077 return this.composition.removeCurrentAttribute(name);
10078 }
10079
10080 // HTML attributes
10081 setHTMLAtributeAtPosition(position, name, value) {
10082 this.composition.setHTMLAtributeAtPosition(position, name, value);
10083 }
10084
10085 // Nesting level
10086
10087 canDecreaseNestingLevel() {
10088 return this.composition.canDecreaseNestingLevel();
10089 }
10090 canIncreaseNestingLevel() {
10091 return this.composition.canIncreaseNestingLevel();
10092 }
10093 decreaseNestingLevel() {
10094 if (this.canDecreaseNestingLevel()) {
10095 return this.composition.decreaseNestingLevel();
10096 }
10097 }
10098 increaseNestingLevel() {
10099 if (this.canIncreaseNestingLevel()) {
10100 return this.composition.increaseNestingLevel();
10101 }
10102 }
10103
10104 // Undo/redo
10105
10106 canRedo() {
10107 return this.undoManager.canRedo();
10108 }
10109 canUndo() {
10110 return this.undoManager.canUndo();
10111 }
10112 recordUndoEntry(description) {
10113 let {
10114 context,
10115 consolidatable
10116 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
10117 return this.undoManager.recordUndoEntry(description, {
10118 context,
10119 consolidatable
10120 });
10121 }
10122 redo() {
10123 if (this.canRedo()) {
10124 return this.undoManager.redo();
10125 }
10126 }
10127 undo() {
10128 if (this.canUndo()) {
10129 return this.undoManager.undo();
10130 }
10131 }
10132 }
10133
10134 /* eslint-disable
10135 no-var,
10136 prefer-const,
10137 */
10138 class LocationMapper {
10139 constructor(element) {
10140 this.element = element;
10141 }
10142 findLocationFromContainerAndOffset(container, offset) {
10143 let {
10144 strict
10145 } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
10146 strict: true
10147 };
10148 let childIndex = 0;
10149 let foundBlock = false;
10150 const location = {
10151 index: 0,
10152 offset: 0
10153 };
10154 const attachmentElement = this.findAttachmentElementParentForNode(container);
10155 if (attachmentElement) {
10156 container = attachmentElement.parentNode;
10157 offset = findChildIndexOfNode(attachmentElement);
10158 }
10159 const walker = walkTree(this.element, {
10160 usingFilter: rejectAttachmentContents
10161 });
10162 while (walker.nextNode()) {
10163 const node = walker.currentNode;
10164 if (node === container && nodeIsTextNode(container)) {
10165 if (!nodeIsCursorTarget(node)) {
10166 location.offset += offset;
10167 }
10168 break;
10169 } else {
10170 if (node.parentNode === container) {
10171 if (childIndex++ === offset) {
10172 if (!strict && nodeIsBlockStart(node, {
10173 strict
10174 })) {
10175 if (foundBlock) {
10176 location.index++;
10177 }
10178 location.offset = 0;
10179 foundBlock = true;
10180 }
10181 break;
10182 }
10183 } else if (!elementContainsNode(container, node)) {
10184 if (childIndex > 0) {
10185 break;
10186 }
10187 }
10188 if (nodeIsBlockStart(node, {
10189 strict
10190 })) {
10191 if (foundBlock) {
10192 location.index++;
10193 }
10194 location.offset = 0;
10195 foundBlock = true;
10196 } else {
10197 location.offset += nodeLength(node);
10198 }
10199 }
10200 }
10201 return location;
10202 }
10203 findContainerAndOffsetFromLocation(location) {
10204 let container, offset;
10205 if (location.index === 0 && location.offset === 0) {
10206 container = this.element;
10207 offset = 0;
10208 while (container.firstChild) {
10209 container = container.firstChild;
10210 if (nodeIsBlockContainer(container)) {
10211 offset = 1;
10212 break;
10213 }
10214 }
10215 return [container, offset];
10216 }
10217 let [node, nodeOffset] = this.findNodeAndOffsetFromLocation(location);
10218 if (!node) return;
10219 if (nodeIsTextNode(node)) {
10220 if (nodeLength(node) === 0) {
10221 container = node.parentNode.parentNode;
10222 offset = findChildIndexOfNode(node.parentNode);
10223 if (nodeIsCursorTarget(node, {
10224 name: "right"
10225 })) {
10226 offset++;
10227 }
10228 } else {
10229 container = node;
10230 offset = location.offset - nodeOffset;
10231 }
10232 } else {
10233 container = node.parentNode;
10234 if (!nodeIsBlockStart(node.previousSibling)) {
10235 if (!nodeIsBlockContainer(container)) {
10236 while (node === container.lastChild) {
10237 node = container;
10238 container = container.parentNode;
10239 if (nodeIsBlockContainer(container)) {
10240 break;
10241 }
10242 }
10243 }
10244 }
10245 offset = findChildIndexOfNode(node);
10246 if (location.offset !== 0) {
10247 offset++;
10248 }
10249 }
10250 return [container, offset];
10251 }
10252 findNodeAndOffsetFromLocation(location) {
10253 let node, nodeOffset;
10254 let offset = 0;
10255 for (const currentNode of this.getSignificantNodesForIndex(location.index)) {
10256 const length = nodeLength(currentNode);
10257 if (location.offset <= offset + length) {
10258 if (nodeIsTextNode(currentNode)) {
10259 node = currentNode;
10260 nodeOffset = offset;
10261 if (location.offset === nodeOffset && nodeIsCursorTarget(node)) {
10262 break;
10263 }
10264 } else if (!node) {
10265 node = currentNode;
10266 nodeOffset = offset;
10267 }
10268 }
10269 offset += length;
10270 if (offset > location.offset) {
10271 break;
10272 }
10273 }
10274 return [node, nodeOffset];
10275 }
10276
10277 // Private
10278
10279 findAttachmentElementParentForNode(node) {
10280 while (node && node !== this.element) {
10281 if (nodeIsAttachmentElement(node)) {
10282 return node;
10283 }
10284 node = node.parentNode;
10285 }
10286 }
10287 getSignificantNodesForIndex(index) {
10288 const nodes = [];
10289 const walker = walkTree(this.element, {
10290 usingFilter: acceptSignificantNodes
10291 });
10292 let recordingNodes = false;
10293 while (walker.nextNode()) {
10294 const node = walker.currentNode;
10295 if (nodeIsBlockStartComment(node)) {
10296 var blockIndex;
10297 if (blockIndex != null) {
10298 blockIndex++;
10299 } else {
10300 blockIndex = 0;
10301 }
10302 if (blockIndex === index) {
10303 recordingNodes = true;
10304 } else if (recordingNodes) {
10305 break;
10306 }
10307 } else if (recordingNodes) {
10308 nodes.push(node);
10309 }
10310 }
10311 return nodes;
10312 }
10313 }
10314 const nodeLength = function (node) {
10315 if (node.nodeType === Node.TEXT_NODE) {
10316 if (nodeIsCursorTarget(node)) {
10317 return 0;
10318 } else {
10319 const string = node.textContent;
10320 return string.length;
10321 }
10322 } else if (tagName(node) === "br" || nodeIsAttachmentElement(node)) {
10323 return 1;
10324 } else {
10325 return 0;
10326 }
10327 };
10328 const acceptSignificantNodes = function (node) {
10329 if (rejectEmptyTextNodes(node) === NodeFilter.FILTER_ACCEPT) {
10330 return rejectAttachmentContents(node);
10331 } else {
10332 return NodeFilter.FILTER_REJECT;
10333 }
10334 };
10335 const rejectEmptyTextNodes = function (node) {
10336 if (nodeIsEmptyTextNode(node)) {
10337 return NodeFilter.FILTER_REJECT;
10338 } else {
10339 return NodeFilter.FILTER_ACCEPT;
10340 }
10341 };
10342 const rejectAttachmentContents = function (node) {
10343 if (nodeIsAttachmentElement(node.parentNode)) {
10344 return NodeFilter.FILTER_REJECT;
10345 } else {
10346 return NodeFilter.FILTER_ACCEPT;
10347 }
10348 };
10349
10350 /* eslint-disable
10351 id-length,
10352 no-empty,
10353 */
10354 class PointMapper {
10355 createDOMRangeFromPoint(_ref) {
10356 let {
10357 x,
10358 y
10359 } = _ref;
10360 let domRange;
10361 if (document.caretPositionFromPoint) {
10362 const {
10363 offsetNode,
10364 offset
10365 } = document.caretPositionFromPoint(x, y);
10366 domRange = document.createRange();
10367 domRange.setStart(offsetNode, offset);
10368 return domRange;
10369 } else if (document.caretRangeFromPoint) {
10370 return document.caretRangeFromPoint(x, y);
10371 } else if (document.body.createTextRange) {
10372 const originalDOMRange = getDOMRange();
10373 try {
10374 // IE 11 throws "Unspecified error" when using moveToPoint
10375 // during a drag-and-drop operation.
10376 const textRange = document.body.createTextRange();
10377 textRange.moveToPoint(x, y);
10378 textRange.select();
10379 } catch (error) {}
10380 domRange = getDOMRange();
10381 setDOMRange(originalDOMRange);
10382 return domRange;
10383 }
10384 }
10385 getClientRectsForDOMRange(domRange) {
10386 const array = Array.from(domRange.getClientRects());
10387 const start = array[0];
10388 const end = array[array.length - 1];
10389 return [start, end];
10390 }
10391 }
10392
10393 /* eslint-disable
10394 */
10395 class SelectionManager extends BasicObject {
10396 constructor(element) {
10397 super(...arguments);
10398 this.didMouseDown = this.didMouseDown.bind(this);
10399 this.selectionDidChange = this.selectionDidChange.bind(this);
10400 this.element = element;
10401 this.locationMapper = new LocationMapper(this.element);
10402 this.pointMapper = new PointMapper();
10403 this.lockCount = 0;
10404 handleEvent("mousedown", {
10405 onElement: this.element,
10406 withCallback: this.didMouseDown
10407 });
10408 }
10409 getLocationRange() {
10410 let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
10411 if (options.strict === false) {
10412 return this.createLocationRangeFromDOMRange(getDOMRange());
10413 } else if (options.ignoreLock) {
10414 return this.currentLocationRange;
10415 } else if (this.lockedLocationRange) {
10416 return this.lockedLocationRange;
10417 } else {
10418 return this.currentLocationRange;
10419 }
10420 }
10421 setLocationRange(locationRange) {
10422 if (this.lockedLocationRange) return;
10423 locationRange = normalizeRange(locationRange);
10424 const domRange = this.createDOMRangeFromLocationRange(locationRange);
10425 if (domRange) {
10426 setDOMRange(domRange);
10427 this.updateCurrentLocationRange(locationRange);
10428 }
10429 }
10430 setLocationRangeFromPointRange(pointRange) {
10431 pointRange = normalizeRange(pointRange);
10432 const startLocation = this.getLocationAtPoint(pointRange[0]);
10433 const endLocation = this.getLocationAtPoint(pointRange[1]);
10434 this.setLocationRange([startLocation, endLocation]);
10435 }
10436 getClientRectAtLocationRange(locationRange) {
10437 const domRange = this.createDOMRangeFromLocationRange(locationRange);
10438 if (domRange) {
10439 return this.getClientRectsForDOMRange(domRange)[1];
10440 }
10441 }
10442 locationIsCursorTarget(location) {
10443 const node = Array.from(this.findNodeAndOffsetFromLocation(location))[0];
10444 return nodeIsCursorTarget(node);
10445 }
10446 lock() {
10447 if (this.lockCount++ === 0) {
10448 this.updateCurrentLocationRange();
10449 this.lockedLocationRange = this.getLocationRange();
10450 }
10451 }
10452 unlock() {
10453 if (--this.lockCount === 0) {
10454 const {
10455 lockedLocationRange
10456 } = this;
10457 this.lockedLocationRange = null;
10458 if (lockedLocationRange != null) {
10459 return this.setLocationRange(lockedLocationRange);
10460 }
10461 }
10462 }
10463 clearSelection() {
10464 var _getDOMSelection;
10465 return (_getDOMSelection = getDOMSelection()) === null || _getDOMSelection === void 0 ? void 0 : _getDOMSelection.removeAllRanges();
10466 }
10467 selectionIsCollapsed() {
10468 var _getDOMRange;
10469 return ((_getDOMRange = getDOMRange()) === null || _getDOMRange === void 0 ? void 0 : _getDOMRange.collapsed) === true;
10470 }
10471 selectionIsExpanded() {
10472 return !this.selectionIsCollapsed();
10473 }
10474 createLocationRangeFromDOMRange(domRange, options) {
10475 if (domRange == null || !this.domRangeWithinElement(domRange)) return;
10476 const start = this.findLocationFromContainerAndOffset(domRange.startContainer, domRange.startOffset, options);
10477 if (!start) return;
10478 const end = domRange.collapsed ? undefined : this.findLocationFromContainerAndOffset(domRange.endContainer, domRange.endOffset, options);
10479 return normalizeRange([start, end]);
10480 }
10481 didMouseDown() {
10482 return this.pauseTemporarily();
10483 }
10484 pauseTemporarily() {
10485 let resumeHandlers;
10486 this.paused = true;
10487 const resume = () => {
10488 this.paused = false;
10489 clearTimeout(resumeTimeout);
10490 Array.from(resumeHandlers).forEach(handler => {
10491 handler.destroy();
10492 });
10493 if (elementContainsNode(document, this.element)) {
10494 return this.selectionDidChange();
10495 }
10496 };
10497 const resumeTimeout = setTimeout(resume, 200);
10498 resumeHandlers = ["mousemove", "keydown"].map(eventName => handleEvent(eventName, {
10499 onElement: document,
10500 withCallback: resume
10501 }));
10502 }
10503 selectionDidChange() {
10504 if (!this.paused && !innerElementIsActive(this.element)) {
10505 return this.updateCurrentLocationRange();
10506 }
10507 }
10508 updateCurrentLocationRange(locationRange) {
10509 if (locationRange != null ? locationRange : locationRange = this.createLocationRangeFromDOMRange(getDOMRange())) {
10510 if (!rangesAreEqual(locationRange, this.currentLocationRange)) {
10511 var _this$delegate, _this$delegate$locati;
10512 this.currentLocationRange = locationRange;
10513 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));
10514 }
10515 }
10516 }
10517 createDOMRangeFromLocationRange(locationRange) {
10518 const rangeStart = this.findContainerAndOffsetFromLocation(locationRange[0]);
10519 const rangeEnd = rangeIsCollapsed(locationRange) ? rangeStart : this.findContainerAndOffsetFromLocation(locationRange[1]) || rangeStart;
10520 if (rangeStart != null && rangeEnd != null) {
10521 const domRange = document.createRange();
10522 domRange.setStart(...Array.from(rangeStart || []));
10523 domRange.setEnd(...Array.from(rangeEnd || []));
10524 return domRange;
10525 }
10526 }
10527 getLocationAtPoint(point) {
10528 const domRange = this.createDOMRangeFromPoint(point);
10529 if (domRange) {
10530 var _this$createLocationR;
10531 return (_this$createLocationR = this.createLocationRangeFromDOMRange(domRange)) === null || _this$createLocationR === void 0 ? void 0 : _this$createLocationR[0];
10532 }
10533 }
10534 domRangeWithinElement(domRange) {
10535 if (domRange.collapsed) {
10536 return elementContainsNode(this.element, domRange.startContainer);
10537 } else {
10538 return elementContainsNode(this.element, domRange.startContainer) && elementContainsNode(this.element, domRange.endContainer);
10539 }
10540 }
10541 }
10542 SelectionManager.proxyMethod("locationMapper.findLocationFromContainerAndOffset");
10543 SelectionManager.proxyMethod("locationMapper.findContainerAndOffsetFromLocation");
10544 SelectionManager.proxyMethod("locationMapper.findNodeAndOffsetFromLocation");
10545 SelectionManager.proxyMethod("pointMapper.createDOMRangeFromPoint");
10546 SelectionManager.proxyMethod("pointMapper.getClientRectsForDOMRange");
10547
10548 var models = /*#__PURE__*/Object.freeze({
10549 __proto__: null,
10550 Attachment: Attachment,
10551 AttachmentManager: AttachmentManager,
10552 AttachmentPiece: AttachmentPiece,
10553 Block: Block,
10554 Composition: Composition,
10555 Document: Document,
10556 Editor: Editor,
10557 HTMLParser: HTMLParser,
10558 HTMLSanitizer: HTMLSanitizer,
10559 LineBreakInsertion: LineBreakInsertion,
10560 LocationMapper: LocationMapper,
10561 ManagedAttachment: ManagedAttachment,
10562 Piece: Piece,
10563 PointMapper: PointMapper,
10564 SelectionManager: SelectionManager,
10565 SplittableList: SplittableList,
10566 StringPiece: StringPiece,
10567 Text: Text,
10568 UndoManager: UndoManager
10569 });
10570
10571 var views = /*#__PURE__*/Object.freeze({
10572 __proto__: null,
10573 ObjectView: ObjectView,
10574 AttachmentView: AttachmentView,
10575 BlockView: BlockView,
10576 DocumentView: DocumentView,
10577 PieceView: PieceView,
10578 PreviewableAttachmentView: PreviewableAttachmentView,
10579 TextView: TextView
10580 });
10581
10582 const {
10583 lang,
10584 css,
10585 keyNames: keyNames$1
10586 } = config;
10587 const undoable = function (fn) {
10588 return function () {
10589 const commands = fn.apply(this, arguments);
10590 commands.do();
10591 if (!this.undos) {
10592 this.undos = [];
10593 }
10594 this.undos.push(commands.undo);
10595 };
10596 };
10597 class AttachmentEditorController extends BasicObject {
10598 constructor(attachmentPiece, _element, container) {
10599 let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
10600 super(...arguments);
10601 // Installing and uninstalling
10602 _defineProperty(this, "makeElementMutable", undoable(() => {
10603 return {
10604 do: () => {
10605 this.element.dataset.trixMutable = true;
10606 },
10607 undo: () => delete this.element.dataset.trixMutable
10608 };
10609 }));
10610 _defineProperty(this, "addToolbar", undoable(() => {
10611 // <div class="#{css.attachmentMetadataContainer}" data-trix-mutable="true">
10612 // <div class="trix-button-row">
10613 // <span class="trix-button-group trix-button-group--actions">
10614 // <button type="button" class="trix-button trix-button--remove" title="#{lang.remove}" data-trix-action="remove">#{lang.remove}</button>
10615 // </span>
10616 // </div>
10617 // </div>
10618 const element = makeElement({
10619 tagName: "div",
10620 className: css.attachmentToolbar,
10621 data: {
10622 trixMutable: true
10623 },
10624 childNodes: makeElement({
10625 tagName: "div",
10626 className: "trix-button-row",
10627 childNodes: makeElement({
10628 tagName: "span",
10629 className: "trix-button-group trix-button-group--actions",
10630 childNodes: makeElement({
10631 tagName: "button",
10632 className: "trix-button trix-button--remove",
10633 textContent: lang.remove,
10634 attributes: {
10635 title: lang.remove
10636 },
10637 data: {
10638 trixAction: "remove"
10639 }
10640 })
10641 })
10642 })
10643 });
10644 if (this.attachment.isPreviewable()) {
10645 // <div class="#{css.attachmentMetadataContainer}">
10646 // <span class="#{css.attachmentMetadata}">
10647 // <span class="#{css.attachmentName}" title="#{name}">#{name}</span>
10648 // <span class="#{css.attachmentSize}">#{size}</span>
10649 // </span>
10650 // </div>
10651 element.appendChild(makeElement({
10652 tagName: "div",
10653 className: css.attachmentMetadataContainer,
10654 childNodes: makeElement({
10655 tagName: "span",
10656 className: css.attachmentMetadata,
10657 childNodes: [makeElement({
10658 tagName: "span",
10659 className: css.attachmentName,
10660 textContent: this.attachment.getFilename(),
10661 attributes: {
10662 title: this.attachment.getFilename()
10663 }
10664 }), makeElement({
10665 tagName: "span",
10666 className: css.attachmentSize,
10667 textContent: this.attachment.getFormattedFilesize()
10668 })]
10669 })
10670 }));
10671 }
10672 handleEvent("click", {
10673 onElement: element,
10674 withCallback: this.didClickToolbar
10675 });
10676 handleEvent("click", {
10677 onElement: element,
10678 matchingSelector: "[data-trix-action]",
10679 withCallback: this.didClickActionButton
10680 });
10681 triggerEvent("trix-attachment-before-toolbar", {
10682 onElement: this.element,
10683 attributes: {
10684 toolbar: element,
10685 attachment: this.attachment
10686 }
10687 });
10688 return {
10689 do: () => this.element.appendChild(element),
10690 undo: () => removeNode(element)
10691 };
10692 }));
10693 _defineProperty(this, "installCaptionEditor", undoable(() => {
10694 const textarea = makeElement({
10695 tagName: "textarea",
10696 className: css.attachmentCaptionEditor,
10697 attributes: {
10698 placeholder: lang.captionPlaceholder
10699 },
10700 data: {
10701 trixMutable: true
10702 }
10703 });
10704 textarea.value = this.attachmentPiece.getCaption();
10705 const textareaClone = textarea.cloneNode();
10706 textareaClone.classList.add("trix-autoresize-clone");
10707 textareaClone.tabIndex = -1;
10708 const autoresize = function () {
10709 textareaClone.value = textarea.value;
10710 textarea.style.height = textareaClone.scrollHeight + "px";
10711 };
10712 handleEvent("input", {
10713 onElement: textarea,
10714 withCallback: autoresize
10715 });
10716 handleEvent("input", {
10717 onElement: textarea,
10718 withCallback: this.didInputCaption
10719 });
10720 handleEvent("keydown", {
10721 onElement: textarea,
10722 withCallback: this.didKeyDownCaption
10723 });
10724 handleEvent("change", {
10725 onElement: textarea,
10726 withCallback: this.didChangeCaption
10727 });
10728 handleEvent("blur", {
10729 onElement: textarea,
10730 withCallback: this.didBlurCaption
10731 });
10732 const figcaption = this.element.querySelector("figcaption");
10733 const editingFigcaption = figcaption.cloneNode();
10734 return {
10735 do: () => {
10736 figcaption.style.display = "none";
10737 editingFigcaption.appendChild(textarea);
10738 editingFigcaption.appendChild(textareaClone);
10739 editingFigcaption.classList.add("".concat(css.attachmentCaption, "--editing"));
10740 figcaption.parentElement.insertBefore(editingFigcaption, figcaption);
10741 autoresize();
10742 if (this.options.editCaption) {
10743 return defer(() => textarea.focus());
10744 }
10745 },
10746 undo() {
10747 removeNode(editingFigcaption);
10748 figcaption.style.display = null;
10749 }
10750 };
10751 }));
10752 this.didClickToolbar = this.didClickToolbar.bind(this);
10753 this.didClickActionButton = this.didClickActionButton.bind(this);
10754 this.didKeyDownCaption = this.didKeyDownCaption.bind(this);
10755 this.didInputCaption = this.didInputCaption.bind(this);
10756 this.didChangeCaption = this.didChangeCaption.bind(this);
10757 this.didBlurCaption = this.didBlurCaption.bind(this);
10758 this.attachmentPiece = attachmentPiece;
10759 this.element = _element;
10760 this.container = container;
10761 this.options = options;
10762 this.attachment = this.attachmentPiece.attachment;
10763 if (tagName(this.element) === "a") {
10764 this.element = this.element.firstChild;
10765 }
10766 this.install();
10767 }
10768 install() {
10769 this.makeElementMutable();
10770 this.addToolbar();
10771 if (this.attachment.isPreviewable()) {
10772 this.installCaptionEditor();
10773 }
10774 }
10775 uninstall() {
10776 var _this$delegate;
10777 let undo = this.undos.pop();
10778 this.savePendingCaption();
10779 while (undo) {
10780 undo();
10781 undo = this.undos.pop();
10782 }
10783 (_this$delegate = this.delegate) === null || _this$delegate === void 0 || _this$delegate.didUninstallAttachmentEditor(this);
10784 }
10785
10786 // Private
10787
10788 savePendingCaption() {
10789 if (this.pendingCaption != null) {
10790 const caption = this.pendingCaption;
10791 this.pendingCaption = null;
10792 if (caption) {
10793 var _this$delegate2, _this$delegate2$attac;
10794 (_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, {
10795 caption
10796 }, this.attachment);
10797 } else {
10798 var _this$delegate3, _this$delegate3$attac;
10799 (_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);
10800 }
10801 }
10802 }
10803 // Event handlers
10804
10805 didClickToolbar(event) {
10806 event.preventDefault();
10807 return event.stopPropagation();
10808 }
10809 didClickActionButton(event) {
10810 var _this$delegate4;
10811 const action = event.target.getAttribute("data-trix-action");
10812 switch (action) {
10813 case "remove":
10814 return (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 ? void 0 : _this$delegate4.attachmentEditorDidRequestRemovalOfAttachment(this.attachment);
10815 }
10816 }
10817 didKeyDownCaption(event) {
10818 if (keyNames$1[event.keyCode] === "return") {
10819 var _this$delegate5, _this$delegate5$attac;
10820 event.preventDefault();
10821 this.savePendingCaption();
10822 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);
10823 }
10824 }
10825 didInputCaption(event) {
10826 this.pendingCaption = event.target.value.replace(/\s/g, " ").trim();
10827 }
10828 didChangeCaption(event) {
10829 return this.savePendingCaption();
10830 }
10831 didBlurCaption(event) {
10832 return this.savePendingCaption();
10833 }
10834 }
10835
10836 class CompositionController extends BasicObject {
10837 constructor(element, composition) {
10838 super(...arguments);
10839 this.didFocus = this.didFocus.bind(this);
10840 this.didBlur = this.didBlur.bind(this);
10841 this.didClickAttachment = this.didClickAttachment.bind(this);
10842 this.element = element;
10843 this.composition = composition;
10844 this.documentView = new DocumentView(this.composition.document, {
10845 element: this.element
10846 });
10847 handleEvent("focus", {
10848 onElement: this.element,
10849 withCallback: this.didFocus
10850 });
10851 handleEvent("blur", {
10852 onElement: this.element,
10853 withCallback: this.didBlur
10854 });
10855 handleEvent("click", {
10856 onElement: this.element,
10857 matchingSelector: "a[contenteditable=false]",
10858 preventDefault: true
10859 });
10860 handleEvent("mousedown", {
10861 onElement: this.element,
10862 matchingSelector: attachmentSelector,
10863 withCallback: this.didClickAttachment
10864 });
10865 handleEvent("click", {
10866 onElement: this.element,
10867 matchingSelector: "a".concat(attachmentSelector),
10868 preventDefault: true
10869 });
10870 }
10871 didFocus(event) {
10872 var _this$blurPromise;
10873 const perform = () => {
10874 if (!this.focused) {
10875 var _this$delegate, _this$delegate$compos;
10876 this.focused = true;
10877 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);
10878 }
10879 };
10880 return ((_this$blurPromise = this.blurPromise) === null || _this$blurPromise === void 0 ? void 0 : _this$blurPromise.then(perform)) || perform();
10881 }
10882 didBlur(event) {
10883 this.blurPromise = new Promise(resolve => {
10884 return defer(() => {
10885 if (!innerElementIsActive(this.element)) {
10886 var _this$delegate2, _this$delegate2$compo;
10887 this.focused = null;
10888 (_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);
10889 }
10890 this.blurPromise = null;
10891 return resolve();
10892 });
10893 });
10894 }
10895 didClickAttachment(event, target) {
10896 var _this$delegate3, _this$delegate3$compo;
10897 const attachment = this.findAttachmentForElement(target);
10898 const editCaption = !!findClosestElementFromNode(event.target, {
10899 matchingSelector: "figcaption"
10900 });
10901 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, {
10902 editCaption
10903 });
10904 }
10905 getSerializableElement() {
10906 if (this.isEditingAttachment()) {
10907 return this.documentView.shadowElement;
10908 } else {
10909 return this.element;
10910 }
10911 }
10912 render() {
10913 var _this$delegate6, _this$delegate6$compo;
10914 if (this.revision !== this.composition.revision) {
10915 this.documentView.setDocument(this.composition.document);
10916 this.documentView.render();
10917 this.revision = this.composition.revision;
10918 }
10919 if (this.canSyncDocumentView() && !this.documentView.isSynced()) {
10920 var _this$delegate4, _this$delegate4$compo, _this$delegate5, _this$delegate5$compo;
10921 (_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);
10922 this.documentView.sync();
10923 (_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);
10924 }
10925 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);
10926 }
10927 rerenderViewForObject(object) {
10928 this.invalidateViewForObject(object);
10929 return this.render();
10930 }
10931 invalidateViewForObject(object) {
10932 return this.documentView.invalidateViewForObject(object);
10933 }
10934 isViewCachingEnabled() {
10935 return this.documentView.isViewCachingEnabled();
10936 }
10937 enableViewCaching() {
10938 return this.documentView.enableViewCaching();
10939 }
10940 disableViewCaching() {
10941 return this.documentView.disableViewCaching();
10942 }
10943 refreshViewCache() {
10944 return this.documentView.garbageCollectCachedViews();
10945 }
10946
10947 // Attachment editor management
10948
10949 isEditingAttachment() {
10950 return !!this.attachmentEditor;
10951 }
10952 installAttachmentEditorForAttachment(attachment, options) {
10953 var _this$attachmentEdito;
10954 if (((_this$attachmentEdito = this.attachmentEditor) === null || _this$attachmentEdito === void 0 ? void 0 : _this$attachmentEdito.attachment) === attachment) return;
10955 const element = this.documentView.findElementForObject(attachment);
10956 if (!element) return;
10957 this.uninstallAttachmentEditor();
10958 const attachmentPiece = this.composition.document.getAttachmentPieceForAttachment(attachment);
10959 this.attachmentEditor = new AttachmentEditorController(attachmentPiece, element, this.element, options);
10960 this.attachmentEditor.delegate = this;
10961 }
10962 uninstallAttachmentEditor() {
10963 var _this$attachmentEdito2;
10964 return (_this$attachmentEdito2 = this.attachmentEditor) === null || _this$attachmentEdito2 === void 0 ? void 0 : _this$attachmentEdito2.uninstall();
10965 }
10966
10967 // Attachment controller delegate
10968
10969 didUninstallAttachmentEditor() {
10970 this.attachmentEditor = null;
10971 return this.render();
10972 }
10973 attachmentEditorDidRequestUpdatingAttributesForAttachment(attributes, attachment) {
10974 var _this$delegate7, _this$delegate7$compo;
10975 (_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);
10976 return this.composition.updateAttributesForAttachment(attributes, attachment);
10977 }
10978 attachmentEditorDidRequestRemovingAttributeForAttachment(attribute, attachment) {
10979 var _this$delegate8, _this$delegate8$compo;
10980 (_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);
10981 return this.composition.removeAttributeForAttachment(attribute, attachment);
10982 }
10983 attachmentEditorDidRequestRemovalOfAttachment(attachment) {
10984 var _this$delegate9, _this$delegate9$compo;
10985 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);
10986 }
10987 attachmentEditorDidRequestDeselectingAttachment(attachment) {
10988 var _this$delegate10, _this$delegate10$comp;
10989 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);
10990 }
10991
10992 // Private
10993
10994 canSyncDocumentView() {
10995 return !this.isEditingAttachment();
10996 }
10997 findAttachmentForElement(element) {
10998 return this.composition.document.getAttachmentById(parseInt(element.dataset.trixId, 10));
10999 }
11000 }
11001
11002 class Controller extends BasicObject {}
11003
11004 const mutableAttributeName = "data-trix-mutable";
11005 const mutableSelector = "[".concat(mutableAttributeName, "]");
11006 const options = {
11007 attributes: true,
11008 childList: true,
11009 characterData: true,
11010 characterDataOldValue: true,
11011 subtree: true
11012 };
11013 class MutationObserver extends BasicObject {
11014 constructor(element) {
11015 super(element);
11016 this.didMutate = this.didMutate.bind(this);
11017 this.element = element;
11018 this.observer = new window.MutationObserver(this.didMutate);
11019 this.start();
11020 }
11021 start() {
11022 this.reset();
11023 return this.observer.observe(this.element, options);
11024 }
11025 stop() {
11026 return this.observer.disconnect();
11027 }
11028 didMutate(mutations) {
11029 this.mutations.push(...Array.from(this.findSignificantMutations(mutations) || []));
11030 if (this.mutations.length) {
11031 var _this$delegate, _this$delegate$elemen;
11032 (_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());
11033 return this.reset();
11034 }
11035 }
11036
11037 // Private
11038
11039 reset() {
11040 this.mutations = [];
11041 }
11042 findSignificantMutations(mutations) {
11043 return mutations.filter(mutation => {
11044 return this.mutationIsSignificant(mutation);
11045 });
11046 }
11047 mutationIsSignificant(mutation) {
11048 if (this.nodeIsMutable(mutation.target)) {
11049 return false;
11050 }
11051 for (const node of Array.from(this.nodesModifiedByMutation(mutation))) {
11052 if (this.nodeIsSignificant(node)) return true;
11053 }
11054 return false;
11055 }
11056 nodeIsSignificant(node) {
11057 return node !== this.element && !this.nodeIsMutable(node) && !nodeIsEmptyTextNode(node);
11058 }
11059 nodeIsMutable(node) {
11060 return findClosestElementFromNode(node, {
11061 matchingSelector: mutableSelector
11062 });
11063 }
11064 nodesModifiedByMutation(mutation) {
11065 const nodes = [];
11066 switch (mutation.type) {
11067 case "attributes":
11068 if (mutation.attributeName !== mutableAttributeName) {
11069 nodes.push(mutation.target);
11070 }
11071 break;
11072 case "characterData":
11073 // Changes to text nodes should consider the parent element
11074 nodes.push(mutation.target.parentNode);
11075 nodes.push(mutation.target);
11076 break;
11077 case "childList":
11078 // Consider each added or removed node
11079 nodes.push(...Array.from(mutation.addedNodes || []));
11080 nodes.push(...Array.from(mutation.removedNodes || []));
11081 break;
11082 }
11083 return nodes;
11084 }
11085 getMutationSummary() {
11086 return this.getTextMutationSummary();
11087 }
11088 getTextMutationSummary() {
11089 const {
11090 additions,
11091 deletions
11092 } = this.getTextChangesFromCharacterData();
11093 const textChanges = this.getTextChangesFromChildList();
11094 Array.from(textChanges.additions).forEach(addition => {
11095 if (!Array.from(additions).includes(addition)) {
11096 additions.push(addition);
11097 }
11098 });
11099 deletions.push(...Array.from(textChanges.deletions || []));
11100 const summary = {};
11101 const added = additions.join("");
11102 if (added) {
11103 summary.textAdded = added;
11104 }
11105 const deleted = deletions.join("");
11106 if (deleted) {
11107 summary.textDeleted = deleted;
11108 }
11109 return summary;
11110 }
11111 getMutationsByType(type) {
11112 return Array.from(this.mutations).filter(mutation => mutation.type === type);
11113 }
11114 getTextChangesFromChildList() {
11115 let textAdded, textRemoved;
11116 const addedNodes = [];
11117 const removedNodes = [];
11118 Array.from(this.getMutationsByType("childList")).forEach(mutation => {
11119 addedNodes.push(...Array.from(mutation.addedNodes || []));
11120 removedNodes.push(...Array.from(mutation.removedNodes || []));
11121 });
11122 const singleBlockCommentRemoved = addedNodes.length === 0 && removedNodes.length === 1 && nodeIsBlockStartComment(removedNodes[0]);
11123 if (singleBlockCommentRemoved) {
11124 textAdded = [];
11125 textRemoved = ["\n"];
11126 } else {
11127 textAdded = getTextForNodes(addedNodes);
11128 textRemoved = getTextForNodes(removedNodes);
11129 }
11130 const additions = textAdded.filter((text, index) => text !== textRemoved[index]).map(normalizeSpaces);
11131 const deletions = textRemoved.filter((text, index) => text !== textAdded[index]).map(normalizeSpaces);
11132 return {
11133 additions,
11134 deletions
11135 };
11136 }
11137 getTextChangesFromCharacterData() {
11138 let added, removed;
11139 const characterMutations = this.getMutationsByType("characterData");
11140 if (characterMutations.length) {
11141 const startMutation = characterMutations[0],
11142 endMutation = characterMutations[characterMutations.length - 1];
11143 const oldString = normalizeSpaces(startMutation.oldValue);
11144 const newString = normalizeSpaces(endMutation.target.data);
11145 const summarized = summarizeStringChange(oldString, newString);
11146 added = summarized.added;
11147 removed = summarized.removed;
11148 }
11149 return {
11150 additions: added ? [added] : [],
11151 deletions: removed ? [removed] : []
11152 };
11153 }
11154 }
11155 const getTextForNodes = function () {
11156 let nodes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
11157 const text = [];
11158 for (const node of Array.from(nodes)) {
11159 switch (node.nodeType) {
11160 case Node.TEXT_NODE:
11161 text.push(node.data);
11162 break;
11163 case Node.ELEMENT_NODE:
11164 if (tagName(node) === "br") {
11165 text.push("\n");
11166 } else {
11167 text.push(...Array.from(getTextForNodes(node.childNodes) || []));
11168 }
11169 break;
11170 }
11171 }
11172 return text;
11173 };
11174
11175 /* eslint-disable
11176 no-empty,
11177 */
11178 class FileVerificationOperation extends Operation {
11179 constructor(file) {
11180 super(...arguments);
11181 this.file = file;
11182 }
11183 perform(callback) {
11184 const reader = new FileReader();
11185 reader.onerror = () => callback(false);
11186 reader.onload = () => {
11187 reader.onerror = null;
11188 try {
11189 reader.abort();
11190 } catch (error) {}
11191 return callback(true, this.file);
11192 };
11193 return reader.readAsArrayBuffer(this.file);
11194 }
11195 }
11196
11197 // Each software keyboard on Android emits its own set of events and some of them can be buggy.
11198 // This class detects when some buggy events are being emitted and lets know the input controller
11199 // that they should be ignored.
11200 class FlakyAndroidKeyboardDetector {
11201 constructor(element) {
11202 this.element = element;
11203 }
11204 shouldIgnore(event) {
11205 if (!browser$1.samsungAndroid) return false;
11206 this.previousEvent = this.event;
11207 this.event = event;
11208 this.checkSamsungKeyboardBuggyModeStart();
11209 this.checkSamsungKeyboardBuggyModeEnd();
11210 return this.buggyMode;
11211 }
11212
11213 // private
11214
11215 // The Samsung keyboard on Android can enter a buggy state in which it emits a flurry of confused events that,
11216 // if processed, corrupts the editor. The buggy mode always starts with an insertText event, right after a
11217 // keydown event with for an "Unidentified" key, with the same text as the editor element, except for a few
11218 // extra whitespace, or exotic utf8, characters.
11219 checkSamsungKeyboardBuggyModeStart() {
11220 if (this.insertingLongTextAfterUnidentifiedChar() && differsInWhitespace(this.element.innerText, this.event.data)) {
11221 this.buggyMode = true;
11222 this.event.preventDefault();
11223 }
11224 }
11225
11226 // The flurry of buggy events are always insertText. If we see any other type, it means it's over.
11227 checkSamsungKeyboardBuggyModeEnd() {
11228 if (this.buggyMode && this.event.inputType !== "insertText") {
11229 this.buggyMode = false;
11230 }
11231 }
11232 insertingLongTextAfterUnidentifiedChar() {
11233 var _this$event$data;
11234 return this.isBeforeInputInsertText() && this.previousEventWasUnidentifiedKeydown() && ((_this$event$data = this.event.data) === null || _this$event$data === void 0 ? void 0 : _this$event$data.length) > 50;
11235 }
11236 isBeforeInputInsertText() {
11237 return this.event.type === "beforeinput" && this.event.inputType === "insertText";
11238 }
11239 previousEventWasUnidentifiedKeydown() {
11240 var _this$previousEvent, _this$previousEvent2;
11241 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";
11242 }
11243 }
11244 const differsInWhitespace = (text1, text2) => {
11245 return normalize(text1) === normalize(text2);
11246 };
11247 const whiteSpaceNormalizerRegexp = new RegExp("(".concat(OBJECT_REPLACEMENT_CHARACTER, "|").concat(ZERO_WIDTH_SPACE, "|").concat(NON_BREAKING_SPACE, "|\\s)+"), "g");
11248 const normalize = text => text.replace(whiteSpaceNormalizerRegexp, " ").trim();
11249
11250 class InputController extends BasicObject {
11251 constructor(element) {
11252 super(...arguments);
11253 this.element = element;
11254 this.mutationObserver = new MutationObserver(this.element);
11255 this.mutationObserver.delegate = this;
11256 this.flakyKeyboardDetector = new FlakyAndroidKeyboardDetector(this.element);
11257 for (const eventName in this.constructor.events) {
11258 handleEvent(eventName, {
11259 onElement: this.element,
11260 withCallback: this.handlerFor(eventName)
11261 });
11262 }
11263 }
11264 elementDidMutate(mutationSummary) {}
11265 editorWillSyncDocumentView() {
11266 return this.mutationObserver.stop();
11267 }
11268 editorDidSyncDocumentView() {
11269 return this.mutationObserver.start();
11270 }
11271 requestRender() {
11272 var _this$delegate, _this$delegate$inputC;
11273 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);
11274 }
11275 requestReparse() {
11276 var _this$delegate2, _this$delegate2$input;
11277 (_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);
11278 return this.requestRender();
11279 }
11280 attachFiles(files) {
11281 const operations = Array.from(files).map(file => new FileVerificationOperation(file));
11282 return Promise.all(operations).then(files => {
11283 this.handleInput(function () {
11284 var _this$delegate3, _this$responder;
11285 (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || _this$delegate3.inputControllerWillAttachFiles();
11286 (_this$responder = this.responder) === null || _this$responder === void 0 || _this$responder.insertFiles(files);
11287 return this.requestRender();
11288 });
11289 });
11290 }
11291
11292 // Private
11293
11294 handlerFor(eventName) {
11295 return event => {
11296 if (!event.defaultPrevented) {
11297 this.handleInput(() => {
11298 if (!innerElementIsActive(this.element)) {
11299 if (this.flakyKeyboardDetector.shouldIgnore(event)) return;
11300 this.eventName = eventName;
11301 this.constructor.events[eventName].call(this, event);
11302 }
11303 });
11304 }
11305 };
11306 }
11307 handleInput(callback) {
11308 try {
11309 var _this$delegate4;
11310 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillHandleInput();
11311 callback.call(this);
11312 } finally {
11313 var _this$delegate5;
11314 (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.inputControllerDidHandleInput();
11315 }
11316 }
11317 createLinkHTML(href, text) {
11318 const link = document.createElement("a");
11319 link.href = href;
11320 link.textContent = text ? text : href;
11321 return link.outerHTML;
11322 }
11323 }
11324 _defineProperty(InputController, "events", {});
11325
11326 var _$codePointAt, _;
11327 const {
11328 browser,
11329 keyNames
11330 } = config;
11331 let pastedFileCount = 0;
11332 class Level0InputController extends InputController {
11333 constructor() {
11334 super(...arguments);
11335 this.resetInputSummary();
11336 }
11337 setInputSummary() {
11338 let summary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
11339 this.inputSummary.eventName = this.eventName;
11340 for (const key in summary) {
11341 const value = summary[key];
11342 this.inputSummary[key] = value;
11343 }
11344 return this.inputSummary;
11345 }
11346 resetInputSummary() {
11347 this.inputSummary = {};
11348 }
11349 reset() {
11350 this.resetInputSummary();
11351 return selectionChangeObserver.reset();
11352 }
11353
11354 // Mutation observer delegate
11355
11356 elementDidMutate(mutationSummary) {
11357 if (this.isComposing()) {
11358 var _this$delegate, _this$delegate$inputC;
11359 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);
11360 } else {
11361 return this.handleInput(function () {
11362 if (this.mutationIsSignificant(mutationSummary)) {
11363 if (this.mutationIsExpected(mutationSummary)) {
11364 this.requestRender();
11365 } else {
11366 this.requestReparse();
11367 }
11368 }
11369 return this.reset();
11370 });
11371 }
11372 }
11373 mutationIsExpected(_ref) {
11374 let {
11375 textAdded,
11376 textDeleted
11377 } = _ref;
11378 if (this.inputSummary.preferDocument) {
11379 return true;
11380 }
11381 const mutationAdditionMatchesSummary = textAdded != null ? textAdded === this.inputSummary.textAdded : !this.inputSummary.textAdded;
11382 const mutationDeletionMatchesSummary = textDeleted != null ? this.inputSummary.didDelete : !this.inputSummary.didDelete;
11383 const unexpectedNewlineAddition = ["\n", " \n"].includes(textAdded) && !mutationAdditionMatchesSummary;
11384 const unexpectedNewlineDeletion = textDeleted === "\n" && !mutationDeletionMatchesSummary;
11385 const singleUnexpectedNewline = unexpectedNewlineAddition && !unexpectedNewlineDeletion || unexpectedNewlineDeletion && !unexpectedNewlineAddition;
11386 if (singleUnexpectedNewline) {
11387 const range = this.getSelectedRange();
11388 if (range) {
11389 var _this$responder;
11390 const offset = unexpectedNewlineAddition ? textAdded.replace(/\n$/, "").length || -1 : (textAdded === null || textAdded === void 0 ? void 0 : textAdded.length) || 1;
11391 if ((_this$responder = this.responder) !== null && _this$responder !== void 0 && _this$responder.positionIsBlockBreak(range[1] + offset)) {
11392 return true;
11393 }
11394 }
11395 }
11396 return mutationAdditionMatchesSummary && mutationDeletionMatchesSummary;
11397 }
11398 mutationIsSignificant(mutationSummary) {
11399 var _this$compositionInpu;
11400 const textChanged = Object.keys(mutationSummary).length > 0;
11401 const composedEmptyString = ((_this$compositionInpu = this.compositionInput) === null || _this$compositionInpu === void 0 ? void 0 : _this$compositionInpu.getEndData()) === "";
11402 return textChanged || !composedEmptyString;
11403 }
11404
11405 // Private
11406
11407 getCompositionInput() {
11408 if (this.isComposing()) {
11409 return this.compositionInput;
11410 } else {
11411 this.compositionInput = new CompositionInput(this);
11412 }
11413 }
11414 isComposing() {
11415 return this.compositionInput && !this.compositionInput.isEnded();
11416 }
11417 deleteInDirection(direction, event) {
11418 var _this$responder2;
11419 if (((_this$responder2 = this.responder) === null || _this$responder2 === void 0 ? void 0 : _this$responder2.deleteInDirection(direction)) === false) {
11420 if (event) {
11421 event.preventDefault();
11422 return this.requestRender();
11423 }
11424 } else {
11425 return this.setInputSummary({
11426 didDelete: true
11427 });
11428 }
11429 }
11430 serializeSelectionToDataTransfer(dataTransfer) {
11431 var _this$responder3;
11432 if (!dataTransferIsWritable(dataTransfer)) return;
11433 const document = (_this$responder3 = this.responder) === null || _this$responder3 === void 0 ? void 0 : _this$responder3.getSelectedDocument().toSerializableDocument();
11434 dataTransfer.setData("application/x-trix-document", JSON.stringify(document));
11435 dataTransfer.setData("text/html", DocumentView.render(document).innerHTML);
11436 dataTransfer.setData("text/plain", document.toString().replace(/\n$/, ""));
11437 return true;
11438 }
11439 canAcceptDataTransfer(dataTransfer) {
11440 const types = {};
11441 Array.from((dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.types) || []).forEach(type => {
11442 types[type] = true;
11443 });
11444 return types.Files || types["application/x-trix-document"] || types["text/html"] || types["text/plain"];
11445 }
11446 getPastedHTMLUsingHiddenElement(callback) {
11447 const selectedRange = this.getSelectedRange();
11448 const style = {
11449 position: "absolute",
11450 left: "".concat(window.pageXOffset, "px"),
11451 top: "".concat(window.pageYOffset, "px"),
11452 opacity: 0
11453 };
11454 const element = makeElement({
11455 style,
11456 tagName: "div",
11457 editable: true
11458 });
11459 document.body.appendChild(element);
11460 element.focus();
11461 return requestAnimationFrame(() => {
11462 const html = element.innerHTML;
11463 removeNode(element);
11464 this.setSelectedRange(selectedRange);
11465 return callback(html);
11466 });
11467 }
11468 }
11469 _defineProperty(Level0InputController, "events", {
11470 keydown(event) {
11471 if (!this.isComposing()) {
11472 this.resetInputSummary();
11473 }
11474 this.inputSummary.didInput = true;
11475 const keyName = keyNames[event.keyCode];
11476 if (keyName) {
11477 var _context2;
11478 let context = this.keys;
11479 ["ctrl", "alt", "shift", "meta"].forEach(modifier => {
11480 if (event["".concat(modifier, "Key")]) {
11481 var _context;
11482 if (modifier === "ctrl") {
11483 modifier = "control";
11484 }
11485 context = (_context = context) === null || _context === void 0 ? void 0 : _context[modifier];
11486 }
11487 });
11488 if (((_context2 = context) === null || _context2 === void 0 ? void 0 : _context2[keyName]) != null) {
11489 this.setInputSummary({
11490 keyName
11491 });
11492 selectionChangeObserver.reset();
11493 context[keyName].call(this, event);
11494 }
11495 }
11496 if (keyEventIsKeyboardCommand(event)) {
11497 const character = String.fromCharCode(event.keyCode).toLowerCase();
11498 if (character) {
11499 var _this$delegate3;
11500 const keys = ["alt", "shift"].map(modifier => {
11501 if (event["".concat(modifier, "Key")]) {
11502 return modifier;
11503 }
11504 }).filter(key => key);
11505 keys.push(character);
11506 if ((_this$delegate3 = this.delegate) !== null && _this$delegate3 !== void 0 && _this$delegate3.inputControllerDidReceiveKeyboardCommand(keys)) {
11507 event.preventDefault();
11508 }
11509 }
11510 }
11511 },
11512 keypress(event) {
11513 if (this.inputSummary.eventName != null) return;
11514 if (event.metaKey) return;
11515 if (event.ctrlKey && !event.altKey) return;
11516 const string = stringFromKeyEvent(event);
11517 if (string) {
11518 var _this$delegate4, _this$responder9;
11519 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillPerformTyping();
11520 (_this$responder9 = this.responder) === null || _this$responder9 === void 0 || _this$responder9.insertString(string);
11521 return this.setInputSummary({
11522 textAdded: string,
11523 didDelete: this.selectionIsExpanded()
11524 });
11525 }
11526 },
11527 textInput(event) {
11528 // Handle autocapitalization
11529 const {
11530 data
11531 } = event;
11532 const {
11533 textAdded
11534 } = this.inputSummary;
11535 if (textAdded && textAdded !== data && textAdded.toUpperCase() === data) {
11536 var _this$responder10;
11537 const range = this.getSelectedRange();
11538 this.setSelectedRange([range[0], range[1] + textAdded.length]);
11539 (_this$responder10 = this.responder) === null || _this$responder10 === void 0 || _this$responder10.insertString(data);
11540 this.setInputSummary({
11541 textAdded: data
11542 });
11543 return this.setSelectedRange(range);
11544 }
11545 },
11546 dragenter(event) {
11547 event.preventDefault();
11548 },
11549 dragstart(event) {
11550 var _this$delegate5, _this$delegate5$input;
11551 this.serializeSelectionToDataTransfer(event.dataTransfer);
11552 this.draggedRange = this.getSelectedRange();
11553 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);
11554 },
11555 dragover(event) {
11556 if (this.draggedRange || this.canAcceptDataTransfer(event.dataTransfer)) {
11557 event.preventDefault();
11558 const draggingPoint = {
11559 x: event.clientX,
11560 y: event.clientY
11561 };
11562 if (!objectsAreEqual(draggingPoint, this.draggingPoint)) {
11563 var _this$delegate6, _this$delegate6$input;
11564 this.draggingPoint = draggingPoint;
11565 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);
11566 }
11567 }
11568 },
11569 dragend(event) {
11570 var _this$delegate7, _this$delegate7$input;
11571 (_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);
11572 this.draggedRange = null;
11573 this.draggingPoint = null;
11574 },
11575 drop(event) {
11576 var _event$dataTransfer, _this$responder11;
11577 event.preventDefault();
11578 const files = (_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.files;
11579 const documentJSON = event.dataTransfer.getData("application/x-trix-document");
11580 const point = {
11581 x: event.clientX,
11582 y: event.clientY
11583 };
11584 (_this$responder11 = this.responder) === null || _this$responder11 === void 0 || _this$responder11.setLocationRangeFromPointRange(point);
11585 if (files !== null && files !== void 0 && files.length) {
11586 this.attachFiles(files);
11587 } else if (this.draggedRange) {
11588 var _this$delegate8, _this$responder12;
11589 (_this$delegate8 = this.delegate) === null || _this$delegate8 === void 0 || _this$delegate8.inputControllerWillMoveText();
11590 (_this$responder12 = this.responder) === null || _this$responder12 === void 0 || _this$responder12.moveTextFromRange(this.draggedRange);
11591 this.draggedRange = null;
11592 this.requestRender();
11593 } else if (documentJSON) {
11594 var _this$responder13;
11595 const document = Document.fromJSONString(documentJSON);
11596 (_this$responder13 = this.responder) === null || _this$responder13 === void 0 || _this$responder13.insertDocument(document);
11597 this.requestRender();
11598 }
11599 this.draggedRange = null;
11600 this.draggingPoint = null;
11601 },
11602 cut(event) {
11603 var _this$responder14;
11604 if ((_this$responder14 = this.responder) !== null && _this$responder14 !== void 0 && _this$responder14.selectionIsExpanded()) {
11605 var _this$delegate9;
11606 if (this.serializeSelectionToDataTransfer(event.clipboardData)) {
11607 event.preventDefault();
11608 }
11609 (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 || _this$delegate9.inputControllerWillCutText();
11610 this.deleteInDirection("backward");
11611 if (event.defaultPrevented) {
11612 return this.requestRender();
11613 }
11614 }
11615 },
11616 copy(event) {
11617 var _this$responder15;
11618 if ((_this$responder15 = this.responder) !== null && _this$responder15 !== void 0 && _this$responder15.selectionIsExpanded()) {
11619 if (this.serializeSelectionToDataTransfer(event.clipboardData)) {
11620 event.preventDefault();
11621 }
11622 }
11623 },
11624 paste(event) {
11625 const clipboard = event.clipboardData || event.testClipboardData;
11626 const paste = {
11627 clipboard
11628 };
11629 if (!clipboard || pasteEventIsCrippledSafariHTMLPaste(event)) {
11630 this.getPastedHTMLUsingHiddenElement(html => {
11631 var _this$delegate10, _this$responder16, _this$delegate11;
11632 paste.type = "text/html";
11633 paste.html = html;
11634 (_this$delegate10 = this.delegate) === null || _this$delegate10 === void 0 || _this$delegate10.inputControllerWillPaste(paste);
11635 (_this$responder16 = this.responder) === null || _this$responder16 === void 0 || _this$responder16.insertHTML(paste.html);
11636 this.requestRender();
11637 return (_this$delegate11 = this.delegate) === null || _this$delegate11 === void 0 ? void 0 : _this$delegate11.inputControllerDidPaste(paste);
11638 });
11639 return;
11640 }
11641 const href = clipboard.getData("URL");
11642 const html = clipboard.getData("text/html");
11643 const name = clipboard.getData("public.url-name");
11644 if (href) {
11645 var _this$delegate12, _this$responder17, _this$delegate13;
11646 let string;
11647 paste.type = "text/html";
11648 if (name) {
11649 string = squishBreakableWhitespace(name).trim();
11650 } else {
11651 string = href;
11652 }
11653 paste.html = this.createLinkHTML(href, string);
11654 (_this$delegate12 = this.delegate) === null || _this$delegate12 === void 0 || _this$delegate12.inputControllerWillPaste(paste);
11655 this.setInputSummary({
11656 textAdded: string,
11657 didDelete: this.selectionIsExpanded()
11658 });
11659 (_this$responder17 = this.responder) === null || _this$responder17 === void 0 || _this$responder17.insertHTML(paste.html);
11660 this.requestRender();
11661 (_this$delegate13 = this.delegate) === null || _this$delegate13 === void 0 || _this$delegate13.inputControllerDidPaste(paste);
11662 } else if (dataTransferIsPlainText(clipboard)) {
11663 var _this$delegate14, _this$responder18, _this$delegate15;
11664 paste.type = "text/plain";
11665 paste.string = clipboard.getData("text/plain");
11666 (_this$delegate14 = this.delegate) === null || _this$delegate14 === void 0 || _this$delegate14.inputControllerWillPaste(paste);
11667 this.setInputSummary({
11668 textAdded: paste.string,
11669 didDelete: this.selectionIsExpanded()
11670 });
11671 (_this$responder18 = this.responder) === null || _this$responder18 === void 0 || _this$responder18.insertString(paste.string);
11672 this.requestRender();
11673 (_this$delegate15 = this.delegate) === null || _this$delegate15 === void 0 || _this$delegate15.inputControllerDidPaste(paste);
11674 } else if (html) {
11675 var _this$delegate16, _this$responder19, _this$delegate17;
11676 paste.type = "text/html";
11677 paste.html = html;
11678 (_this$delegate16 = this.delegate) === null || _this$delegate16 === void 0 || _this$delegate16.inputControllerWillPaste(paste);
11679 (_this$responder19 = this.responder) === null || _this$responder19 === void 0 || _this$responder19.insertHTML(paste.html);
11680 this.requestRender();
11681 (_this$delegate17 = this.delegate) === null || _this$delegate17 === void 0 || _this$delegate17.inputControllerDidPaste(paste);
11682 } else if (Array.from(clipboard.types).includes("Files")) {
11683 var _clipboard$items, _clipboard$items$getA;
11684 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);
11685 if (file) {
11686 var _this$delegate18, _this$responder20, _this$delegate19;
11687 const extension = extensionForFile(file);
11688 if (!file.name && extension) {
11689 file.name = "pasted-file-".concat(++pastedFileCount, ".").concat(extension);
11690 }
11691 paste.type = "File";
11692 paste.file = file;
11693 (_this$delegate18 = this.delegate) === null || _this$delegate18 === void 0 || _this$delegate18.inputControllerWillAttachFiles();
11694 (_this$responder20 = this.responder) === null || _this$responder20 === void 0 || _this$responder20.insertFile(paste.file);
11695 this.requestRender();
11696 (_this$delegate19 = this.delegate) === null || _this$delegate19 === void 0 || _this$delegate19.inputControllerDidPaste(paste);
11697 }
11698 }
11699 event.preventDefault();
11700 },
11701 compositionstart(event) {
11702 return this.getCompositionInput().start(event.data);
11703 },
11704 compositionupdate(event) {
11705 return this.getCompositionInput().update(event.data);
11706 },
11707 compositionend(event) {
11708 return this.getCompositionInput().end(event.data);
11709 },
11710 beforeinput(event) {
11711 this.inputSummary.didInput = true;
11712 },
11713 input(event) {
11714 this.inputSummary.didInput = true;
11715 return event.stopPropagation();
11716 }
11717 });
11718 _defineProperty(Level0InputController, "keys", {
11719 backspace(event) {
11720 var _this$delegate20;
11721 (_this$delegate20 = this.delegate) === null || _this$delegate20 === void 0 || _this$delegate20.inputControllerWillPerformTyping();
11722 return this.deleteInDirection("backward", event);
11723 },
11724 delete(event) {
11725 var _this$delegate21;
11726 (_this$delegate21 = this.delegate) === null || _this$delegate21 === void 0 || _this$delegate21.inputControllerWillPerformTyping();
11727 return this.deleteInDirection("forward", event);
11728 },
11729 return(event) {
11730 var _this$delegate22, _this$responder21;
11731 this.setInputSummary({
11732 preferDocument: true
11733 });
11734 (_this$delegate22 = this.delegate) === null || _this$delegate22 === void 0 || _this$delegate22.inputControllerWillPerformTyping();
11735 return (_this$responder21 = this.responder) === null || _this$responder21 === void 0 ? void 0 : _this$responder21.insertLineBreak();
11736 },
11737 tab(event) {
11738 var _this$responder22;
11739 if ((_this$responder22 = this.responder) !== null && _this$responder22 !== void 0 && _this$responder22.canIncreaseNestingLevel()) {
11740 var _this$responder23;
11741 (_this$responder23 = this.responder) === null || _this$responder23 === void 0 || _this$responder23.increaseNestingLevel();
11742 this.requestRender();
11743 event.preventDefault();
11744 }
11745 },
11746 left(event) {
11747 if (this.selectionIsInCursorTarget()) {
11748 var _this$responder24;
11749 event.preventDefault();
11750 return (_this$responder24 = this.responder) === null || _this$responder24 === void 0 ? void 0 : _this$responder24.moveCursorInDirection("backward");
11751 }
11752 },
11753 right(event) {
11754 if (this.selectionIsInCursorTarget()) {
11755 var _this$responder25;
11756 event.preventDefault();
11757 return (_this$responder25 = this.responder) === null || _this$responder25 === void 0 ? void 0 : _this$responder25.moveCursorInDirection("forward");
11758 }
11759 },
11760 control: {
11761 d(event) {
11762 var _this$delegate23;
11763 (_this$delegate23 = this.delegate) === null || _this$delegate23 === void 0 || _this$delegate23.inputControllerWillPerformTyping();
11764 return this.deleteInDirection("forward", event);
11765 },
11766 h(event) {
11767 var _this$delegate24;
11768 (_this$delegate24 = this.delegate) === null || _this$delegate24 === void 0 || _this$delegate24.inputControllerWillPerformTyping();
11769 return this.deleteInDirection("backward", event);
11770 },
11771 o(event) {
11772 var _this$delegate25, _this$responder26;
11773 event.preventDefault();
11774 (_this$delegate25 = this.delegate) === null || _this$delegate25 === void 0 || _this$delegate25.inputControllerWillPerformTyping();
11775 (_this$responder26 = this.responder) === null || _this$responder26 === void 0 || _this$responder26.insertString("\n", {
11776 updatePosition: false
11777 });
11778 return this.requestRender();
11779 }
11780 },
11781 shift: {
11782 return(event) {
11783 var _this$delegate26, _this$responder27;
11784 (_this$delegate26 = this.delegate) === null || _this$delegate26 === void 0 || _this$delegate26.inputControllerWillPerformTyping();
11785 (_this$responder27 = this.responder) === null || _this$responder27 === void 0 || _this$responder27.insertString("\n");
11786 this.requestRender();
11787 event.preventDefault();
11788 },
11789 tab(event) {
11790 var _this$responder28;
11791 if ((_this$responder28 = this.responder) !== null && _this$responder28 !== void 0 && _this$responder28.canDecreaseNestingLevel()) {
11792 var _this$responder29;
11793 (_this$responder29 = this.responder) === null || _this$responder29 === void 0 || _this$responder29.decreaseNestingLevel();
11794 this.requestRender();
11795 event.preventDefault();
11796 }
11797 },
11798 left(event) {
11799 if (this.selectionIsInCursorTarget()) {
11800 event.preventDefault();
11801 return this.expandSelectionInDirection("backward");
11802 }
11803 },
11804 right(event) {
11805 if (this.selectionIsInCursorTarget()) {
11806 event.preventDefault();
11807 return this.expandSelectionInDirection("forward");
11808 }
11809 }
11810 },
11811 alt: {
11812 backspace(event) {
11813 var _this$delegate27;
11814 this.setInputSummary({
11815 preferDocument: false
11816 });
11817 return (_this$delegate27 = this.delegate) === null || _this$delegate27 === void 0 ? void 0 : _this$delegate27.inputControllerWillPerformTyping();
11818 }
11819 },
11820 meta: {
11821 backspace(event) {
11822 var _this$delegate28;
11823 this.setInputSummary({
11824 preferDocument: false
11825 });
11826 return (_this$delegate28 = this.delegate) === null || _this$delegate28 === void 0 ? void 0 : _this$delegate28.inputControllerWillPerformTyping();
11827 }
11828 }
11829 });
11830 Level0InputController.proxyMethod("responder?.getSelectedRange");
11831 Level0InputController.proxyMethod("responder?.setSelectedRange");
11832 Level0InputController.proxyMethod("responder?.expandSelectionInDirection");
11833 Level0InputController.proxyMethod("responder?.selectionIsInCursorTarget");
11834 Level0InputController.proxyMethod("responder?.selectionIsExpanded");
11835 const extensionForFile = file => {
11836 var _file$type;
11837 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];
11838 };
11839 const hasStringCodePointAt = !!((_$codePointAt = (_ = " ").codePointAt) !== null && _$codePointAt !== void 0 && _$codePointAt.call(_, 0));
11840 const stringFromKeyEvent = function (event) {
11841 if (event.key && hasStringCodePointAt && event.key.codePointAt(0) === event.keyCode) {
11842 return event.key;
11843 } else {
11844 let code;
11845 if (event.which === null) {
11846 code = event.keyCode;
11847 } else if (event.which !== 0 && event.charCode !== 0) {
11848 code = event.charCode;
11849 }
11850 if (code != null && keyNames[code] !== "escape") {
11851 return UTF16String.fromCodepoints([code]).toString();
11852 }
11853 }
11854 };
11855 const pasteEventIsCrippledSafariHTMLPaste = function (event) {
11856 const paste = event.clipboardData;
11857 if (paste) {
11858 if (paste.types.includes("text/html")) {
11859 // Answer is yes if there's any possibility of Paste and Match Style in Safari,
11860 // which is nearly impossible to detect confidently: https://bugs.webkit.org/show_bug.cgi?id=174165
11861 for (const type of paste.types) {
11862 const hasPasteboardFlavor = /^CorePasteboardFlavorType/.test(type);
11863 const hasReadableDynamicData = /^dyn\./.test(type) && paste.getData(type);
11864 const mightBePasteAndMatchStyle = hasPasteboardFlavor || hasReadableDynamicData;
11865 if (mightBePasteAndMatchStyle) {
11866 return true;
11867 }
11868 }
11869 return false;
11870 } else {
11871 const isExternalHTMLPaste = paste.types.includes("com.apple.webarchive");
11872 const isExternalRichTextPaste = paste.types.includes("com.apple.flat-rtfd");
11873 return isExternalHTMLPaste || isExternalRichTextPaste;
11874 }
11875 }
11876 };
11877 class CompositionInput extends BasicObject {
11878 constructor(inputController) {
11879 super(...arguments);
11880 this.inputController = inputController;
11881 this.responder = this.inputController.responder;
11882 this.delegate = this.inputController.delegate;
11883 this.inputSummary = this.inputController.inputSummary;
11884 this.data = {};
11885 }
11886 start(data) {
11887 this.data.start = data;
11888 if (this.isSignificant()) {
11889 var _this$responder5;
11890 if (this.inputSummary.eventName === "keypress" && this.inputSummary.textAdded) {
11891 var _this$responder4;
11892 (_this$responder4 = this.responder) === null || _this$responder4 === void 0 || _this$responder4.deleteInDirection("left");
11893 }
11894 if (!this.selectionIsExpanded()) {
11895 this.insertPlaceholder();
11896 this.requestRender();
11897 }
11898 this.range = (_this$responder5 = this.responder) === null || _this$responder5 === void 0 ? void 0 : _this$responder5.getSelectedRange();
11899 }
11900 }
11901 update(data) {
11902 this.data.update = data;
11903 if (this.isSignificant()) {
11904 const range = this.selectPlaceholder();
11905 if (range) {
11906 this.forgetPlaceholder();
11907 this.range = range;
11908 }
11909 }
11910 }
11911 end(data) {
11912 this.data.end = data;
11913 if (this.isSignificant()) {
11914 this.forgetPlaceholder();
11915 if (this.canApplyToDocument()) {
11916 var _this$delegate2, _this$responder6, _this$responder7, _this$responder8;
11917 this.setInputSummary({
11918 preferDocument: true,
11919 didInput: false
11920 });
11921 (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || _this$delegate2.inputControllerWillPerformTyping();
11922 (_this$responder6 = this.responder) === null || _this$responder6 === void 0 || _this$responder6.setSelectedRange(this.range);
11923 (_this$responder7 = this.responder) === null || _this$responder7 === void 0 || _this$responder7.insertString(this.data.end);
11924 return (_this$responder8 = this.responder) === null || _this$responder8 === void 0 ? void 0 : _this$responder8.setSelectedRange(this.range[0] + this.data.end.length);
11925 } else if (this.data.start != null || this.data.update != null) {
11926 this.requestReparse();
11927 return this.inputController.reset();
11928 }
11929 } else {
11930 return this.inputController.reset();
11931 }
11932 }
11933 getEndData() {
11934 return this.data.end;
11935 }
11936 isEnded() {
11937 return this.getEndData() != null;
11938 }
11939 isSignificant() {
11940 if (browser.composesExistingText) {
11941 return this.inputSummary.didInput;
11942 } else {
11943 return true;
11944 }
11945 }
11946
11947 // Private
11948
11949 canApplyToDocument() {
11950 var _this$data$start, _this$data$end;
11951 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;
11952 }
11953 }
11954 CompositionInput.proxyMethod("inputController.setInputSummary");
11955 CompositionInput.proxyMethod("inputController.requestRender");
11956 CompositionInput.proxyMethod("inputController.requestReparse");
11957 CompositionInput.proxyMethod("responder?.selectionIsExpanded");
11958 CompositionInput.proxyMethod("responder?.insertPlaceholder");
11959 CompositionInput.proxyMethod("responder?.selectPlaceholder");
11960 CompositionInput.proxyMethod("responder?.forgetPlaceholder");
11961
11962 class Level2InputController extends InputController {
11963 constructor() {
11964 super(...arguments);
11965 this.render = this.render.bind(this);
11966 }
11967 elementDidMutate() {
11968 if (this.scheduledRender) {
11969 if (this.composing) {
11970 var _this$delegate, _this$delegate$inputC;
11971 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);
11972 }
11973 } else {
11974 return this.reparse();
11975 }
11976 }
11977 scheduleRender() {
11978 return this.scheduledRender ? this.scheduledRender : this.scheduledRender = requestAnimationFrame(this.render);
11979 }
11980 render() {
11981 var _this$afterRender;
11982 cancelAnimationFrame(this.scheduledRender);
11983 this.scheduledRender = null;
11984 if (!this.composing) {
11985 var _this$delegate2;
11986 (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || _this$delegate2.render();
11987 }
11988 (_this$afterRender = this.afterRender) === null || _this$afterRender === void 0 || _this$afterRender.call(this);
11989 this.afterRender = null;
11990 }
11991 reparse() {
11992 var _this$delegate3;
11993 return (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 ? void 0 : _this$delegate3.reparse();
11994 }
11995
11996 // Responder helpers
11997
11998 insertString() {
11999 var _this$delegate4;
12000 let string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
12001 let options = arguments.length > 1 ? arguments[1] : undefined;
12002 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillPerformTyping();
12003 return this.withTargetDOMRange(function () {
12004 var _this$responder;
12005 return (_this$responder = this.responder) === null || _this$responder === void 0 ? void 0 : _this$responder.insertString(string, options);
12006 });
12007 }
12008 toggleAttributeIfSupported(attributeName) {
12009 if (getAllAttributeNames().includes(attributeName)) {
12010 var _this$delegate5;
12011 (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.inputControllerWillPerformFormatting(attributeName);
12012 return this.withTargetDOMRange(function () {
12013 var _this$responder2;
12014 return (_this$responder2 = this.responder) === null || _this$responder2 === void 0 ? void 0 : _this$responder2.toggleCurrentAttribute(attributeName);
12015 });
12016 }
12017 }
12018 activateAttributeIfSupported(attributeName, value) {
12019 if (getAllAttributeNames().includes(attributeName)) {
12020 var _this$delegate6;
12021 (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 || _this$delegate6.inputControllerWillPerformFormatting(attributeName);
12022 return this.withTargetDOMRange(function () {
12023 var _this$responder3;
12024 return (_this$responder3 = this.responder) === null || _this$responder3 === void 0 ? void 0 : _this$responder3.setCurrentAttribute(attributeName, value);
12025 });
12026 }
12027 }
12028 deleteInDirection(direction) {
12029 let {
12030 recordUndoEntry
12031 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
12032 recordUndoEntry: true
12033 };
12034 if (recordUndoEntry) {
12035 var _this$delegate7;
12036 (_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || _this$delegate7.inputControllerWillPerformTyping();
12037 }
12038 const perform = () => {
12039 var _this$responder4;
12040 return (_this$responder4 = this.responder) === null || _this$responder4 === void 0 ? void 0 : _this$responder4.deleteInDirection(direction);
12041 };
12042 const domRange = this.getTargetDOMRange({
12043 minLength: this.composing ? 1 : 2
12044 });
12045 if (domRange) {
12046 return this.withTargetDOMRange(domRange, perform);
12047 } else {
12048 return perform();
12049 }
12050 }
12051
12052 // Selection helpers
12053
12054 withTargetDOMRange(domRange, fn) {
12055 if (typeof domRange === "function") {
12056 fn = domRange;
12057 domRange = this.getTargetDOMRange();
12058 }
12059 if (domRange) {
12060 var _this$responder5;
12061 return (_this$responder5 = this.responder) === null || _this$responder5 === void 0 ? void 0 : _this$responder5.withTargetDOMRange(domRange, fn.bind(this));
12062 } else {
12063 selectionChangeObserver.reset();
12064 return fn.call(this);
12065 }
12066 }
12067 getTargetDOMRange() {
12068 var _this$event$getTarget, _this$event;
12069 let {
12070 minLength
12071 } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
12072 minLength: 0
12073 };
12074 const targetRanges = (_this$event$getTarget = (_this$event = this.event).getTargetRanges) === null || _this$event$getTarget === void 0 ? void 0 : _this$event$getTarget.call(_this$event);
12075 if (targetRanges) {
12076 if (targetRanges.length) {
12077 const domRange = staticRangeToRange(targetRanges[0]);
12078 if (minLength === 0 || domRange.toString().length >= minLength) {
12079 return domRange;
12080 }
12081 }
12082 }
12083 }
12084 withEvent(event, fn) {
12085 let result;
12086 this.event = event;
12087 try {
12088 result = fn.call(this);
12089 } finally {
12090 this.event = null;
12091 }
12092 return result;
12093 }
12094 }
12095 _defineProperty(Level2InputController, "events", {
12096 keydown(event) {
12097 if (keyEventIsKeyboardCommand(event)) {
12098 var _this$delegate8;
12099 const command = keyboardCommandFromKeyEvent(event);
12100 if ((_this$delegate8 = this.delegate) !== null && _this$delegate8 !== void 0 && _this$delegate8.inputControllerDidReceiveKeyboardCommand(command)) {
12101 event.preventDefault();
12102 }
12103 } else {
12104 let name = event.key;
12105 if (event.altKey) {
12106 name += "+Alt";
12107 }
12108 if (event.shiftKey) {
12109 name += "+Shift";
12110 }
12111 const handler = this.constructor.keys[name];
12112 if (handler) {
12113 return this.withEvent(event, handler);
12114 }
12115 }
12116 },
12117 // Handle paste event to work around beforeinput.insertFromPaste browser bugs.
12118 // Safe to remove each condition once fixed upstream.
12119 paste(event) {
12120 var _event$clipboardData;
12121 // https://bugs.webkit.org/show_bug.cgi?id=194921
12122 let paste;
12123 const href = (_event$clipboardData = event.clipboardData) === null || _event$clipboardData === void 0 ? void 0 : _event$clipboardData.getData("URL");
12124 if (pasteEventHasFilesOnly(event)) {
12125 event.preventDefault();
12126 return this.attachFiles(event.clipboardData.files);
12127
12128 // https://bugs.chromium.org/p/chromium/issues/detail?id=934448
12129 } else if (pasteEventHasPlainTextOnly(event)) {
12130 var _this$delegate9, _this$responder6, _this$delegate10;
12131 event.preventDefault();
12132 paste = {
12133 type: "text/plain",
12134 string: event.clipboardData.getData("text/plain")
12135 };
12136 (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 || _this$delegate9.inputControllerWillPaste(paste);
12137 (_this$responder6 = this.responder) === null || _this$responder6 === void 0 || _this$responder6.insertString(paste.string);
12138 this.render();
12139 return (_this$delegate10 = this.delegate) === null || _this$delegate10 === void 0 ? void 0 : _this$delegate10.inputControllerDidPaste(paste);
12140
12141 // https://bugs.webkit.org/show_bug.cgi?id=196702
12142 } else if (href) {
12143 var _this$delegate11, _this$responder7, _this$delegate12;
12144 event.preventDefault();
12145 paste = {
12146 type: "text/html",
12147 html: this.createLinkHTML(href)
12148 };
12149 (_this$delegate11 = this.delegate) === null || _this$delegate11 === void 0 || _this$delegate11.inputControllerWillPaste(paste);
12150 (_this$responder7 = this.responder) === null || _this$responder7 === void 0 || _this$responder7.insertHTML(paste.html);
12151 this.render();
12152 return (_this$delegate12 = this.delegate) === null || _this$delegate12 === void 0 ? void 0 : _this$delegate12.inputControllerDidPaste(paste);
12153 }
12154 },
12155 beforeinput(event) {
12156 const handler = this.constructor.inputTypes[event.inputType];
12157 const immmediateRender = shouldRenderInmmediatelyToDealWithIOSDictation(event);
12158 if (handler) {
12159 this.withEvent(event, handler);
12160 if (!immmediateRender) {
12161 this.scheduleRender();
12162 }
12163 }
12164 if (immmediateRender) {
12165 this.render();
12166 }
12167 },
12168 input(event) {
12169 selectionChangeObserver.reset();
12170 },
12171 dragstart(event) {
12172 var _this$responder8;
12173 if ((_this$responder8 = this.responder) !== null && _this$responder8 !== void 0 && _this$responder8.selectionContainsAttachments()) {
12174 var _this$responder9;
12175 event.dataTransfer.setData("application/x-trix-dragging", true);
12176 this.dragging = {
12177 range: (_this$responder9 = this.responder) === null || _this$responder9 === void 0 ? void 0 : _this$responder9.getSelectedRange(),
12178 point: pointFromEvent(event)
12179 };
12180 }
12181 },
12182 dragenter(event) {
12183 if (dragEventHasFiles(event)) {
12184 event.preventDefault();
12185 }
12186 },
12187 dragover(event) {
12188 if (this.dragging) {
12189 event.preventDefault();
12190 const point = pointFromEvent(event);
12191 if (!objectsAreEqual(point, this.dragging.point)) {
12192 var _this$responder10;
12193 this.dragging.point = point;
12194 return (_this$responder10 = this.responder) === null || _this$responder10 === void 0 ? void 0 : _this$responder10.setLocationRangeFromPointRange(point);
12195 }
12196 } else if (dragEventHasFiles(event)) {
12197 event.preventDefault();
12198 }
12199 },
12200 drop(event) {
12201 if (this.dragging) {
12202 var _this$delegate13, _this$responder11;
12203 event.preventDefault();
12204 (_this$delegate13 = this.delegate) === null || _this$delegate13 === void 0 || _this$delegate13.inputControllerWillMoveText();
12205 (_this$responder11 = this.responder) === null || _this$responder11 === void 0 || _this$responder11.moveTextFromRange(this.dragging.range);
12206 this.dragging = null;
12207 return this.scheduleRender();
12208 } else if (dragEventHasFiles(event)) {
12209 var _this$responder12;
12210 event.preventDefault();
12211 const point = pointFromEvent(event);
12212 (_this$responder12 = this.responder) === null || _this$responder12 === void 0 || _this$responder12.setLocationRangeFromPointRange(point);
12213 return this.attachFiles(event.dataTransfer.files);
12214 }
12215 },
12216 dragend() {
12217 if (this.dragging) {
12218 var _this$responder13;
12219 (_this$responder13 = this.responder) === null || _this$responder13 === void 0 || _this$responder13.setSelectedRange(this.dragging.range);
12220 this.dragging = null;
12221 }
12222 },
12223 compositionend(event) {
12224 if (this.composing) {
12225 this.composing = false;
12226 if (!browser$1.recentAndroid) this.scheduleRender();
12227 }
12228 }
12229 });
12230 _defineProperty(Level2InputController, "keys", {
12231 ArrowLeft() {
12232 var _this$responder14;
12233 if ((_this$responder14 = this.responder) !== null && _this$responder14 !== void 0 && _this$responder14.shouldManageMovingCursorInDirection("backward")) {
12234 var _this$responder15;
12235 this.event.preventDefault();
12236 return (_this$responder15 = this.responder) === null || _this$responder15 === void 0 ? void 0 : _this$responder15.moveCursorInDirection("backward");
12237 }
12238 },
12239 ArrowRight() {
12240 var _this$responder16;
12241 if ((_this$responder16 = this.responder) !== null && _this$responder16 !== void 0 && _this$responder16.shouldManageMovingCursorInDirection("forward")) {
12242 var _this$responder17;
12243 this.event.preventDefault();
12244 return (_this$responder17 = this.responder) === null || _this$responder17 === void 0 ? void 0 : _this$responder17.moveCursorInDirection("forward");
12245 }
12246 },
12247 Backspace() {
12248 var _this$responder18;
12249 if ((_this$responder18 = this.responder) !== null && _this$responder18 !== void 0 && _this$responder18.shouldManageDeletingInDirection("backward")) {
12250 var _this$delegate14, _this$responder19;
12251 this.event.preventDefault();
12252 (_this$delegate14 = this.delegate) === null || _this$delegate14 === void 0 || _this$delegate14.inputControllerWillPerformTyping();
12253 (_this$responder19 = this.responder) === null || _this$responder19 === void 0 || _this$responder19.deleteInDirection("backward");
12254 return this.render();
12255 }
12256 },
12257 Tab() {
12258 var _this$responder20;
12259 if ((_this$responder20 = this.responder) !== null && _this$responder20 !== void 0 && _this$responder20.canIncreaseNestingLevel()) {
12260 var _this$responder21;
12261 this.event.preventDefault();
12262 (_this$responder21 = this.responder) === null || _this$responder21 === void 0 || _this$responder21.increaseNestingLevel();
12263 return this.render();
12264 }
12265 },
12266 "Tab+Shift"() {
12267 var _this$responder22;
12268 if ((_this$responder22 = this.responder) !== null && _this$responder22 !== void 0 && _this$responder22.canDecreaseNestingLevel()) {
12269 var _this$responder23;
12270 this.event.preventDefault();
12271 (_this$responder23 = this.responder) === null || _this$responder23 === void 0 || _this$responder23.decreaseNestingLevel();
12272 return this.render();
12273 }
12274 }
12275 });
12276 _defineProperty(Level2InputController, "inputTypes", {
12277 deleteByComposition() {
12278 return this.deleteInDirection("backward", {
12279 recordUndoEntry: false
12280 });
12281 },
12282 deleteByCut() {
12283 return this.deleteInDirection("backward");
12284 },
12285 deleteByDrag() {
12286 this.event.preventDefault();
12287 return this.withTargetDOMRange(function () {
12288 var _this$responder24;
12289 this.deleteByDragRange = (_this$responder24 = this.responder) === null || _this$responder24 === void 0 ? void 0 : _this$responder24.getSelectedRange();
12290 });
12291 },
12292 deleteCompositionText() {
12293 return this.deleteInDirection("backward", {
12294 recordUndoEntry: false
12295 });
12296 },
12297 deleteContent() {
12298 return this.deleteInDirection("backward");
12299 },
12300 deleteContentBackward() {
12301 return this.deleteInDirection("backward");
12302 },
12303 deleteContentForward() {
12304 return this.deleteInDirection("forward");
12305 },
12306 deleteEntireSoftLine() {
12307 return this.deleteInDirection("forward");
12308 },
12309 deleteHardLineBackward() {
12310 return this.deleteInDirection("backward");
12311 },
12312 deleteHardLineForward() {
12313 return this.deleteInDirection("forward");
12314 },
12315 deleteSoftLineBackward() {
12316 return this.deleteInDirection("backward");
12317 },
12318 deleteSoftLineForward() {
12319 return this.deleteInDirection("forward");
12320 },
12321 deleteWordBackward() {
12322 return this.deleteInDirection("backward");
12323 },
12324 deleteWordForward() {
12325 return this.deleteInDirection("forward");
12326 },
12327 formatBackColor() {
12328 return this.activateAttributeIfSupported("backgroundColor", this.event.data);
12329 },
12330 formatBold() {
12331 return this.toggleAttributeIfSupported("bold");
12332 },
12333 formatFontColor() {
12334 return this.activateAttributeIfSupported("color", this.event.data);
12335 },
12336 formatFontName() {
12337 return this.activateAttributeIfSupported("font", this.event.data);
12338 },
12339 formatIndent() {
12340 var _this$responder25;
12341 if ((_this$responder25 = this.responder) !== null && _this$responder25 !== void 0 && _this$responder25.canIncreaseNestingLevel()) {
12342 return this.withTargetDOMRange(function () {
12343 var _this$responder26;
12344 return (_this$responder26 = this.responder) === null || _this$responder26 === void 0 ? void 0 : _this$responder26.increaseNestingLevel();
12345 });
12346 }
12347 },
12348 formatItalic() {
12349 return this.toggleAttributeIfSupported("italic");
12350 },
12351 formatJustifyCenter() {
12352 return this.toggleAttributeIfSupported("justifyCenter");
12353 },
12354 formatJustifyFull() {
12355 return this.toggleAttributeIfSupported("justifyFull");
12356 },
12357 formatJustifyLeft() {
12358 return this.toggleAttributeIfSupported("justifyLeft");
12359 },
12360 formatJustifyRight() {
12361 return this.toggleAttributeIfSupported("justifyRight");
12362 },
12363 formatOutdent() {
12364 var _this$responder27;
12365 if ((_this$responder27 = this.responder) !== null && _this$responder27 !== void 0 && _this$responder27.canDecreaseNestingLevel()) {
12366 return this.withTargetDOMRange(function () {
12367 var _this$responder28;
12368 return (_this$responder28 = this.responder) === null || _this$responder28 === void 0 ? void 0 : _this$responder28.decreaseNestingLevel();
12369 });
12370 }
12371 },
12372 formatRemove() {
12373 this.withTargetDOMRange(function () {
12374 for (const attributeName in (_this$responder29 = this.responder) === null || _this$responder29 === void 0 ? void 0 : _this$responder29.getCurrentAttributes()) {
12375 var _this$responder29, _this$responder30;
12376 (_this$responder30 = this.responder) === null || _this$responder30 === void 0 || _this$responder30.removeCurrentAttribute(attributeName);
12377 }
12378 });
12379 },
12380 formatSetBlockTextDirection() {
12381 return this.activateAttributeIfSupported("blockDir", this.event.data);
12382 },
12383 formatSetInlineTextDirection() {
12384 return this.activateAttributeIfSupported("textDir", this.event.data);
12385 },
12386 formatStrikeThrough() {
12387 return this.toggleAttributeIfSupported("strike");
12388 },
12389 formatSubscript() {
12390 return this.toggleAttributeIfSupported("sub");
12391 },
12392 formatSuperscript() {
12393 return this.toggleAttributeIfSupported("sup");
12394 },
12395 formatUnderline() {
12396 return this.toggleAttributeIfSupported("underline");
12397 },
12398 historyRedo() {
12399 var _this$delegate15;
12400 return (_this$delegate15 = this.delegate) === null || _this$delegate15 === void 0 ? void 0 : _this$delegate15.inputControllerWillPerformRedo();
12401 },
12402 historyUndo() {
12403 var _this$delegate16;
12404 return (_this$delegate16 = this.delegate) === null || _this$delegate16 === void 0 ? void 0 : _this$delegate16.inputControllerWillPerformUndo();
12405 },
12406 insertCompositionText() {
12407 this.composing = true;
12408 return this.insertString(this.event.data);
12409 },
12410 insertFromComposition() {
12411 this.composing = false;
12412 return this.insertString(this.event.data);
12413 },
12414 insertFromDrop() {
12415 const range = this.deleteByDragRange;
12416 if (range) {
12417 var _this$delegate17;
12418 this.deleteByDragRange = null;
12419 (_this$delegate17 = this.delegate) === null || _this$delegate17 === void 0 || _this$delegate17.inputControllerWillMoveText();
12420 return this.withTargetDOMRange(function () {
12421 var _this$responder31;
12422 return (_this$responder31 = this.responder) === null || _this$responder31 === void 0 ? void 0 : _this$responder31.moveTextFromRange(range);
12423 });
12424 }
12425 },
12426 insertFromPaste() {
12427 const {
12428 dataTransfer
12429 } = this.event;
12430 const paste = {
12431 dataTransfer
12432 };
12433 const href = dataTransfer.getData("URL");
12434 const html = dataTransfer.getData("text/html");
12435 if (href) {
12436 var _this$delegate18;
12437 let string;
12438 this.event.preventDefault();
12439 paste.type = "text/html";
12440 const name = dataTransfer.getData("public.url-name");
12441 if (name) {
12442 string = squishBreakableWhitespace(name).trim();
12443 } else {
12444 string = href;
12445 }
12446 paste.html = this.createLinkHTML(href, string);
12447 (_this$delegate18 = this.delegate) === null || _this$delegate18 === void 0 || _this$delegate18.inputControllerWillPaste(paste);
12448 this.withTargetDOMRange(function () {
12449 var _this$responder32;
12450 return (_this$responder32 = this.responder) === null || _this$responder32 === void 0 ? void 0 : _this$responder32.insertHTML(paste.html);
12451 });
12452 this.afterRender = () => {
12453 var _this$delegate19;
12454 return (_this$delegate19 = this.delegate) === null || _this$delegate19 === void 0 ? void 0 : _this$delegate19.inputControllerDidPaste(paste);
12455 };
12456 } else if (dataTransferIsPlainText(dataTransfer)) {
12457 var _this$delegate20;
12458 paste.type = "text/plain";
12459 paste.string = dataTransfer.getData("text/plain");
12460 (_this$delegate20 = this.delegate) === null || _this$delegate20 === void 0 || _this$delegate20.inputControllerWillPaste(paste);
12461 this.withTargetDOMRange(function () {
12462 var _this$responder33;
12463 return (_this$responder33 = this.responder) === null || _this$responder33 === void 0 ? void 0 : _this$responder33.insertString(paste.string);
12464 });
12465 this.afterRender = () => {
12466 var _this$delegate21;
12467 return (_this$delegate21 = this.delegate) === null || _this$delegate21 === void 0 ? void 0 : _this$delegate21.inputControllerDidPaste(paste);
12468 };
12469 } else if (processableFilePaste(this.event)) {
12470 var _this$delegate22;
12471 paste.type = "File";
12472 paste.file = dataTransfer.files[0];
12473 (_this$delegate22 = this.delegate) === null || _this$delegate22 === void 0 || _this$delegate22.inputControllerWillPaste(paste);
12474 this.withTargetDOMRange(function () {
12475 var _this$responder34;
12476 return (_this$responder34 = this.responder) === null || _this$responder34 === void 0 ? void 0 : _this$responder34.insertFile(paste.file);
12477 });
12478 this.afterRender = () => {
12479 var _this$delegate23;
12480 return (_this$delegate23 = this.delegate) === null || _this$delegate23 === void 0 ? void 0 : _this$delegate23.inputControllerDidPaste(paste);
12481 };
12482 } else if (html) {
12483 var _this$delegate24;
12484 this.event.preventDefault();
12485 paste.type = "text/html";
12486 paste.html = html;
12487 (_this$delegate24 = this.delegate) === null || _this$delegate24 === void 0 || _this$delegate24.inputControllerWillPaste(paste);
12488 this.withTargetDOMRange(function () {
12489 var _this$responder35;
12490 return (_this$responder35 = this.responder) === null || _this$responder35 === void 0 ? void 0 : _this$responder35.insertHTML(paste.html);
12491 });
12492 this.afterRender = () => {
12493 var _this$delegate25;
12494 return (_this$delegate25 = this.delegate) === null || _this$delegate25 === void 0 ? void 0 : _this$delegate25.inputControllerDidPaste(paste);
12495 };
12496 }
12497 },
12498 insertFromYank() {
12499 return this.insertString(this.event.data);
12500 },
12501 insertLineBreak() {
12502 return this.insertString("\n");
12503 },
12504 insertLink() {
12505 return this.activateAttributeIfSupported("href", this.event.data);
12506 },
12507 insertOrderedList() {
12508 return this.toggleAttributeIfSupported("number");
12509 },
12510 insertParagraph() {
12511 var _this$delegate26;
12512 (_this$delegate26 = this.delegate) === null || _this$delegate26 === void 0 || _this$delegate26.inputControllerWillPerformTyping();
12513 return this.withTargetDOMRange(function () {
12514 var _this$responder36;
12515 return (_this$responder36 = this.responder) === null || _this$responder36 === void 0 ? void 0 : _this$responder36.insertLineBreak();
12516 });
12517 },
12518 insertReplacementText() {
12519 const replacement = this.event.dataTransfer.getData("text/plain");
12520 const domRange = this.event.getTargetRanges()[0];
12521 this.withTargetDOMRange(domRange, () => {
12522 this.insertString(replacement, {
12523 updatePosition: false
12524 });
12525 });
12526 },
12527 insertText() {
12528 var _this$event$dataTrans;
12529 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")));
12530 },
12531 insertTranspose() {
12532 return this.insertString(this.event.data);
12533 },
12534 insertUnorderedList() {
12535 return this.toggleAttributeIfSupported("bullet");
12536 }
12537 });
12538 const staticRangeToRange = function (staticRange) {
12539 const range = document.createRange();
12540 range.setStart(staticRange.startContainer, staticRange.startOffset);
12541 range.setEnd(staticRange.endContainer, staticRange.endOffset);
12542 return range;
12543 };
12544
12545 // Event helpers
12546
12547 const dragEventHasFiles = event => {
12548 var _event$dataTransfer;
12549 return Array.from(((_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.types) || []).includes("Files");
12550 };
12551 const processableFilePaste = event => {
12552 var _event$dataTransfer$f;
12553 // Paste events that only have files are handled by the paste event handler,
12554 // to work around Safari not supporting beforeinput.insertFromPaste for files.
12555
12556 // MS Office text pastes include a file with a screenshot of the text, but we should
12557 // handle them as text pastes.
12558 return ((_event$dataTransfer$f = event.dataTransfer.files) === null || _event$dataTransfer$f === void 0 ? void 0 : _event$dataTransfer$f[0]) && !pasteEventHasFilesOnly(event) && !dataTransferIsMsOfficePaste(event);
12559 };
12560 const pasteEventHasFilesOnly = function (event) {
12561 const clipboard = event.clipboardData;
12562 if (clipboard) {
12563 const fileTypes = Array.from(clipboard.types).filter(type => type.match(/file/i)); // "Files", "application/x-moz-file"
12564 return fileTypes.length === clipboard.types.length && clipboard.files.length >= 1;
12565 }
12566 };
12567 const pasteEventHasPlainTextOnly = function (event) {
12568 const clipboard = event.clipboardData;
12569 if (clipboard) {
12570 return clipboard.types.includes("text/plain") && clipboard.types.length === 1;
12571 }
12572 };
12573 const keyboardCommandFromKeyEvent = function (event) {
12574 const command = [];
12575 if (event.altKey) {
12576 command.push("alt");
12577 }
12578 if (event.shiftKey) {
12579 command.push("shift");
12580 }
12581 command.push(event.key);
12582 return command;
12583 };
12584 const pointFromEvent = event => ({
12585 x: event.clientX,
12586 y: event.clientY
12587 });
12588
12589 const attributeButtonSelector = "[data-trix-attribute]";
12590 const actionButtonSelector = "[data-trix-action]";
12591 const toolbarButtonSelector = "".concat(attributeButtonSelector, ", ").concat(actionButtonSelector);
12592 const dialogSelector = "[data-trix-dialog]";
12593 const activeDialogSelector = "".concat(dialogSelector, "[data-trix-active]");
12594 const dialogButtonSelector = "".concat(dialogSelector, " [data-trix-method]");
12595 const dialogInputSelector = "".concat(dialogSelector, " [data-trix-input]");
12596 const getInputForDialog = (element, attributeName) => {
12597 if (!attributeName) {
12598 attributeName = getAttributeName(element);
12599 }
12600 return element.querySelector("[data-trix-input][name='".concat(attributeName, "']"));
12601 };
12602 const getActionName = element => element.getAttribute("data-trix-action");
12603 const getAttributeName = element => {
12604 return element.getAttribute("data-trix-attribute") || element.getAttribute("data-trix-dialog-attribute");
12605 };
12606 const getDialogName = element => element.getAttribute("data-trix-dialog");
12607 class ToolbarController extends BasicObject {
12608 constructor(element) {
12609 super(element);
12610 this.didClickActionButton = this.didClickActionButton.bind(this);
12611 this.didClickAttributeButton = this.didClickAttributeButton.bind(this);
12612 this.didClickDialogButton = this.didClickDialogButton.bind(this);
12613 this.didKeyDownDialogInput = this.didKeyDownDialogInput.bind(this);
12614 this.element = element;
12615 this.attributes = {};
12616 this.actions = {};
12617 this.resetDialogInputs();
12618 handleEvent("mousedown", {
12619 onElement: this.element,
12620 matchingSelector: actionButtonSelector,
12621 withCallback: this.didClickActionButton
12622 });
12623 handleEvent("mousedown", {
12624 onElement: this.element,
12625 matchingSelector: attributeButtonSelector,
12626 withCallback: this.didClickAttributeButton
12627 });
12628 handleEvent("click", {
12629 onElement: this.element,
12630 matchingSelector: toolbarButtonSelector,
12631 preventDefault: true
12632 });
12633 handleEvent("click", {
12634 onElement: this.element,
12635 matchingSelector: dialogButtonSelector,
12636 withCallback: this.didClickDialogButton
12637 });
12638 handleEvent("keydown", {
12639 onElement: this.element,
12640 matchingSelector: dialogInputSelector,
12641 withCallback: this.didKeyDownDialogInput
12642 });
12643 }
12644
12645 // Event handlers
12646
12647 didClickActionButton(event, element) {
12648 var _this$delegate;
12649 (_this$delegate = this.delegate) === null || _this$delegate === void 0 || _this$delegate.toolbarDidClickButton();
12650 event.preventDefault();
12651 const actionName = getActionName(element);
12652 if (this.getDialog(actionName)) {
12653 return this.toggleDialog(actionName);
12654 } else {
12655 var _this$delegate2;
12656 return (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 ? void 0 : _this$delegate2.toolbarDidInvokeAction(actionName, element);
12657 }
12658 }
12659 didClickAttributeButton(event, element) {
12660 var _this$delegate3;
12661 (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || _this$delegate3.toolbarDidClickButton();
12662 event.preventDefault();
12663 const attributeName = getAttributeName(element);
12664 if (this.getDialog(attributeName)) {
12665 this.toggleDialog(attributeName);
12666 } else {
12667 var _this$delegate4;
12668 (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.toolbarDidToggleAttribute(attributeName);
12669 }
12670 return this.refreshAttributeButtons();
12671 }
12672 didClickDialogButton(event, element) {
12673 const dialogElement = findClosestElementFromNode(element, {
12674 matchingSelector: dialogSelector
12675 });
12676 const method = element.getAttribute("data-trix-method");
12677 return this[method].call(this, dialogElement);
12678 }
12679 didKeyDownDialogInput(event, element) {
12680 if (event.keyCode === 13) {
12681 // Enter key
12682 event.preventDefault();
12683 const attribute = element.getAttribute("name");
12684 const dialog = this.getDialog(attribute);
12685 this.setAttribute(dialog);
12686 }
12687 if (event.keyCode === 27) {
12688 // Escape key
12689 event.preventDefault();
12690 return this.hideDialog();
12691 }
12692 }
12693
12694 // Action buttons
12695
12696 updateActions(actions) {
12697 this.actions = actions;
12698 return this.refreshActionButtons();
12699 }
12700 refreshActionButtons() {
12701 return this.eachActionButton((element, actionName) => {
12702 element.disabled = this.actions[actionName] === false;
12703 });
12704 }
12705 eachActionButton(callback) {
12706 return Array.from(this.element.querySelectorAll(actionButtonSelector)).map(element => callback(element, getActionName(element)));
12707 }
12708
12709 // Attribute buttons
12710
12711 updateAttributes(attributes) {
12712 this.attributes = attributes;
12713 return this.refreshAttributeButtons();
12714 }
12715 refreshAttributeButtons() {
12716 return this.eachAttributeButton((element, attributeName) => {
12717 element.disabled = this.attributes[attributeName] === false;
12718 if (this.attributes[attributeName] || this.dialogIsVisible(attributeName)) {
12719 element.setAttribute("data-trix-active", "");
12720 return element.classList.add("trix-active");
12721 } else {
12722 element.removeAttribute("data-trix-active");
12723 return element.classList.remove("trix-active");
12724 }
12725 });
12726 }
12727 eachAttributeButton(callback) {
12728 return Array.from(this.element.querySelectorAll(attributeButtonSelector)).map(element => callback(element, getAttributeName(element)));
12729 }
12730 applyKeyboardCommand(keys) {
12731 const keyString = JSON.stringify(keys.sort());
12732 for (const button of Array.from(this.element.querySelectorAll("[data-trix-key]"))) {
12733 const buttonKeys = button.getAttribute("data-trix-key").split("+");
12734 const buttonKeyString = JSON.stringify(buttonKeys.sort());
12735 if (buttonKeyString === keyString) {
12736 triggerEvent("mousedown", {
12737 onElement: button
12738 });
12739 return true;
12740 }
12741 }
12742 return false;
12743 }
12744
12745 // Dialogs
12746
12747 dialogIsVisible(dialogName) {
12748 const element = this.getDialog(dialogName);
12749 if (element) {
12750 return element.hasAttribute("data-trix-active");
12751 }
12752 }
12753 toggleDialog(dialogName) {
12754 if (this.dialogIsVisible(dialogName)) {
12755 return this.hideDialog();
12756 } else {
12757 return this.showDialog(dialogName);
12758 }
12759 }
12760 showDialog(dialogName) {
12761 var _this$delegate5, _this$delegate6;
12762 this.hideDialog();
12763 (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.toolbarWillShowDialog();
12764 const element = this.getDialog(dialogName);
12765 element.setAttribute("data-trix-active", "");
12766 element.classList.add("trix-active");
12767 Array.from(element.querySelectorAll("input[disabled]")).forEach(disabledInput => {
12768 disabledInput.removeAttribute("disabled");
12769 });
12770 const attributeName = getAttributeName(element);
12771 if (attributeName) {
12772 const input = getInputForDialog(element, dialogName);
12773 if (input) {
12774 input.value = this.attributes[attributeName] || "";
12775 input.select();
12776 }
12777 }
12778 return (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 ? void 0 : _this$delegate6.toolbarDidShowDialog(dialogName);
12779 }
12780 setAttribute(dialogElement) {
12781 var _this$delegate7;
12782 const attributeName = getAttributeName(dialogElement);
12783 const input = getInputForDialog(dialogElement, attributeName);
12784 if (input.willValidate) {
12785 input.setCustomValidity("");
12786 if (!input.checkValidity() || !this.isSafeAttribute(input)) {
12787 input.setCustomValidity("Invalid value");
12788 input.setAttribute("data-trix-validate", "");
12789 input.classList.add("trix-validate");
12790 return input.focus();
12791 }
12792 }
12793 (_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || _this$delegate7.toolbarDidUpdateAttribute(attributeName, input.value);
12794 return this.hideDialog();
12795 }
12796 isSafeAttribute(input) {
12797 if (input.hasAttribute("data-trix-validate-href")) {
12798 return purify.isValidAttribute("a", "href", input.value);
12799 } else {
12800 return true;
12801 }
12802 }
12803 removeAttribute(dialogElement) {
12804 var _this$delegate8;
12805 const attributeName = getAttributeName(dialogElement);
12806 (_this$delegate8 = this.delegate) === null || _this$delegate8 === void 0 || _this$delegate8.toolbarDidRemoveAttribute(attributeName);
12807 return this.hideDialog();
12808 }
12809 hideDialog() {
12810 const element = this.element.querySelector(activeDialogSelector);
12811 if (element) {
12812 var _this$delegate9;
12813 element.removeAttribute("data-trix-active");
12814 element.classList.remove("trix-active");
12815 this.resetDialogInputs();
12816 return (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 ? void 0 : _this$delegate9.toolbarDidHideDialog(getDialogName(element));
12817 }
12818 }
12819 resetDialogInputs() {
12820 Array.from(this.element.querySelectorAll(dialogInputSelector)).forEach(input => {
12821 input.setAttribute("disabled", "disabled");
12822 input.removeAttribute("data-trix-validate");
12823 input.classList.remove("trix-validate");
12824 });
12825 }
12826 getDialog(dialogName) {
12827 return this.element.querySelector("[data-trix-dialog=".concat(dialogName, "]"));
12828 }
12829 }
12830
12831 const snapshotsAreEqual = (a, b) => rangesAreEqual(a.selectedRange, b.selectedRange) && a.document.isEqualTo(b.document);
12832 class EditorController extends Controller {
12833 constructor(_ref) {
12834 let {
12835 editorElement,
12836 document,
12837 html
12838 } = _ref;
12839 super(...arguments);
12840 this.editorElement = editorElement;
12841 this.selectionManager = new SelectionManager(this.editorElement);
12842 this.selectionManager.delegate = this;
12843 this.composition = new Composition();
12844 this.composition.delegate = this;
12845 this.attachmentManager = new AttachmentManager(this.composition.getAttachments());
12846 this.attachmentManager.delegate = this;
12847 this.inputController = input.getLevel() === 2 ? new Level2InputController(this.editorElement) : new Level0InputController(this.editorElement);
12848 this.inputController.delegate = this;
12849 this.inputController.responder = this.composition;
12850 this.compositionController = new CompositionController(this.editorElement, this.composition);
12851 this.compositionController.delegate = this;
12852 this.toolbarController = new ToolbarController(this.editorElement.toolbarElement);
12853 this.toolbarController.delegate = this;
12854 this.editor = new Editor(this.composition, this.selectionManager, this.editorElement);
12855 if (document) {
12856 this.editor.loadDocument(document);
12857 } else {
12858 this.editor.loadHTML(html);
12859 }
12860 }
12861 registerSelectionManager() {
12862 return selectionChangeObserver.registerSelectionManager(this.selectionManager);
12863 }
12864 unregisterSelectionManager() {
12865 return selectionChangeObserver.unregisterSelectionManager(this.selectionManager);
12866 }
12867 render() {
12868 return this.compositionController.render();
12869 }
12870 reparse() {
12871 return this.composition.replaceHTML(this.editorElement.innerHTML);
12872 }
12873
12874 // Composition delegate
12875
12876 compositionDidChangeDocument(document) {
12877 this.notifyEditorElement("document-change");
12878 if (!this.handlingInput) {
12879 return this.render();
12880 }
12881 }
12882 compositionDidChangeCurrentAttributes(currentAttributes) {
12883 this.currentAttributes = currentAttributes;
12884 this.toolbarController.updateAttributes(this.currentAttributes);
12885 this.updateCurrentActions();
12886 return this.notifyEditorElement("attributes-change", {
12887 attributes: this.currentAttributes
12888 });
12889 }
12890 compositionDidPerformInsertionAtRange(range) {
12891 if (this.pasting) {
12892 this.pastedRange = range;
12893 }
12894 }
12895 compositionShouldAcceptFile(file) {
12896 return this.notifyEditorElement("file-accept", {
12897 file
12898 });
12899 }
12900 compositionDidAddAttachment(attachment) {
12901 const managedAttachment = this.attachmentManager.manageAttachment(attachment);
12902 return this.notifyEditorElement("attachment-add", {
12903 attachment: managedAttachment
12904 });
12905 }
12906 compositionDidEditAttachment(attachment) {
12907 this.compositionController.rerenderViewForObject(attachment);
12908 const managedAttachment = this.attachmentManager.manageAttachment(attachment);
12909 this.notifyEditorElement("attachment-edit", {
12910 attachment: managedAttachment
12911 });
12912 return this.notifyEditorElement("change");
12913 }
12914 compositionDidChangeAttachmentPreviewURL(attachment) {
12915 this.compositionController.invalidateViewForObject(attachment);
12916 return this.notifyEditorElement("change");
12917 }
12918 compositionDidRemoveAttachment(attachment) {
12919 const managedAttachment = this.attachmentManager.unmanageAttachment(attachment);
12920 return this.notifyEditorElement("attachment-remove", {
12921 attachment: managedAttachment
12922 });
12923 }
12924 compositionDidStartEditingAttachment(attachment, options) {
12925 this.attachmentLocationRange = this.composition.document.getLocationRangeOfAttachment(attachment);
12926 this.compositionController.installAttachmentEditorForAttachment(attachment, options);
12927 return this.selectionManager.setLocationRange(this.attachmentLocationRange);
12928 }
12929 compositionDidStopEditingAttachment(attachment) {
12930 this.compositionController.uninstallAttachmentEditor();
12931 this.attachmentLocationRange = null;
12932 }
12933 compositionDidRequestChangingSelectionToLocationRange(locationRange) {
12934 if (this.loadingSnapshot && !this.isFocused()) return;
12935 this.requestedLocationRange = locationRange;
12936 this.compositionRevisionWhenLocationRangeRequested = this.composition.revision;
12937 if (!this.handlingInput) {
12938 return this.render();
12939 }
12940 }
12941 compositionWillLoadSnapshot() {
12942 this.loadingSnapshot = true;
12943 }
12944 compositionDidLoadSnapshot() {
12945 this.compositionController.refreshViewCache();
12946 this.render();
12947 this.loadingSnapshot = false;
12948 }
12949 getSelectionManager() {
12950 return this.selectionManager;
12951 }
12952
12953 // Attachment manager delegate
12954
12955 attachmentManagerDidRequestRemovalOfAttachment(attachment) {
12956 return this.removeAttachment(attachment);
12957 }
12958
12959 // Document controller delegate
12960
12961 compositionControllerWillSyncDocumentView() {
12962 this.inputController.editorWillSyncDocumentView();
12963 this.selectionManager.lock();
12964 return this.selectionManager.clearSelection();
12965 }
12966 compositionControllerDidSyncDocumentView() {
12967 this.inputController.editorDidSyncDocumentView();
12968 this.selectionManager.unlock();
12969 this.updateCurrentActions();
12970 return this.notifyEditorElement("sync");
12971 }
12972 compositionControllerDidRender() {
12973 if (this.requestedLocationRange) {
12974 if (this.compositionRevisionWhenLocationRangeRequested === this.composition.revision) {
12975 this.selectionManager.setLocationRange(this.requestedLocationRange);
12976 }
12977 this.requestedLocationRange = null;
12978 this.compositionRevisionWhenLocationRangeRequested = null;
12979 }
12980 if (this.renderedCompositionRevision !== this.composition.revision) {
12981 this.runEditorFilters();
12982 this.composition.updateCurrentAttributes();
12983 this.notifyEditorElement("render");
12984 }
12985 this.renderedCompositionRevision = this.composition.revision;
12986 }
12987 compositionControllerDidFocus() {
12988 if (this.isFocusedInvisibly()) {
12989 this.setLocationRange({
12990 index: 0,
12991 offset: 0
12992 });
12993 }
12994 this.toolbarController.hideDialog();
12995 return this.notifyEditorElement("focus");
12996 }
12997 compositionControllerDidBlur() {
12998 return this.notifyEditorElement("blur");
12999 }
13000 compositionControllerDidSelectAttachment(attachment, options) {
13001 this.toolbarController.hideDialog();
13002 return this.composition.editAttachment(attachment, options);
13003 }
13004 compositionControllerDidRequestDeselectingAttachment(attachment) {
13005 const locationRange = this.attachmentLocationRange || this.composition.document.getLocationRangeOfAttachment(attachment);
13006 return this.selectionManager.setLocationRange(locationRange[1]);
13007 }
13008 compositionControllerWillUpdateAttachment(attachment) {
13009 return this.editor.recordUndoEntry("Edit Attachment", {
13010 context: attachment.id,
13011 consolidatable: true
13012 });
13013 }
13014 compositionControllerDidRequestRemovalOfAttachment(attachment) {
13015 return this.removeAttachment(attachment);
13016 }
13017
13018 // Input controller delegate
13019
13020 inputControllerWillHandleInput() {
13021 this.handlingInput = true;
13022 this.requestedRender = false;
13023 }
13024 inputControllerDidRequestRender() {
13025 this.requestedRender = true;
13026 }
13027 inputControllerDidHandleInput() {
13028 this.handlingInput = false;
13029 if (this.requestedRender) {
13030 this.requestedRender = false;
13031 return this.render();
13032 }
13033 }
13034 inputControllerDidAllowUnhandledInput() {
13035 return this.notifyEditorElement("change");
13036 }
13037 inputControllerDidRequestReparse() {
13038 return this.reparse();
13039 }
13040 inputControllerWillPerformTyping() {
13041 return this.recordTypingUndoEntry();
13042 }
13043 inputControllerWillPerformFormatting(attributeName) {
13044 return this.recordFormattingUndoEntry(attributeName);
13045 }
13046 inputControllerWillCutText() {
13047 return this.editor.recordUndoEntry("Cut");
13048 }
13049 inputControllerWillPaste(paste) {
13050 this.editor.recordUndoEntry("Paste");
13051 this.pasting = true;
13052 return this.notifyEditorElement("before-paste", {
13053 paste
13054 });
13055 }
13056 inputControllerDidPaste(paste) {
13057 paste.range = this.pastedRange;
13058 this.pastedRange = null;
13059 this.pasting = null;
13060 return this.notifyEditorElement("paste", {
13061 paste
13062 });
13063 }
13064 inputControllerWillMoveText() {
13065 return this.editor.recordUndoEntry("Move");
13066 }
13067 inputControllerWillAttachFiles() {
13068 return this.editor.recordUndoEntry("Drop Files");
13069 }
13070 inputControllerWillPerformUndo() {
13071 return this.editor.undo();
13072 }
13073 inputControllerWillPerformRedo() {
13074 return this.editor.redo();
13075 }
13076 inputControllerDidReceiveKeyboardCommand(keys) {
13077 return this.toolbarController.applyKeyboardCommand(keys);
13078 }
13079 inputControllerDidStartDrag() {
13080 this.locationRangeBeforeDrag = this.selectionManager.getLocationRange();
13081 }
13082 inputControllerDidReceiveDragOverPoint(point) {
13083 return this.selectionManager.setLocationRangeFromPointRange(point);
13084 }
13085 inputControllerDidCancelDrag() {
13086 this.selectionManager.setLocationRange(this.locationRangeBeforeDrag);
13087 this.locationRangeBeforeDrag = null;
13088 }
13089
13090 // Selection manager delegate
13091
13092 locationRangeDidChange(locationRange) {
13093 this.composition.updateCurrentAttributes();
13094 this.updateCurrentActions();
13095 if (this.attachmentLocationRange && !rangesAreEqual(this.attachmentLocationRange, locationRange)) {
13096 this.composition.stopEditingAttachment();
13097 }
13098 return this.notifyEditorElement("selection-change");
13099 }
13100
13101 // Toolbar controller delegate
13102
13103 toolbarDidClickButton() {
13104 if (!this.getLocationRange()) {
13105 return this.setLocationRange({
13106 index: 0,
13107 offset: 0
13108 });
13109 }
13110 }
13111 toolbarDidInvokeAction(actionName, invokingElement) {
13112 return this.invokeAction(actionName, invokingElement);
13113 }
13114 toolbarDidToggleAttribute(attributeName) {
13115 this.recordFormattingUndoEntry(attributeName);
13116 this.composition.toggleCurrentAttribute(attributeName);
13117 this.render();
13118 if (!this.selectionFrozen) {
13119 return this.editorElement.focus();
13120 }
13121 }
13122 toolbarDidUpdateAttribute(attributeName, value) {
13123 this.recordFormattingUndoEntry(attributeName);
13124 this.composition.setCurrentAttribute(attributeName, value);
13125 this.render();
13126 if (!this.selectionFrozen) {
13127 return this.editorElement.focus();
13128 }
13129 }
13130 toolbarDidRemoveAttribute(attributeName) {
13131 this.recordFormattingUndoEntry(attributeName);
13132 this.composition.removeCurrentAttribute(attributeName);
13133 this.render();
13134 if (!this.selectionFrozen) {
13135 return this.editorElement.focus();
13136 }
13137 }
13138 toolbarWillShowDialog(dialogElement) {
13139 this.composition.expandSelectionForEditing();
13140 return this.freezeSelection();
13141 }
13142 toolbarDidShowDialog(dialogName) {
13143 return this.notifyEditorElement("toolbar-dialog-show", {
13144 dialogName
13145 });
13146 }
13147 toolbarDidHideDialog(dialogName) {
13148 this.thawSelection();
13149 this.editorElement.focus();
13150 return this.notifyEditorElement("toolbar-dialog-hide", {
13151 dialogName
13152 });
13153 }
13154
13155 // Selection
13156
13157 freezeSelection() {
13158 if (!this.selectionFrozen) {
13159 this.selectionManager.lock();
13160 this.composition.freezeSelection();
13161 this.selectionFrozen = true;
13162 return this.render();
13163 }
13164 }
13165 thawSelection() {
13166 if (this.selectionFrozen) {
13167 this.composition.thawSelection();
13168 this.selectionManager.unlock();
13169 this.selectionFrozen = false;
13170 return this.render();
13171 }
13172 }
13173 canInvokeAction(actionName) {
13174 if (this.actionIsExternal(actionName)) {
13175 return true;
13176 } else {
13177 var _this$actions$actionN;
13178 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));
13179 }
13180 }
13181 invokeAction(actionName, invokingElement) {
13182 if (this.actionIsExternal(actionName)) {
13183 return this.notifyEditorElement("action-invoke", {
13184 actionName,
13185 invokingElement
13186 });
13187 } else {
13188 var _this$actions$actionN2;
13189 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);
13190 }
13191 }
13192 actionIsExternal(actionName) {
13193 return /^x-./.test(actionName);
13194 }
13195 getCurrentActions() {
13196 const result = {};
13197 for (const actionName in this.actions) {
13198 result[actionName] = this.canInvokeAction(actionName);
13199 }
13200 return result;
13201 }
13202 updateCurrentActions() {
13203 const currentActions = this.getCurrentActions();
13204 if (!objectsAreEqual(currentActions, this.currentActions)) {
13205 this.currentActions = currentActions;
13206 this.toolbarController.updateActions(this.currentActions);
13207 return this.notifyEditorElement("actions-change", {
13208 actions: this.currentActions
13209 });
13210 }
13211 }
13212
13213 // Editor filters
13214
13215 runEditorFilters() {
13216 let snapshot = this.composition.getSnapshot();
13217 Array.from(this.editor.filters).forEach(filter => {
13218 const {
13219 document,
13220 selectedRange
13221 } = snapshot;
13222 snapshot = filter.call(this.editor, snapshot) || {};
13223 if (!snapshot.document) {
13224 snapshot.document = document;
13225 }
13226 if (!snapshot.selectedRange) {
13227 snapshot.selectedRange = selectedRange;
13228 }
13229 });
13230 if (!snapshotsAreEqual(snapshot, this.composition.getSnapshot())) {
13231 return this.composition.loadSnapshot(snapshot);
13232 }
13233 }
13234
13235 // Private
13236
13237 updateInputElement() {
13238 const element = this.compositionController.getSerializableElement();
13239 const value = serializeToContentType(element, "text/html");
13240 return this.editorElement.setFormValue(value);
13241 }
13242 notifyEditorElement(message, data) {
13243 switch (message) {
13244 case "document-change":
13245 this.documentChangedSinceLastRender = true;
13246 break;
13247 case "render":
13248 if (this.documentChangedSinceLastRender) {
13249 this.documentChangedSinceLastRender = false;
13250 this.notifyEditorElement("change");
13251 }
13252 break;
13253 case "change":
13254 case "attachment-add":
13255 case "attachment-edit":
13256 case "attachment-remove":
13257 this.updateInputElement();
13258 break;
13259 }
13260 return this.editorElement.notify(message, data);
13261 }
13262 removeAttachment(attachment) {
13263 this.editor.recordUndoEntry("Delete Attachment");
13264 this.composition.removeAttachment(attachment);
13265 return this.render();
13266 }
13267 recordFormattingUndoEntry(attributeName) {
13268 const blockConfig = getBlockConfig(attributeName);
13269 const locationRange = this.selectionManager.getLocationRange();
13270 if (blockConfig || !rangeIsCollapsed(locationRange)) {
13271 return this.editor.recordUndoEntry("Formatting", {
13272 context: this.getUndoContext(),
13273 consolidatable: true
13274 });
13275 }
13276 }
13277 recordTypingUndoEntry() {
13278 return this.editor.recordUndoEntry("Typing", {
13279 context: this.getUndoContext(this.currentAttributes),
13280 consolidatable: true
13281 });
13282 }
13283 getUndoContext() {
13284 for (var _len = arguments.length, context = new Array(_len), _key = 0; _key < _len; _key++) {
13285 context[_key] = arguments[_key];
13286 }
13287 return [this.getLocationContext(), this.getTimeContext(), ...Array.from(context)];
13288 }
13289 getLocationContext() {
13290 const locationRange = this.selectionManager.getLocationRange();
13291 if (rangeIsCollapsed(locationRange)) {
13292 return locationRange[0].index;
13293 } else {
13294 return locationRange;
13295 }
13296 }
13297 getTimeContext() {
13298 if (undo.interval > 0) {
13299 return Math.floor(new Date().getTime() / undo.interval);
13300 } else {
13301 return 0;
13302 }
13303 }
13304 isFocused() {
13305 var _this$editorElement$o;
13306 return this.editorElement === ((_this$editorElement$o = this.editorElement.ownerDocument) === null || _this$editorElement$o === void 0 ? void 0 : _this$editorElement$o.activeElement);
13307 }
13308
13309 // Detect "Cursor disappears sporadically" Firefox bug.
13310 // - https://bugzilla.mozilla.org/show_bug.cgi?id=226301
13311 isFocusedInvisibly() {
13312 return this.isFocused() && !this.getLocationRange();
13313 }
13314 get actions() {
13315 return this.constructor.actions;
13316 }
13317 }
13318 _defineProperty(EditorController, "actions", {
13319 undo: {
13320 test() {
13321 return this.editor.canUndo();
13322 },
13323 perform() {
13324 return this.editor.undo();
13325 }
13326 },
13327 redo: {
13328 test() {
13329 return this.editor.canRedo();
13330 },
13331 perform() {
13332 return this.editor.redo();
13333 }
13334 },
13335 link: {
13336 test() {
13337 return this.editor.canActivateAttribute("href");
13338 }
13339 },
13340 increaseNestingLevel: {
13341 test() {
13342 return this.editor.canIncreaseNestingLevel();
13343 },
13344 perform() {
13345 return this.editor.increaseNestingLevel() && this.render();
13346 }
13347 },
13348 decreaseNestingLevel: {
13349 test() {
13350 return this.editor.canDecreaseNestingLevel();
13351 },
13352 perform() {
13353 return this.editor.decreaseNestingLevel() && this.render();
13354 }
13355 },
13356 attachFiles: {
13357 test() {
13358 return true;
13359 },
13360 perform() {
13361 return input.pickFiles(this.editor.insertFiles);
13362 }
13363 }
13364 });
13365 EditorController.proxyMethod("getSelectionManager().setLocationRange");
13366 EditorController.proxyMethod("getSelectionManager().getLocationRange");
13367
13368 var controllers = /*#__PURE__*/Object.freeze({
13369 __proto__: null,
13370 AttachmentEditorController: AttachmentEditorController,
13371 CompositionController: CompositionController,
13372 Controller: Controller,
13373 EditorController: EditorController,
13374 InputController: InputController,
13375 Level0InputController: Level0InputController,
13376 Level2InputController: Level2InputController,
13377 ToolbarController: ToolbarController
13378 });
13379
13380 var observers = /*#__PURE__*/Object.freeze({
13381 __proto__: null,
13382 MutationObserver: MutationObserver,
13383 SelectionChangeObserver: SelectionChangeObserver
13384 });
13385
13386 var operations = /*#__PURE__*/Object.freeze({
13387 __proto__: null,
13388 FileVerificationOperation: FileVerificationOperation,
13389 ImagePreloadOperation: ImagePreloadOperation
13390 });
13391
13392 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}");
13393 class TrixToolbarElement extends HTMLElement {
13394 // Element lifecycle
13395
13396 connectedCallback() {
13397 if (this.innerHTML === "") {
13398 this.innerHTML = toolbar.getDefaultHTML();
13399 }
13400 }
13401
13402 // Properties
13403
13404 get editorElements() {
13405 if (this.id) {
13406 var _this$ownerDocument;
13407 const nodeList = (_this$ownerDocument = this.ownerDocument) === null || _this$ownerDocument === void 0 ? void 0 : _this$ownerDocument.querySelectorAll("trix-editor[toolbar=\"".concat(this.id, "\"]"));
13408 return Array.from(nodeList);
13409 } else {
13410 return [];
13411 }
13412 }
13413 get editorElement() {
13414 const [editorElement] = this.editorElements;
13415 return editorElement;
13416 }
13417 }
13418
13419 let id = 0;
13420
13421 // Contenteditable support helpers
13422
13423 const autofocus = function (element) {
13424 if (!document.querySelector(":focus")) {
13425 if (element.hasAttribute("autofocus") && document.querySelector("[autofocus]") === element) {
13426 return element.focus();
13427 }
13428 }
13429 };
13430 const makeEditable = function (element) {
13431 if (element.hasAttribute("contenteditable")) {
13432 return;
13433 }
13434 element.toggleAttribute("contenteditable", !element.disabled);
13435 return handleEventOnce("focus", {
13436 onElement: element,
13437 withCallback() {
13438 return configureContentEditable(element);
13439 }
13440 });
13441 };
13442 const configureContentEditable = function (element) {
13443 disableObjectResizing(element);
13444 return setDefaultParagraphSeparator(element);
13445 };
13446 const disableObjectResizing = function (element) {
13447 var _document$queryComman, _document;
13448 if ((_document$queryComman = (_document = document).queryCommandSupported) !== null && _document$queryComman !== void 0 && _document$queryComman.call(_document, "enableObjectResizing")) {
13449 document.execCommand("enableObjectResizing", false, false);
13450 return handleEvent("mscontrolselect", {
13451 onElement: element,
13452 preventDefault: true
13453 });
13454 }
13455 };
13456 const setDefaultParagraphSeparator = function (element) {
13457 var _document$queryComman2, _document2;
13458 if ((_document$queryComman2 = (_document2 = document).queryCommandSupported) !== null && _document$queryComman2 !== void 0 && _document$queryComman2.call(_document2, "DefaultParagraphSeparator")) {
13459 const {
13460 tagName
13461 } = attributes.default;
13462 if (["div", "p"].includes(tagName)) {
13463 return document.execCommand("DefaultParagraphSeparator", false, tagName);
13464 }
13465 }
13466 };
13467
13468 // Accessibility helpers
13469
13470 const addAccessibilityRole = function (element) {
13471 if (element.hasAttribute("role")) {
13472 return;
13473 }
13474 return element.setAttribute("role", "textbox");
13475 };
13476 const ensureAriaLabel = function (element) {
13477 if (element.hasAttribute("aria-label") || element.hasAttribute("aria-labelledby")) {
13478 return;
13479 }
13480 const update = function () {
13481 const texts = Array.from(element.labels).map(label => {
13482 if (!label.contains(element)) return label.textContent;
13483 }).filter(text => text);
13484 const text = texts.join(" ");
13485 if (text) {
13486 return element.setAttribute("aria-label", text);
13487 } else {
13488 return element.removeAttribute("aria-label");
13489 }
13490 };
13491 update();
13492 return handleEvent("focus", {
13493 onElement: element,
13494 withCallback: update
13495 });
13496 };
13497
13498 // Style
13499
13500 const cursorTargetStyles = function () {
13501 if (browser$1.forcesObjectResizing) {
13502 return {
13503 display: "inline",
13504 width: "auto"
13505 };
13506 } else {
13507 return {
13508 display: "inline-block",
13509 width: "1px"
13510 };
13511 }
13512 }();
13513 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}"));
13514 var _internals = /*#__PURE__*/new WeakMap();
13515 var _formDisabled = /*#__PURE__*/new WeakMap();
13516 var _validate = /*#__PURE__*/new WeakSet();
13517 class ElementInternalsDelegate {
13518 constructor(element) {
13519 _classPrivateMethodInitSpec(this, _validate);
13520 _defineProperty(this, "value", "");
13521 _classPrivateFieldInitSpec(this, _internals, {
13522 writable: true,
13523 value: void 0
13524 });
13525 _classPrivateFieldInitSpec(this, _formDisabled, {
13526 writable: true,
13527 value: void 0
13528 });
13529 this.element = element;
13530 _classPrivateFieldSet(this, _internals, element.attachInternals());
13531 _classPrivateFieldSet(this, _formDisabled, false);
13532 }
13533 connectedCallback() {
13534 _classPrivateMethodGet(this, _validate, _validate2).call(this);
13535 }
13536 disconnectedCallback() {}
13537 get form() {
13538 return _classPrivateFieldGet(this, _internals).form;
13539 }
13540 get name() {
13541 return this.element.getAttribute("name");
13542 }
13543 set name(value) {
13544 this.element.setAttribute("name", value);
13545 }
13546 get labels() {
13547 return _classPrivateFieldGet(this, _internals).labels;
13548 }
13549 get disabled() {
13550 return _classPrivateFieldGet(this, _formDisabled) || this.element.hasAttribute("disabled");
13551 }
13552 set disabled(value) {
13553 this.element.toggleAttribute("disabled", value);
13554 }
13555 get required() {
13556 return this.element.hasAttribute("required");
13557 }
13558 set required(value) {
13559 this.element.toggleAttribute("required", value);
13560 _classPrivateMethodGet(this, _validate, _validate2).call(this);
13561 }
13562 get validity() {
13563 return _classPrivateFieldGet(this, _internals).validity;
13564 }
13565 get validationMessage() {
13566 return _classPrivateFieldGet(this, _internals).validationMessage;
13567 }
13568 get willValidate() {
13569 return _classPrivateFieldGet(this, _internals).willValidate;
13570 }
13571 formDisabledCallback(disabled) {
13572 _classPrivateFieldSet(this, _formDisabled, disabled);
13573 }
13574 setFormValue(value) {
13575 this.value = value;
13576 _classPrivateMethodGet(this, _validate, _validate2).call(this);
13577 _classPrivateFieldGet(this, _internals).setFormValue(this.element.disabled ? undefined : this.value);
13578 }
13579 checkValidity() {
13580 return _classPrivateFieldGet(this, _internals).checkValidity();
13581 }
13582 reportValidity() {
13583 return _classPrivateFieldGet(this, _internals).reportValidity();
13584 }
13585 setCustomValidity(validationMessage) {
13586 _classPrivateMethodGet(this, _validate, _validate2).call(this, validationMessage);
13587 }
13588 }
13589 function _validate2() {
13590 let customValidationMessage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
13591 const {
13592 required,
13593 value
13594 } = this.element;
13595 const valueMissing = required && !value;
13596 const customError = !!customValidationMessage;
13597 const input = makeElement("input", {
13598 required
13599 });
13600 const validationMessage = customValidationMessage || input.validationMessage;
13601 _classPrivateFieldGet(this, _internals).setValidity({
13602 valueMissing,
13603 customError
13604 }, validationMessage);
13605 }
13606 var _focusHandler = /*#__PURE__*/new WeakMap();
13607 var _resetBubbled = /*#__PURE__*/new WeakMap();
13608 var _clickBubbled = /*#__PURE__*/new WeakMap();
13609 class LegacyDelegate {
13610 constructor(element) {
13611 _classPrivateFieldInitSpec(this, _focusHandler, {
13612 writable: true,
13613 value: void 0
13614 });
13615 _classPrivateFieldInitSpec(this, _resetBubbled, {
13616 writable: true,
13617 value: event => {
13618 if (event.defaultPrevented) return;
13619 if (event.target !== this.element.form) return;
13620 this.element.reset();
13621 }
13622 });
13623 _classPrivateFieldInitSpec(this, _clickBubbled, {
13624 writable: true,
13625 value: event => {
13626 if (event.defaultPrevented) return;
13627 if (this.element.contains(event.target)) return;
13628 const label = findClosestElementFromNode(event.target, {
13629 matchingSelector: "label"
13630 });
13631 if (!label) return;
13632 if (!Array.from(this.labels).includes(label)) return;
13633 this.element.focus();
13634 }
13635 });
13636 this.element = element;
13637 }
13638 connectedCallback() {
13639 _classPrivateFieldSet(this, _focusHandler, ensureAriaLabel(this.element));
13640 window.addEventListener("reset", _classPrivateFieldGet(this, _resetBubbled), false);
13641 window.addEventListener("click", _classPrivateFieldGet(this, _clickBubbled), false);
13642 }
13643 disconnectedCallback() {
13644 var _classPrivateFieldGet2;
13645 (_classPrivateFieldGet2 = _classPrivateFieldGet(this, _focusHandler)) === null || _classPrivateFieldGet2 === void 0 || _classPrivateFieldGet2.destroy();
13646 window.removeEventListener("reset", _classPrivateFieldGet(this, _resetBubbled), false);
13647 window.removeEventListener("click", _classPrivateFieldGet(this, _clickBubbled), false);
13648 }
13649 get labels() {
13650 const labels = [];
13651 if (this.element.id && this.element.ownerDocument) {
13652 labels.push(...Array.from(this.element.ownerDocument.querySelectorAll("label[for='".concat(this.element.id, "']")) || []));
13653 }
13654 const label = findClosestElementFromNode(this.element, {
13655 matchingSelector: "label"
13656 });
13657 if (label) {
13658 if ([this.element, null].includes(label.control)) {
13659 labels.push(label);
13660 }
13661 }
13662 return labels;
13663 }
13664 get form() {
13665 console.warn("This browser does not support the .form property for trix-editor elements.");
13666 return null;
13667 }
13668 get name() {
13669 console.warn("This browser does not support the .name property for trix-editor elements.");
13670 return null;
13671 }
13672 set name(value) {
13673 console.warn("This browser does not support the .name property for trix-editor elements.");
13674 }
13675 get disabled() {
13676 console.warn("This browser does not support the [disabled] attribute for trix-editor elements.");
13677 return false;
13678 }
13679 set disabled(value) {
13680 console.warn("This browser does not support the [disabled] attribute for trix-editor elements.");
13681 }
13682 get required() {
13683 console.warn("This browser does not support the [required] attribute for trix-editor elements.");
13684 return false;
13685 }
13686 set required(value) {
13687 console.warn("This browser does not support the [required] attribute for trix-editor elements.");
13688 }
13689 get validity() {
13690 console.warn("This browser does not support the validity property for trix-editor elements.");
13691 return null;
13692 }
13693 get validationMessage() {
13694 console.warn("This browser does not support the validationMessage property for trix-editor elements.");
13695 return "";
13696 }
13697 get willValidate() {
13698 console.warn("This browser does not support the willValidate property for trix-editor elements.");
13699 return false;
13700 }
13701 formDisabledCallback(value) {}
13702 setFormValue(value) {}
13703 checkValidity() {
13704 console.warn("This browser does not support checkValidity() for trix-editor elements.");
13705 return true;
13706 }
13707 reportValidity() {
13708 console.warn("This browser does not support reportValidity() for trix-editor elements.");
13709 return true;
13710 }
13711 setCustomValidity(validationMessage) {
13712 console.warn("This browser does not support setCustomValidity(validationMessage) for trix-editor elements.");
13713 }
13714 }
13715 var _delegate = /*#__PURE__*/new WeakMap();
13716 class TrixEditorElement extends HTMLElement {
13717 constructor() {
13718 super();
13719 _classPrivateFieldInitSpec(this, _delegate, {
13720 writable: true,
13721 value: void 0
13722 });
13723 this.willCreateInput = true;
13724 _classPrivateFieldSet(this, _delegate, this.constructor.formAssociated ? new ElementInternalsDelegate(this) : new LegacyDelegate(this));
13725 }
13726
13727 // Properties
13728
13729 get trixId() {
13730 if (this.hasAttribute("trix-id")) {
13731 return this.getAttribute("trix-id");
13732 } else {
13733 this.setAttribute("trix-id", ++id);
13734 return this.trixId;
13735 }
13736 }
13737 get labels() {
13738 return _classPrivateFieldGet(this, _delegate).labels;
13739 }
13740 get disabled() {
13741 const {
13742 inputElement
13743 } = this;
13744 if (inputElement) {
13745 return inputElement.disabled;
13746 } else {
13747 return _classPrivateFieldGet(this, _delegate).disabled;
13748 }
13749 }
13750 set disabled(value) {
13751 const {
13752 inputElement
13753 } = this;
13754 if (inputElement) {
13755 inputElement.disabled = value;
13756 }
13757 _classPrivateFieldGet(this, _delegate).disabled = value;
13758 }
13759 get required() {
13760 return _classPrivateFieldGet(this, _delegate).required;
13761 }
13762 set required(value) {
13763 _classPrivateFieldGet(this, _delegate).required = value;
13764 }
13765 get validity() {
13766 return _classPrivateFieldGet(this, _delegate).validity;
13767 }
13768 get validationMessage() {
13769 return _classPrivateFieldGet(this, _delegate).validationMessage;
13770 }
13771 get willValidate() {
13772 return _classPrivateFieldGet(this, _delegate).willValidate;
13773 }
13774 get type() {
13775 return this.localName;
13776 }
13777 get toolbarElement() {
13778 if (this.hasAttribute("toolbar")) {
13779 var _this$ownerDocument;
13780 return (_this$ownerDocument = this.ownerDocument) === null || _this$ownerDocument === void 0 ? void 0 : _this$ownerDocument.getElementById(this.getAttribute("toolbar"));
13781 } else if (this.parentNode) {
13782 const toolbarId = "trix-toolbar-".concat(this.trixId);
13783 this.setAttribute("toolbar", toolbarId);
13784 this.internalToolbar = makeElement("trix-toolbar", {
13785 id: toolbarId
13786 });
13787 this.parentNode.insertBefore(this.internalToolbar, this);
13788 return this.internalToolbar;
13789 } else {
13790 return undefined;
13791 }
13792 }
13793 get form() {
13794 const {
13795 inputElement
13796 } = this;
13797 if (inputElement) {
13798 return inputElement.form;
13799 } else {
13800 return _classPrivateFieldGet(this, _delegate).form;
13801 }
13802 }
13803 get inputElement() {
13804 if (this.hasAttribute("input")) {
13805 var _this$ownerDocument2;
13806 return (_this$ownerDocument2 = this.ownerDocument) === null || _this$ownerDocument2 === void 0 ? void 0 : _this$ownerDocument2.getElementById(this.getAttribute("input"));
13807 } else {
13808 return undefined;
13809 }
13810 }
13811 get editor() {
13812 var _this$editorControlle;
13813 return (_this$editorControlle = this.editorController) === null || _this$editorControlle === void 0 ? void 0 : _this$editorControlle.editor;
13814 }
13815 get name() {
13816 const {
13817 inputElement
13818 } = this;
13819 if (inputElement) {
13820 return inputElement.name;
13821 } else {
13822 return _classPrivateFieldGet(this, _delegate).name;
13823 }
13824 }
13825 set name(value) {
13826 const {
13827 inputElement
13828 } = this;
13829 if (inputElement) {
13830 inputElement.name = value;
13831 } else {
13832 _classPrivateFieldGet(this, _delegate).name = value;
13833 }
13834 }
13835 get value() {
13836 const {
13837 inputElement
13838 } = this;
13839 if (inputElement) {
13840 return inputElement.value;
13841 } else {
13842 return _classPrivateFieldGet(this, _delegate).value;
13843 }
13844 }
13845 set value(defaultValue) {
13846 var _this$editor;
13847 this.defaultValue = defaultValue;
13848 (_this$editor = this.editor) === null || _this$editor === void 0 || _this$editor.loadHTML(this.defaultValue);
13849 }
13850
13851 // Element callbacks
13852
13853 attributeChangedCallback(name, oldValue, newValue) {
13854 if (name === "connected" && this.isConnected && oldValue != null && oldValue !== newValue) {
13855 requestAnimationFrame(() => this.reconnect());
13856 }
13857 }
13858
13859 // Controller delegate methods
13860
13861 notify(message, data) {
13862 if (this.editorController) {
13863 return triggerEvent("trix-".concat(message), {
13864 onElement: this,
13865 attributes: data
13866 });
13867 }
13868 }
13869 setFormValue(value) {
13870 const {
13871 inputElement
13872 } = this;
13873 if (inputElement) {
13874 inputElement.value = value;
13875 }
13876 _classPrivateFieldGet(this, _delegate).setFormValue(value);
13877 }
13878
13879 // Element lifecycle
13880
13881 connectedCallback() {
13882 if (!this.hasAttribute("data-trix-internal")) {
13883 makeEditable(this);
13884 addAccessibilityRole(this);
13885 if (!this.editorController) {
13886 triggerEvent("trix-before-initialize", {
13887 onElement: this
13888 });
13889 this.defaultValue = this.inputElement ? this.inputElement.value : this.innerHTML;
13890 if (!this.hasAttribute("input") && this.parentNode && this.willCreateInput) {
13891 const inputId = "trix-input-".concat(this.trixId);
13892 this.setAttribute("input", inputId);
13893 const element = makeElement("input", {
13894 type: "hidden",
13895 id: inputId
13896 });
13897 this.parentNode.insertBefore(element, this.nextElementSibling);
13898 }
13899 this.editorController = new EditorController({
13900 editorElement: this,
13901 html: this.defaultValue
13902 });
13903 requestAnimationFrame(() => triggerEvent("trix-initialize", {
13904 onElement: this
13905 }));
13906 }
13907 this.editorController.registerSelectionManager();
13908 _classPrivateFieldGet(this, _delegate).connectedCallback();
13909 this.toggleAttribute("connected", true);
13910 autofocus(this);
13911 }
13912 }
13913 disconnectedCallback() {
13914 var _this$editorControlle2;
13915 (_this$editorControlle2 = this.editorController) === null || _this$editorControlle2 === void 0 || _this$editorControlle2.unregisterSelectionManager();
13916 _classPrivateFieldGet(this, _delegate).disconnectedCallback();
13917 this.toggleAttribute("connected", false);
13918 }
13919 reconnect() {
13920 this.removeInternalToolbar();
13921 this.disconnectedCallback();
13922 this.connectedCallback();
13923 }
13924 removeInternalToolbar() {
13925 var _this$internalToolbar;
13926 (_this$internalToolbar = this.internalToolbar) === null || _this$internalToolbar === void 0 || _this$internalToolbar.remove();
13927 this.internalToolbar = null;
13928 }
13929
13930 // Form support
13931
13932 checkValidity() {
13933 return _classPrivateFieldGet(this, _delegate).checkValidity();
13934 }
13935 reportValidity() {
13936 return _classPrivateFieldGet(this, _delegate).reportValidity();
13937 }
13938 setCustomValidity(validationMessage) {
13939 _classPrivateFieldGet(this, _delegate).setCustomValidity(validationMessage);
13940 }
13941 formDisabledCallback(disabled) {
13942 const {
13943 inputElement
13944 } = this;
13945 if (inputElement) {
13946 inputElement.disabled = disabled;
13947 }
13948 this.toggleAttribute("contenteditable", !disabled);
13949 _classPrivateFieldGet(this, _delegate).formDisabledCallback(disabled);
13950 }
13951 formResetCallback() {
13952 this.reset();
13953 }
13954 reset() {
13955 this.value = this.defaultValue;
13956 }
13957 }
13958 _defineProperty(TrixEditorElement, "formAssociated", "ElementInternals" in window);
13959 _defineProperty(TrixEditorElement, "observedAttributes", ["connected"]);
13960
13961 var elements = /*#__PURE__*/Object.freeze({
13962 __proto__: null,
13963 TrixEditorElement: TrixEditorElement,
13964 TrixToolbarElement: TrixToolbarElement
13965 });
13966
13967 var filters = /*#__PURE__*/Object.freeze({
13968 __proto__: null,
13969 Filter: Filter,
13970 attachmentGalleryFilter: attachmentGalleryFilter
13971 });
13972
13973 const Trix = {
13974 VERSION: version,
13975 config,
13976 core,
13977 models,
13978 views,
13979 controllers,
13980 observers,
13981 operations,
13982 elements,
13983 filters
13984 };
13985
13986 // Expose models under the Trix constant for compatibility with v1
13987 Object.assign(Trix, models);
13988 function start() {
13989 if (!customElements.get("trix-toolbar")) {
13990 customElements.define("trix-toolbar", TrixToolbarElement);
13991 }
13992 if (!customElements.get("trix-editor")) {
13993 customElements.define("trix-editor", TrixEditorElement);
13994 }
13995 }
13996 window.Trix = Trix;
13997 setTimeout(start, 0);
13998
13999 return Trix;
14000
14001}));