ぼざクリ タグ広場 https://hub.nizika.monster
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

13721 lines
501 KiB

  1. /*
  2. Trix 2.1.10
  3. Copyright © 2024 37signals, LLC
  4. */
  5. (function (global, factory) {
  6. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  7. typeof define === 'function' && define.amd ? define(factory) :
  8. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Trix = factory());
  9. })(this, (function () { 'use strict';
  10. var name = "trix";
  11. var version = "2.1.10";
  12. var description = "A rich text editor for everyday writing";
  13. var main = "dist/trix.umd.min.js";
  14. var module = "dist/trix.esm.min.js";
  15. var style = "dist/trix.css";
  16. var files = [
  17. "dist/*.css",
  18. "dist/*.js",
  19. "dist/*.map",
  20. "src/{inspector,trix}/*.js"
  21. ];
  22. var repository = {
  23. type: "git",
  24. url: "git+https://github.com/basecamp/trix.git"
  25. };
  26. var keywords = [
  27. "rich text",
  28. "wysiwyg",
  29. "editor"
  30. ];
  31. var author = "37signals, LLC";
  32. var license = "MIT";
  33. var bugs = {
  34. url: "https://github.com/basecamp/trix/issues"
  35. };
  36. var homepage = "https://trix-editor.org/";
  37. var devDependencies = {
  38. "@babel/core": "^7.16.0",
  39. "@babel/preset-env": "^7.16.4",
  40. "@rollup/plugin-babel": "^5.3.0",
  41. "@rollup/plugin-commonjs": "^22.0.2",
  42. "@rollup/plugin-json": "^4.1.0",
  43. "@rollup/plugin-node-resolve": "^13.3.0",
  44. "@web/dev-server": "^0.1.34",
  45. "babel-eslint": "^10.1.0",
  46. concurrently: "^7.4.0",
  47. eslint: "^7.32.0",
  48. esm: "^3.2.25",
  49. karma: "6.4.1",
  50. "karma-chrome-launcher": "3.2.0",
  51. "karma-qunit": "^4.1.2",
  52. "karma-sauce-launcher": "^4.3.6",
  53. "node-sass": "^7.0.1",
  54. qunit: "2.19.1",
  55. rangy: "^1.3.0",
  56. rollup: "^2.56.3",
  57. "rollup-plugin-includepaths": "^0.2.4",
  58. "rollup-plugin-terser": "^7.0.2",
  59. svgo: "^2.8.0",
  60. webdriverio: "^7.19.5"
  61. };
  62. var resolutions = {
  63. webdriverio: "^7.19.5"
  64. };
  65. var scripts = {
  66. "build-css": "node-sass --functions=./assets/trix/stylesheets/functions assets/trix.scss dist/trix.css",
  67. "build-js": "rollup -c",
  68. "build-assets": "cp -f assets/*.html dist/",
  69. build: "yarn run build-js && yarn run build-css && yarn run build-assets",
  70. watch: "rollup -c -w",
  71. lint: "eslint .",
  72. pretest: "yarn run lint && yarn run build",
  73. test: "karma start",
  74. prerelease: "yarn version && yarn test",
  75. release: "npm adduser && npm publish",
  76. postrelease: "git push && git push --tags",
  77. dev: "web-dev-server --app-index index.html --root-dir dist --node-resolve --open",
  78. start: "yarn build-assets && concurrently --kill-others --names js,css,dev-server 'yarn watch' 'yarn build-css --watch' 'yarn dev'"
  79. };
  80. var dependencies = {
  81. dompurify: "^3.2.3"
  82. };
  83. var _package = {
  84. name: name,
  85. version: version,
  86. description: description,
  87. main: main,
  88. module: module,
  89. style: style,
  90. files: files,
  91. repository: repository,
  92. keywords: keywords,
  93. author: author,
  94. license: license,
  95. bugs: bugs,
  96. homepage: homepage,
  97. devDependencies: devDependencies,
  98. resolutions: resolutions,
  99. scripts: scripts,
  100. dependencies: dependencies
  101. };
  102. const attachmentSelector = "[data-trix-attachment]";
  103. const attachments = {
  104. preview: {
  105. presentation: "gallery",
  106. caption: {
  107. name: true,
  108. size: true
  109. }
  110. },
  111. file: {
  112. caption: {
  113. size: true
  114. }
  115. }
  116. };
  117. const attributes = {
  118. default: {
  119. tagName: "div",
  120. parse: false
  121. },
  122. quote: {
  123. tagName: "blockquote",
  124. nestable: true
  125. },
  126. heading1: {
  127. tagName: "h1",
  128. terminal: true,
  129. breakOnReturn: true,
  130. group: false
  131. },
  132. code: {
  133. tagName: "pre",
  134. terminal: true,
  135. htmlAttributes: ["language"],
  136. text: {
  137. plaintext: true
  138. }
  139. },
  140. bulletList: {
  141. tagName: "ul",
  142. parse: false
  143. },
  144. bullet: {
  145. tagName: "li",
  146. listAttribute: "bulletList",
  147. group: false,
  148. nestable: true,
  149. test(element) {
  150. return tagName$1(element.parentNode) === attributes[this.listAttribute].tagName;
  151. }
  152. },
  153. numberList: {
  154. tagName: "ol",
  155. parse: false
  156. },
  157. number: {
  158. tagName: "li",
  159. listAttribute: "numberList",
  160. group: false,
  161. nestable: true,
  162. test(element) {
  163. return tagName$1(element.parentNode) === attributes[this.listAttribute].tagName;
  164. }
  165. },
  166. attachmentGallery: {
  167. tagName: "div",
  168. exclusive: true,
  169. terminal: true,
  170. parse: false,
  171. group: false
  172. }
  173. };
  174. const tagName$1 = element => {
  175. var _element$tagName;
  176. return element === null || element === void 0 || (_element$tagName = element.tagName) === null || _element$tagName === void 0 ? void 0 : _element$tagName.toLowerCase();
  177. };
  178. const androidVersionMatch = navigator.userAgent.match(/android\s([0-9]+.*Chrome)/i);
  179. const androidVersion = androidVersionMatch && parseInt(androidVersionMatch[1]);
  180. var browser$1 = {
  181. // Android emits composition events when moving the cursor through existing text
  182. // Introduced in Chrome 65: https://bugs.chromium.org/p/chromium/issues/detail?id=764439#c9
  183. composesExistingText: /Android.*Chrome/.test(navigator.userAgent),
  184. // Android 13, especially on Samsung keyboards, emits extra compositionend and beforeinput events
  185. // that can make the input handler lose the current selection or enter an infinite input -> render -> input
  186. // loop.
  187. recentAndroid: androidVersion && androidVersion > 12,
  188. samsungAndroid: androidVersion && navigator.userAgent.match(/Android.*SM-/),
  189. // IE 11 activates resizing handles on editable elements that have "layout"
  190. forcesObjectResizing: /Trident.*rv:11/.test(navigator.userAgent),
  191. // https://www.w3.org/TR/input-events-1/ + https://www.w3.org/TR/input-events-2/
  192. supportsInputEvents: typeof InputEvent !== "undefined" && ["data", "getTargetRanges", "inputType"].every(prop => prop in InputEvent.prototype)
  193. };
  194. var css$3 = {
  195. attachment: "attachment",
  196. attachmentCaption: "attachment__caption",
  197. attachmentCaptionEditor: "attachment__caption-editor",
  198. attachmentMetadata: "attachment__metadata",
  199. attachmentMetadataContainer: "attachment__metadata-container",
  200. attachmentName: "attachment__name",
  201. attachmentProgress: "attachment__progress",
  202. attachmentSize: "attachment__size",
  203. attachmentToolbar: "attachment__toolbar",
  204. attachmentGallery: "attachment-gallery"
  205. };
  206. var lang$1 = {
  207. attachFiles: "Attach Files",
  208. bold: "Bold",
  209. bullets: "Bullets",
  210. byte: "Byte",
  211. bytes: "Bytes",
  212. captionPlaceholder: "Add a caption…",
  213. code: "Code",
  214. heading1: "Heading",
  215. indent: "Increase Level",
  216. italic: "Italic",
  217. link: "Link",
  218. numbers: "Numbers",
  219. outdent: "Decrease Level",
  220. quote: "Quote",
  221. redo: "Redo",
  222. remove: "Remove",
  223. strike: "Strikethrough",
  224. undo: "Undo",
  225. unlink: "Unlink",
  226. url: "URL",
  227. urlPlaceholder: "Enter a URL…",
  228. GB: "GB",
  229. KB: "KB",
  230. MB: "MB",
  231. PB: "PB",
  232. TB: "TB"
  233. };
  234. /* eslint-disable
  235. no-case-declarations,
  236. */
  237. const sizes = [lang$1.bytes, lang$1.KB, lang$1.MB, lang$1.GB, lang$1.TB, lang$1.PB];
  238. var file_size_formatting = {
  239. prefix: "IEC",
  240. precision: 2,
  241. formatter(number) {
  242. switch (number) {
  243. case 0:
  244. return "0 ".concat(lang$1.bytes);
  245. case 1:
  246. return "1 ".concat(lang$1.byte);
  247. default:
  248. let base;
  249. if (this.prefix === "SI") {
  250. base = 1000;
  251. } else if (this.prefix === "IEC") {
  252. base = 1024;
  253. }
  254. const exp = Math.floor(Math.log(number) / Math.log(base));
  255. const humanSize = number / Math.pow(base, exp);
  256. const string = humanSize.toFixed(this.precision);
  257. const withoutInsignificantZeros = string.replace(/0*$/, "").replace(/\.$/, "");
  258. return "".concat(withoutInsignificantZeros, " ").concat(sizes[exp]);
  259. }
  260. }
  261. };
  262. const ZERO_WIDTH_SPACE = "\uFEFF";
  263. const NON_BREAKING_SPACE = "\u00A0";
  264. const OBJECT_REPLACEMENT_CHARACTER = "\uFFFC";
  265. const extend = function (properties) {
  266. for (const key in properties) {
  267. const value = properties[key];
  268. this[key] = value;
  269. }
  270. return this;
  271. };
  272. const html$2 = document.documentElement;
  273. const match = html$2.matches;
  274. const handleEvent = function (eventName) {
  275. let {
  276. onElement,
  277. matchingSelector,
  278. withCallback,
  279. inPhase,
  280. preventDefault,
  281. times
  282. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  283. const element = onElement ? onElement : html$2;
  284. const selector = matchingSelector;
  285. const useCapture = inPhase === "capturing";
  286. const handler = function (event) {
  287. if (times != null && --times === 0) {
  288. handler.destroy();
  289. }
  290. const target = findClosestElementFromNode(event.target, {
  291. matchingSelector: selector
  292. });
  293. if (target != null) {
  294. withCallback === null || withCallback === void 0 || withCallback.call(target, event, target);
  295. if (preventDefault) {
  296. event.preventDefault();
  297. }
  298. }
  299. };
  300. handler.destroy = () => element.removeEventListener(eventName, handler, useCapture);
  301. element.addEventListener(eventName, handler, useCapture);
  302. return handler;
  303. };
  304. const handleEventOnce = function (eventName) {
  305. let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  306. options.times = 1;
  307. return handleEvent(eventName, options);
  308. };
  309. const triggerEvent = function (eventName) {
  310. let {
  311. onElement,
  312. bubbles,
  313. cancelable,
  314. attributes
  315. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  316. const element = onElement != null ? onElement : html$2;
  317. bubbles = bubbles !== false;
  318. cancelable = cancelable !== false;
  319. const event = document.createEvent("Events");
  320. event.initEvent(eventName, bubbles, cancelable);
  321. if (attributes != null) {
  322. extend.call(event, attributes);
  323. }
  324. return element.dispatchEvent(event);
  325. };
  326. const elementMatchesSelector = function (element, selector) {
  327. if ((element === null || element === void 0 ? void 0 : element.nodeType) === 1) {
  328. return match.call(element, selector);
  329. }
  330. };
  331. const findClosestElementFromNode = function (node) {
  332. let {
  333. matchingSelector,
  334. untilNode
  335. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  336. while (node && node.nodeType !== Node.ELEMENT_NODE) {
  337. node = node.parentNode;
  338. }
  339. if (node == null) {
  340. return;
  341. }
  342. if (matchingSelector != null) {
  343. if (node.closest && untilNode == null) {
  344. return node.closest(matchingSelector);
  345. } else {
  346. while (node && node !== untilNode) {
  347. if (elementMatchesSelector(node, matchingSelector)) {
  348. return node;
  349. }
  350. node = node.parentNode;
  351. }
  352. }
  353. } else {
  354. return node;
  355. }
  356. };
  357. const findInnerElement = function (element) {
  358. while ((_element = element) !== null && _element !== void 0 && _element.firstElementChild) {
  359. var _element;
  360. element = element.firstElementChild;
  361. }
  362. return element;
  363. };
  364. const innerElementIsActive = element => document.activeElement !== element && elementContainsNode(element, document.activeElement);
  365. const elementContainsNode = function (element, node) {
  366. if (!element || !node) {
  367. return;
  368. }
  369. while (node) {
  370. if (node === element) {
  371. return true;
  372. }
  373. node = node.parentNode;
  374. }
  375. };
  376. const findNodeFromContainerAndOffset = function (container, offset) {
  377. if (!container) {
  378. return;
  379. }
  380. if (container.nodeType === Node.TEXT_NODE) {
  381. return container;
  382. } else if (offset === 0) {
  383. return container.firstChild != null ? container.firstChild : container;
  384. } else {
  385. return container.childNodes.item(offset - 1);
  386. }
  387. };
  388. const findElementFromContainerAndOffset = function (container, offset) {
  389. const node = findNodeFromContainerAndOffset(container, offset);
  390. return findClosestElementFromNode(node);
  391. };
  392. const findChildIndexOfNode = function (node) {
  393. var _node;
  394. if (!((_node = node) !== null && _node !== void 0 && _node.parentNode)) {
  395. return;
  396. }
  397. let childIndex = 0;
  398. node = node.previousSibling;
  399. while (node) {
  400. childIndex++;
  401. node = node.previousSibling;
  402. }
  403. return childIndex;
  404. };
  405. const removeNode = node => {
  406. var _node$parentNode;
  407. return node === null || node === void 0 || (_node$parentNode = node.parentNode) === null || _node$parentNode === void 0 ? void 0 : _node$parentNode.removeChild(node);
  408. };
  409. const walkTree = function (tree) {
  410. let {
  411. onlyNodesOfType,
  412. usingFilter,
  413. expandEntityReferences
  414. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  415. const whatToShow = (() => {
  416. switch (onlyNodesOfType) {
  417. case "element":
  418. return NodeFilter.SHOW_ELEMENT;
  419. case "text":
  420. return NodeFilter.SHOW_TEXT;
  421. case "comment":
  422. return NodeFilter.SHOW_COMMENT;
  423. default:
  424. return NodeFilter.SHOW_ALL;
  425. }
  426. })();
  427. return document.createTreeWalker(tree, whatToShow, usingFilter != null ? usingFilter : null, expandEntityReferences === true);
  428. };
  429. const tagName = element => {
  430. var _element$tagName;
  431. return element === null || element === void 0 || (_element$tagName = element.tagName) === null || _element$tagName === void 0 ? void 0 : _element$tagName.toLowerCase();
  432. };
  433. const makeElement = function (tag) {
  434. let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  435. let key, value;
  436. if (typeof tag === "object") {
  437. options = tag;
  438. tag = options.tagName;
  439. } else {
  440. options = {
  441. attributes: options
  442. };
  443. }
  444. const element = document.createElement(tag);
  445. if (options.editable != null) {
  446. if (options.attributes == null) {
  447. options.attributes = {};
  448. }
  449. options.attributes.contenteditable = options.editable;
  450. }
  451. if (options.attributes) {
  452. for (key in options.attributes) {
  453. value = options.attributes[key];
  454. element.setAttribute(key, value);
  455. }
  456. }
  457. if (options.style) {
  458. for (key in options.style) {
  459. value = options.style[key];
  460. element.style[key] = value;
  461. }
  462. }
  463. if (options.data) {
  464. for (key in options.data) {
  465. value = options.data[key];
  466. element.dataset[key] = value;
  467. }
  468. }
  469. if (options.className) {
  470. options.className.split(" ").forEach(className => {
  471. element.classList.add(className);
  472. });
  473. }
  474. if (options.textContent) {
  475. element.textContent = options.textContent;
  476. }
  477. if (options.childNodes) {
  478. [].concat(options.childNodes).forEach(childNode => {
  479. element.appendChild(childNode);
  480. });
  481. }
  482. return element;
  483. };
  484. let blockTagNames = undefined;
  485. const getBlockTagNames = function () {
  486. if (blockTagNames != null) {
  487. return blockTagNames;
  488. }
  489. blockTagNames = [];
  490. for (const key in attributes) {
  491. const attributes$1 = attributes[key];
  492. if (attributes$1.tagName) {
  493. blockTagNames.push(attributes$1.tagName);
  494. }
  495. }
  496. return blockTagNames;
  497. };
  498. const nodeIsBlockContainer = node => nodeIsBlockStartComment(node === null || node === void 0 ? void 0 : node.firstChild);
  499. const nodeProbablyIsBlockContainer = function (node) {
  500. return getBlockTagNames().includes(tagName(node)) && !getBlockTagNames().includes(tagName(node.firstChild));
  501. };
  502. const nodeIsBlockStart = function (node) {
  503. let {
  504. strict
  505. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
  506. strict: true
  507. };
  508. if (strict) {
  509. return nodeIsBlockStartComment(node);
  510. } else {
  511. return nodeIsBlockStartComment(node) || !nodeIsBlockStartComment(node.firstChild) && nodeProbablyIsBlockContainer(node);
  512. }
  513. };
  514. const nodeIsBlockStartComment = node => nodeIsCommentNode(node) && (node === null || node === void 0 ? void 0 : node.data) === "block";
  515. const nodeIsCommentNode = node => (node === null || node === void 0 ? void 0 : node.nodeType) === Node.COMMENT_NODE;
  516. const nodeIsCursorTarget = function (node) {
  517. let {
  518. name
  519. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  520. if (!node) {
  521. return;
  522. }
  523. if (nodeIsTextNode(node)) {
  524. if (node.data === ZERO_WIDTH_SPACE) {
  525. if (name) {
  526. return node.parentNode.dataset.trixCursorTarget === name;
  527. } else {
  528. return true;
  529. }
  530. }
  531. } else {
  532. return nodeIsCursorTarget(node.firstChild);
  533. }
  534. };
  535. const nodeIsAttachmentElement = node => elementMatchesSelector(node, attachmentSelector);
  536. const nodeIsEmptyTextNode = node => nodeIsTextNode(node) && (node === null || node === void 0 ? void 0 : node.data) === "";
  537. const nodeIsTextNode = node => (node === null || node === void 0 ? void 0 : node.nodeType) === Node.TEXT_NODE;
  538. const input = {
  539. level2Enabled: true,
  540. getLevel() {
  541. if (this.level2Enabled && browser$1.supportsInputEvents) {
  542. return 2;
  543. } else {
  544. return 0;
  545. }
  546. },
  547. pickFiles(callback) {
  548. const input = makeElement("input", {
  549. type: "file",
  550. multiple: true,
  551. hidden: true,
  552. id: this.fileInputId
  553. });
  554. input.addEventListener("change", () => {
  555. callback(input.files);
  556. removeNode(input);
  557. });
  558. removeNode(document.getElementById(this.fileInputId));
  559. document.body.appendChild(input);
  560. input.click();
  561. }
  562. };
  563. var key_names = {
  564. 8: "backspace",
  565. 9: "tab",
  566. 13: "return",
  567. 27: "escape",
  568. 37: "left",
  569. 39: "right",
  570. 46: "delete",
  571. 68: "d",
  572. 72: "h",
  573. 79: "o"
  574. };
  575. var parser = {
  576. removeBlankTableCells: false,
  577. tableCellSeparator: " | ",
  578. tableRowSeparator: "\n"
  579. };
  580. var text_attributes = {
  581. bold: {
  582. tagName: "strong",
  583. inheritable: true,
  584. parser(element) {
  585. const style = window.getComputedStyle(element);
  586. return style.fontWeight === "bold" || style.fontWeight >= 600;
  587. }
  588. },
  589. italic: {
  590. tagName: "em",
  591. inheritable: true,
  592. parser(element) {
  593. const style = window.getComputedStyle(element);
  594. return style.fontStyle === "italic";
  595. }
  596. },
  597. href: {
  598. groupTagName: "a",
  599. parser(element) {
  600. const matchingSelector = "a:not(".concat(attachmentSelector, ")");
  601. const link = element.closest(matchingSelector);
  602. if (link) {
  603. return link.getAttribute("href");
  604. }
  605. }
  606. },
  607. strike: {
  608. tagName: "del",
  609. inheritable: true
  610. },
  611. frozen: {
  612. style: {
  613. backgroundColor: "highlight"
  614. }
  615. }
  616. };
  617. var toolbar = {
  618. getDefaultHTML() {
  619. return "<div class=\"trix-button-row\">\n <span class=\"trix-button-group trix-button-group--text-tools\" data-trix-button-group=\"text-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-bold\" data-trix-attribute=\"bold\" data-trix-key=\"b\" title=\"".concat(lang$1.bold, "\" tabindex=\"-1\">").concat(lang$1.bold, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-italic\" data-trix-attribute=\"italic\" data-trix-key=\"i\" title=\"").concat(lang$1.italic, "\" tabindex=\"-1\">").concat(lang$1.italic, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-strike\" data-trix-attribute=\"strike\" title=\"").concat(lang$1.strike, "\" tabindex=\"-1\">").concat(lang$1.strike, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-link\" data-trix-attribute=\"href\" data-trix-action=\"link\" data-trix-key=\"k\" title=\"").concat(lang$1.link, "\" tabindex=\"-1\">").concat(lang$1.link, "</button>\n </span>\n\n <span class=\"trix-button-group trix-button-group--block-tools\" data-trix-button-group=\"block-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-heading-1\" data-trix-attribute=\"heading1\" title=\"").concat(lang$1.heading1, "\" tabindex=\"-1\">").concat(lang$1.heading1, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-quote\" data-trix-attribute=\"quote\" title=\"").concat(lang$1.quote, "\" tabindex=\"-1\">").concat(lang$1.quote, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-code\" data-trix-attribute=\"code\" title=\"").concat(lang$1.code, "\" tabindex=\"-1\">").concat(lang$1.code, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-bullet-list\" data-trix-attribute=\"bullet\" title=\"").concat(lang$1.bullets, "\" tabindex=\"-1\">").concat(lang$1.bullets, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-number-list\" data-trix-attribute=\"number\" title=\"").concat(lang$1.numbers, "\" tabindex=\"-1\">").concat(lang$1.numbers, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-decrease-nesting-level\" data-trix-action=\"decreaseNestingLevel\" title=\"").concat(lang$1.outdent, "\" tabindex=\"-1\">").concat(lang$1.outdent, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-increase-nesting-level\" data-trix-action=\"increaseNestingLevel\" title=\"").concat(lang$1.indent, "\" tabindex=\"-1\">").concat(lang$1.indent, "</button>\n </span>\n\n <span class=\"trix-button-group trix-button-group--file-tools\" data-trix-button-group=\"file-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-attach\" data-trix-action=\"attachFiles\" title=\"").concat(lang$1.attachFiles, "\" tabindex=\"-1\">").concat(lang$1.attachFiles, "</button>\n </span>\n\n <span class=\"trix-button-group-spacer\"></span>\n\n <span class=\"trix-button-group trix-button-group--history-tools\" data-trix-button-group=\"history-tools\">\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-undo\" data-trix-action=\"undo\" data-trix-key=\"z\" title=\"").concat(lang$1.undo, "\" tabindex=\"-1\">").concat(lang$1.undo, "</button>\n <button type=\"button\" class=\"trix-button trix-button--icon trix-button--icon-redo\" data-trix-action=\"redo\" data-trix-key=\"shift+z\" title=\"").concat(lang$1.redo, "\" tabindex=\"-1\">").concat(lang$1.redo, "</button>\n </span>\n </div>\n\n <div class=\"trix-dialogs\" data-trix-dialogs>\n <div class=\"trix-dialog trix-dialog--link\" data-trix-dialog=\"href\" data-trix-dialog-attribute=\"href\">\n <div class=\"trix-dialog__link-fields\">\n <input type=\"url\" name=\"href\" class=\"trix-input trix-input--dialog\" placeholder=\"").concat(lang$1.urlPlaceholder, "\" aria-label=\"").concat(lang$1.url, "\" required data-trix-input>\n <div class=\"trix-button-group\">\n <input type=\"button\" class=\"trix-button trix-button--dialog\" value=\"").concat(lang$1.link, "\" data-trix-method=\"setAttribute\">\n <input type=\"button\" class=\"trix-button trix-button--dialog\" value=\"").concat(lang$1.unlink, "\" data-trix-method=\"removeAttribute\">\n </div>\n </div>\n </div>\n </div>");
  620. }
  621. };
  622. const undo = {
  623. interval: 5000
  624. };
  625. var config = /*#__PURE__*/Object.freeze({
  626. __proto__: null,
  627. attachments: attachments,
  628. blockAttributes: attributes,
  629. browser: browser$1,
  630. css: css$3,
  631. fileSize: file_size_formatting,
  632. input: input,
  633. keyNames: key_names,
  634. lang: lang$1,
  635. parser: parser,
  636. textAttributes: text_attributes,
  637. toolbar: toolbar,
  638. undo: undo
  639. });
  640. class BasicObject {
  641. static proxyMethod(expression) {
  642. const {
  643. name,
  644. toMethod,
  645. toProperty,
  646. optional
  647. } = parseProxyMethodExpression(expression);
  648. this.prototype[name] = function () {
  649. let subject;
  650. let object;
  651. if (toMethod) {
  652. if (optional) {
  653. var _this$toMethod;
  654. object = (_this$toMethod = this[toMethod]) === null || _this$toMethod === void 0 ? void 0 : _this$toMethod.call(this);
  655. } else {
  656. object = this[toMethod]();
  657. }
  658. } else if (toProperty) {
  659. object = this[toProperty];
  660. }
  661. if (optional) {
  662. var _object;
  663. subject = (_object = object) === null || _object === void 0 ? void 0 : _object[name];
  664. if (subject) {
  665. return apply$1.call(subject, object, arguments);
  666. }
  667. } else {
  668. subject = object[name];
  669. return apply$1.call(subject, object, arguments);
  670. }
  671. };
  672. }
  673. }
  674. const parseProxyMethodExpression = function (expression) {
  675. const match = expression.match(proxyMethodExpressionPattern);
  676. if (!match) {
  677. throw new Error("can't parse @proxyMethod expression: ".concat(expression));
  678. }
  679. const args = {
  680. name: match[4]
  681. };
  682. if (match[2] != null) {
  683. args.toMethod = match[1];
  684. } else {
  685. args.toProperty = match[1];
  686. }
  687. if (match[3] != null) {
  688. args.optional = true;
  689. }
  690. return args;
  691. };
  692. const {
  693. apply: apply$1
  694. } = Function.prototype;
  695. const proxyMethodExpressionPattern = new RegExp("\
  696. ^\
  697. (.+?)\
  698. (\\(\\))?\
  699. (\\?)?\
  700. \\.\
  701. (.+?)\
  702. $\
  703. ");
  704. var _Array$from, _$codePointAt$1, _$1, _String$fromCodePoint;
  705. class UTF16String extends BasicObject {
  706. static box() {
  707. let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
  708. if (value instanceof this) {
  709. return value;
  710. } else {
  711. return this.fromUCS2String(value === null || value === void 0 ? void 0 : value.toString());
  712. }
  713. }
  714. static fromUCS2String(ucs2String) {
  715. return new this(ucs2String, ucs2decode(ucs2String));
  716. }
  717. static fromCodepoints(codepoints) {
  718. return new this(ucs2encode(codepoints), codepoints);
  719. }
  720. constructor(ucs2String, codepoints) {
  721. super(...arguments);
  722. this.ucs2String = ucs2String;
  723. this.codepoints = codepoints;
  724. this.length = this.codepoints.length;
  725. this.ucs2Length = this.ucs2String.length;
  726. }
  727. offsetToUCS2Offset(offset) {
  728. return ucs2encode(this.codepoints.slice(0, Math.max(0, offset))).length;
  729. }
  730. offsetFromUCS2Offset(ucs2Offset) {
  731. return ucs2decode(this.ucs2String.slice(0, Math.max(0, ucs2Offset))).length;
  732. }
  733. slice() {
  734. return this.constructor.fromCodepoints(this.codepoints.slice(...arguments));
  735. }
  736. charAt(offset) {
  737. return this.slice(offset, offset + 1);
  738. }
  739. isEqualTo(value) {
  740. return this.constructor.box(value).ucs2String === this.ucs2String;
  741. }
  742. toJSON() {
  743. return this.ucs2String;
  744. }
  745. getCacheKey() {
  746. return this.ucs2String;
  747. }
  748. toString() {
  749. return this.ucs2String;
  750. }
  751. }
  752. const hasArrayFrom = ((_Array$from = Array.from) === null || _Array$from === void 0 ? void 0 : _Array$from.call(Array, "\ud83d\udc7c").length) === 1;
  753. const hasStringCodePointAt$1 = ((_$codePointAt$1 = (_$1 = " ").codePointAt) === null || _$codePointAt$1 === void 0 ? void 0 : _$codePointAt$1.call(_$1, 0)) != null;
  754. const hasStringFromCodePoint = ((_String$fromCodePoint = String.fromCodePoint) === null || _String$fromCodePoint === void 0 ? void 0 : _String$fromCodePoint.call(String, 32, 128124)) === " \ud83d\udc7c";
  755. // UCS-2 conversion helpers ported from Mathias Bynens' Punycode.js:
  756. // https://github.com/bestiejs/punycode.js#punycodeucs2
  757. let ucs2decode, ucs2encode;
  758. // Creates an array containing the numeric code points of each Unicode
  759. // character in the string. While JavaScript uses UCS-2 internally,
  760. // this function will convert a pair of surrogate halves (each of which
  761. // UCS-2 exposes as separate characters) into a single code point,
  762. // matching UTF-16.
  763. if (hasArrayFrom && hasStringCodePointAt$1) {
  764. ucs2decode = string => Array.from(string).map(char => char.codePointAt(0));
  765. } else {
  766. ucs2decode = function (string) {
  767. const output = [];
  768. let counter = 0;
  769. const {
  770. length
  771. } = string;
  772. while (counter < length) {
  773. let value = string.charCodeAt(counter++);
  774. if (0xd800 <= value && value <= 0xdbff && counter < length) {
  775. // high surrogate, and there is a next character
  776. const extra = string.charCodeAt(counter++);
  777. if ((extra & 0xfc00) === 0xdc00) {
  778. // low surrogate
  779. value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
  780. } else {
  781. // unmatched surrogate; only append this code unit, in case the
  782. // next code unit is the high surrogate of a surrogate pair
  783. counter--;
  784. }
  785. }
  786. output.push(value);
  787. }
  788. return output;
  789. };
  790. }
  791. // Creates a string based on an array of numeric code points.
  792. if (hasStringFromCodePoint) {
  793. ucs2encode = array => String.fromCodePoint(...Array.from(array || []));
  794. } else {
  795. ucs2encode = function (array) {
  796. const characters = (() => {
  797. const result = [];
  798. Array.from(array).forEach(value => {
  799. let output = "";
  800. if (value > 0xffff) {
  801. value -= 0x10000;
  802. output += String.fromCharCode(value >>> 10 & 0x3ff | 0xd800);
  803. value = 0xdc00 | value & 0x3ff;
  804. }
  805. result.push(output + String.fromCharCode(value));
  806. });
  807. return result;
  808. })();
  809. return characters.join("");
  810. };
  811. }
  812. let id$2 = 0;
  813. class TrixObject extends BasicObject {
  814. static fromJSONString(jsonString) {
  815. return this.fromJSON(JSON.parse(jsonString));
  816. }
  817. constructor() {
  818. super(...arguments);
  819. this.id = ++id$2;
  820. }
  821. hasSameConstructorAs(object) {
  822. return this.constructor === (object === null || object === void 0 ? void 0 : object.constructor);
  823. }
  824. isEqualTo(object) {
  825. return this === object;
  826. }
  827. inspect() {
  828. const parts = [];
  829. const contents = this.contentsForInspection() || {};
  830. for (const key in contents) {
  831. const value = contents[key];
  832. parts.push("".concat(key, "=").concat(value));
  833. }
  834. return "#<".concat(this.constructor.name, ":").concat(this.id).concat(parts.length ? " ".concat(parts.join(", ")) : "", ">");
  835. }
  836. contentsForInspection() {}
  837. toJSONString() {
  838. return JSON.stringify(this);
  839. }
  840. toUTF16String() {
  841. return UTF16String.box(this);
  842. }
  843. getCacheKey() {
  844. return this.id.toString();
  845. }
  846. }
  847. /* eslint-disable
  848. id-length,
  849. */
  850. const arraysAreEqual = function () {
  851. let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  852. let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  853. if (a.length !== b.length) {
  854. return false;
  855. }
  856. for (let index = 0; index < a.length; index++) {
  857. const value = a[index];
  858. if (value !== b[index]) {
  859. return false;
  860. }
  861. }
  862. return true;
  863. };
  864. const arrayStartsWith = function () {
  865. let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  866. let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  867. return arraysAreEqual(a.slice(0, b.length), b);
  868. };
  869. const spliceArray = function (array) {
  870. const result = array.slice(0);
  871. for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  872. args[_key - 1] = arguments[_key];
  873. }
  874. result.splice(...args);
  875. return result;
  876. };
  877. const summarizeArrayChange = function () {
  878. let oldArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  879. let newArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  880. const added = [];
  881. const removed = [];
  882. const existingValues = new Set();
  883. oldArray.forEach(value => {
  884. existingValues.add(value);
  885. });
  886. const currentValues = new Set();
  887. newArray.forEach(value => {
  888. currentValues.add(value);
  889. if (!existingValues.has(value)) {
  890. added.push(value);
  891. }
  892. });
  893. oldArray.forEach(value => {
  894. if (!currentValues.has(value)) {
  895. removed.push(value);
  896. }
  897. });
  898. return {
  899. added,
  900. removed
  901. };
  902. };
  903. // https://github.com/mathiasbynens/unicode-2.1.8/blob/master/Bidi_Class/Right_To_Left/regex.js
  904. 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]/;
  905. const getDirection = function () {
  906. const input = makeElement("input", {
  907. dir: "auto",
  908. name: "x",
  909. dirName: "x.dir"
  910. });
  911. const textArea = makeElement("textarea", {
  912. dir: "auto",
  913. name: "y",
  914. dirName: "y.dir"
  915. });
  916. const form = makeElement("form");
  917. form.appendChild(input);
  918. form.appendChild(textArea);
  919. const supportsDirName = function () {
  920. try {
  921. return new FormData(form).has(textArea.dirName);
  922. } catch (error) {
  923. return false;
  924. }
  925. }();
  926. const supportsDirSelector = function () {
  927. try {
  928. return input.matches(":dir(ltr),:dir(rtl)");
  929. } catch (error) {
  930. return false;
  931. }
  932. }();
  933. if (supportsDirName) {
  934. return function (string) {
  935. textArea.value = string;
  936. return new FormData(form).get(textArea.dirName);
  937. };
  938. } else if (supportsDirSelector) {
  939. return function (string) {
  940. input.value = string;
  941. if (input.matches(":dir(rtl)")) {
  942. return "rtl";
  943. } else {
  944. return "ltr";
  945. }
  946. };
  947. } else {
  948. return function (string) {
  949. const char = string.trim().charAt(0);
  950. if (RTL_PATTERN.test(char)) {
  951. return "rtl";
  952. } else {
  953. return "ltr";
  954. }
  955. };
  956. }
  957. }();
  958. let allAttributeNames = null;
  959. let blockAttributeNames = null;
  960. let textAttributeNames = null;
  961. let listAttributeNames = null;
  962. const getAllAttributeNames = () => {
  963. if (!allAttributeNames) {
  964. allAttributeNames = getTextAttributeNames().concat(getBlockAttributeNames());
  965. }
  966. return allAttributeNames;
  967. };
  968. const getBlockConfig = attributeName => attributes[attributeName];
  969. const getBlockAttributeNames = () => {
  970. if (!blockAttributeNames) {
  971. blockAttributeNames = Object.keys(attributes);
  972. }
  973. return blockAttributeNames;
  974. };
  975. const getTextConfig = attributeName => text_attributes[attributeName];
  976. const getTextAttributeNames = () => {
  977. if (!textAttributeNames) {
  978. textAttributeNames = Object.keys(text_attributes);
  979. }
  980. return textAttributeNames;
  981. };
  982. const getListAttributeNames = () => {
  983. if (!listAttributeNames) {
  984. listAttributeNames = [];
  985. for (const key in attributes) {
  986. const {
  987. listAttribute
  988. } = attributes[key];
  989. if (listAttribute != null) {
  990. listAttributeNames.push(listAttribute);
  991. }
  992. }
  993. }
  994. return listAttributeNames;
  995. };
  996. /* eslint-disable
  997. */
  998. const installDefaultCSSForTagName = function (tagName, defaultCSS) {
  999. const styleElement = insertStyleElementForTagName(tagName);
  1000. styleElement.textContent = defaultCSS.replace(/%t/g, tagName);
  1001. };
  1002. const insertStyleElementForTagName = function (tagName) {
  1003. const element = document.createElement("style");
  1004. element.setAttribute("type", "text/css");
  1005. element.setAttribute("data-tag-name", tagName.toLowerCase());
  1006. const nonce = getCSPNonce();
  1007. if (nonce) {
  1008. element.setAttribute("nonce", nonce);
  1009. }
  1010. document.head.insertBefore(element, document.head.firstChild);
  1011. return element;
  1012. };
  1013. const getCSPNonce = function () {
  1014. const element = getMetaElement("trix-csp-nonce") || getMetaElement("csp-nonce");
  1015. if (element) {
  1016. const {
  1017. nonce,
  1018. content
  1019. } = element;
  1020. return nonce == "" ? content : nonce;
  1021. }
  1022. };
  1023. const getMetaElement = name => document.head.querySelector("meta[name=".concat(name, "]"));
  1024. const testTransferData = {
  1025. "application/x-trix-feature-detection": "test"
  1026. };
  1027. const dataTransferIsPlainText = function (dataTransfer) {
  1028. const text = dataTransfer.getData("text/plain");
  1029. const html = dataTransfer.getData("text/html");
  1030. if (text && html) {
  1031. const {
  1032. body
  1033. } = new DOMParser().parseFromString(html, "text/html");
  1034. if (body.textContent === text) {
  1035. return !body.querySelector("*");
  1036. }
  1037. } else {
  1038. return text === null || text === void 0 ? void 0 : text.length;
  1039. }
  1040. };
  1041. const dataTransferIsMsOfficePaste = _ref => {
  1042. let {
  1043. dataTransfer
  1044. } = _ref;
  1045. return dataTransfer.types.includes("Files") && dataTransfer.types.includes("text/html") && dataTransfer.getData("text/html").includes("urn:schemas-microsoft-com:office:office");
  1046. };
  1047. const dataTransferIsWritable = function (dataTransfer) {
  1048. if (!(dataTransfer !== null && dataTransfer !== void 0 && dataTransfer.setData)) return false;
  1049. for (const key in testTransferData) {
  1050. const value = testTransferData[key];
  1051. try {
  1052. dataTransfer.setData(key, value);
  1053. if (!dataTransfer.getData(key) === value) return false;
  1054. } catch (error) {
  1055. return false;
  1056. }
  1057. }
  1058. return true;
  1059. };
  1060. const keyEventIsKeyboardCommand = function () {
  1061. if (/Mac|^iP/.test(navigator.platform)) {
  1062. return event => event.metaKey;
  1063. } else {
  1064. return event => event.ctrlKey;
  1065. }
  1066. }();
  1067. function shouldRenderInmmediatelyToDealWithIOSDictation(inputEvent) {
  1068. if (/iPhone|iPad/.test(navigator.userAgent)) {
  1069. // Handle garbled content and duplicated newlines when using dictation on iOS 18+. Upon dictation completion, iOS sends
  1070. // the list of insertText / insertParagraph events in a quick sequence. If we don't render
  1071. // the editor synchronously, the internal range fails to update and results in garbled content or duplicated newlines.
  1072. //
  1073. // This workaround is necessary because iOS doesn't send composing events as expected while dictating:
  1074. // https://bugs.webkit.org/show_bug.cgi?id=261764
  1075. return !inputEvent.inputType || inputEvent.inputType === "insertParagraph";
  1076. } else {
  1077. return false;
  1078. }
  1079. }
  1080. const defer = fn => setTimeout(fn, 1);
  1081. /* eslint-disable
  1082. id-length,
  1083. */
  1084. const copyObject = function () {
  1085. let object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1086. const result = {};
  1087. for (const key in object) {
  1088. const value = object[key];
  1089. result[key] = value;
  1090. }
  1091. return result;
  1092. };
  1093. const objectsAreEqual = function () {
  1094. let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1095. let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  1096. if (Object.keys(a).length !== Object.keys(b).length) {
  1097. return false;
  1098. }
  1099. for (const key in a) {
  1100. const value = a[key];
  1101. if (value !== b[key]) {
  1102. return false;
  1103. }
  1104. }
  1105. return true;
  1106. };
  1107. const normalizeRange = function (range) {
  1108. if (range == null) return;
  1109. if (!Array.isArray(range)) {
  1110. range = [range, range];
  1111. }
  1112. return [copyValue(range[0]), copyValue(range[1] != null ? range[1] : range[0])];
  1113. };
  1114. const rangeIsCollapsed = function (range) {
  1115. if (range == null) return;
  1116. const [start, end] = normalizeRange(range);
  1117. return rangeValuesAreEqual(start, end);
  1118. };
  1119. const rangesAreEqual = function (leftRange, rightRange) {
  1120. if (leftRange == null || rightRange == null) return;
  1121. const [leftStart, leftEnd] = normalizeRange(leftRange);
  1122. const [rightStart, rightEnd] = normalizeRange(rightRange);
  1123. return rangeValuesAreEqual(leftStart, rightStart) && rangeValuesAreEqual(leftEnd, rightEnd);
  1124. };
  1125. const copyValue = function (value) {
  1126. if (typeof value === "number") {
  1127. return value;
  1128. } else {
  1129. return copyObject(value);
  1130. }
  1131. };
  1132. const rangeValuesAreEqual = function (left, right) {
  1133. if (typeof left === "number") {
  1134. return left === right;
  1135. } else {
  1136. return objectsAreEqual(left, right);
  1137. }
  1138. };
  1139. class SelectionChangeObserver extends BasicObject {
  1140. constructor() {
  1141. super(...arguments);
  1142. this.update = this.update.bind(this);
  1143. this.selectionManagers = [];
  1144. }
  1145. start() {
  1146. if (!this.started) {
  1147. this.started = true;
  1148. document.addEventListener("selectionchange", this.update, true);
  1149. }
  1150. }
  1151. stop() {
  1152. if (this.started) {
  1153. this.started = false;
  1154. return document.removeEventListener("selectionchange", this.update, true);
  1155. }
  1156. }
  1157. registerSelectionManager(selectionManager) {
  1158. if (!this.selectionManagers.includes(selectionManager)) {
  1159. this.selectionManagers.push(selectionManager);
  1160. return this.start();
  1161. }
  1162. }
  1163. unregisterSelectionManager(selectionManager) {
  1164. this.selectionManagers = this.selectionManagers.filter(sm => sm !== selectionManager);
  1165. if (this.selectionManagers.length === 0) {
  1166. return this.stop();
  1167. }
  1168. }
  1169. notifySelectionManagersOfSelectionChange() {
  1170. return this.selectionManagers.map(selectionManager => selectionManager.selectionDidChange());
  1171. }
  1172. update() {
  1173. this.notifySelectionManagersOfSelectionChange();
  1174. }
  1175. reset() {
  1176. this.update();
  1177. }
  1178. }
  1179. const selectionChangeObserver = new SelectionChangeObserver();
  1180. const getDOMSelection = function () {
  1181. const selection = window.getSelection();
  1182. if (selection.rangeCount > 0) {
  1183. return selection;
  1184. }
  1185. };
  1186. const getDOMRange = function () {
  1187. var _getDOMSelection;
  1188. const domRange = (_getDOMSelection = getDOMSelection()) === null || _getDOMSelection === void 0 ? void 0 : _getDOMSelection.getRangeAt(0);
  1189. if (domRange) {
  1190. if (!domRangeIsPrivate(domRange)) {
  1191. return domRange;
  1192. }
  1193. }
  1194. };
  1195. const setDOMRange = function (domRange) {
  1196. const selection = window.getSelection();
  1197. selection.removeAllRanges();
  1198. selection.addRange(domRange);
  1199. return selectionChangeObserver.update();
  1200. };
  1201. // In Firefox, clicking certain <input> elements changes the selection to a
  1202. // private element used to draw its UI. Attempting to access properties of those
  1203. // elements throws an error.
  1204. // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
  1205. const domRangeIsPrivate = domRange => nodeIsPrivate(domRange.startContainer) || nodeIsPrivate(domRange.endContainer);
  1206. const nodeIsPrivate = node => !Object.getPrototypeOf(node);
  1207. /* eslint-disable
  1208. id-length,
  1209. no-useless-escape,
  1210. */
  1211. const normalizeSpaces = string => string.replace(new RegExp("".concat(ZERO_WIDTH_SPACE), "g"), "").replace(new RegExp("".concat(NON_BREAKING_SPACE), "g"), " ");
  1212. const normalizeNewlines = string => string.replace(/\r\n?/g, "\n");
  1213. const breakableWhitespacePattern = new RegExp("[^\\S".concat(NON_BREAKING_SPACE, "]"));
  1214. const squishBreakableWhitespace = string => string
  1215. // Replace all breakable whitespace characters with a space
  1216. .replace(new RegExp("".concat(breakableWhitespacePattern.source), "g"), " ")
  1217. // Replace two or more spaces with a single space
  1218. .replace(/\ {2,}/g, " ");
  1219. const summarizeStringChange = function (oldString, newString) {
  1220. let added, removed;
  1221. oldString = UTF16String.box(oldString);
  1222. newString = UTF16String.box(newString);
  1223. if (newString.length < oldString.length) {
  1224. [removed, added] = utf16StringDifferences(oldString, newString);
  1225. } else {
  1226. [added, removed] = utf16StringDifferences(newString, oldString);
  1227. }
  1228. return {
  1229. added,
  1230. removed
  1231. };
  1232. };
  1233. const utf16StringDifferences = function (a, b) {
  1234. if (a.isEqualTo(b)) {
  1235. return ["", ""];
  1236. }
  1237. const diffA = utf16StringDifference(a, b);
  1238. const {
  1239. length
  1240. } = diffA.utf16String;
  1241. let diffB;
  1242. if (length) {
  1243. const {
  1244. offset
  1245. } = diffA;
  1246. const codepoints = a.codepoints.slice(0, offset).concat(a.codepoints.slice(offset + length));
  1247. diffB = utf16StringDifference(b, UTF16String.fromCodepoints(codepoints));
  1248. } else {
  1249. diffB = utf16StringDifference(b, a);
  1250. }
  1251. return [diffA.utf16String.toString(), diffB.utf16String.toString()];
  1252. };
  1253. const utf16StringDifference = function (a, b) {
  1254. let leftIndex = 0;
  1255. let rightIndexA = a.length;
  1256. let rightIndexB = b.length;
  1257. while (leftIndex < rightIndexA && a.charAt(leftIndex).isEqualTo(b.charAt(leftIndex))) {
  1258. leftIndex++;
  1259. }
  1260. while (rightIndexA > leftIndex + 1 && a.charAt(rightIndexA - 1).isEqualTo(b.charAt(rightIndexB - 1))) {
  1261. rightIndexA--;
  1262. rightIndexB--;
  1263. }
  1264. return {
  1265. utf16String: a.slice(leftIndex, rightIndexA),
  1266. offset: leftIndex
  1267. };
  1268. };
  1269. class Hash extends TrixObject {
  1270. static fromCommonAttributesOfObjects() {
  1271. let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  1272. if (!objects.length) {
  1273. return new this();
  1274. }
  1275. let hash = box(objects[0]);
  1276. let keys = hash.getKeys();
  1277. objects.slice(1).forEach(object => {
  1278. keys = hash.getKeysCommonToHash(box(object));
  1279. hash = hash.slice(keys);
  1280. });
  1281. return hash;
  1282. }
  1283. static box(values) {
  1284. return box(values);
  1285. }
  1286. constructor() {
  1287. let values = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1288. super(...arguments);
  1289. this.values = copy(values);
  1290. }
  1291. add(key, value) {
  1292. return this.merge(object(key, value));
  1293. }
  1294. remove(key) {
  1295. return new Hash(copy(this.values, key));
  1296. }
  1297. get(key) {
  1298. return this.values[key];
  1299. }
  1300. has(key) {
  1301. return key in this.values;
  1302. }
  1303. merge(values) {
  1304. return new Hash(merge(this.values, unbox(values)));
  1305. }
  1306. slice(keys) {
  1307. const values = {};
  1308. Array.from(keys).forEach(key => {
  1309. if (this.has(key)) {
  1310. values[key] = this.values[key];
  1311. }
  1312. });
  1313. return new Hash(values);
  1314. }
  1315. getKeys() {
  1316. return Object.keys(this.values);
  1317. }
  1318. getKeysCommonToHash(hash) {
  1319. hash = box(hash);
  1320. return this.getKeys().filter(key => this.values[key] === hash.values[key]);
  1321. }
  1322. isEqualTo(values) {
  1323. return arraysAreEqual(this.toArray(), box(values).toArray());
  1324. }
  1325. isEmpty() {
  1326. return this.getKeys().length === 0;
  1327. }
  1328. toArray() {
  1329. if (!this.array) {
  1330. const result = [];
  1331. for (const key in this.values) {
  1332. const value = this.values[key];
  1333. result.push(result.push(key, value));
  1334. }
  1335. this.array = result.slice(0);
  1336. }
  1337. return this.array;
  1338. }
  1339. toObject() {
  1340. return copy(this.values);
  1341. }
  1342. toJSON() {
  1343. return this.toObject();
  1344. }
  1345. contentsForInspection() {
  1346. return {
  1347. values: JSON.stringify(this.values)
  1348. };
  1349. }
  1350. }
  1351. const object = function (key, value) {
  1352. const result = {};
  1353. result[key] = value;
  1354. return result;
  1355. };
  1356. const merge = function (object, values) {
  1357. const result = copy(object);
  1358. for (const key in values) {
  1359. const value = values[key];
  1360. result[key] = value;
  1361. }
  1362. return result;
  1363. };
  1364. const copy = function (object, keyToRemove) {
  1365. const result = {};
  1366. const sortedKeys = Object.keys(object).sort();
  1367. sortedKeys.forEach(key => {
  1368. if (key !== keyToRemove) {
  1369. result[key] = object[key];
  1370. }
  1371. });
  1372. return result;
  1373. };
  1374. const box = function (object) {
  1375. if (object instanceof Hash) {
  1376. return object;
  1377. } else {
  1378. return new Hash(object);
  1379. }
  1380. };
  1381. const unbox = function (object) {
  1382. if (object instanceof Hash) {
  1383. return object.values;
  1384. } else {
  1385. return object;
  1386. }
  1387. };
  1388. class ObjectGroup {
  1389. static groupObjects() {
  1390. let ungroupedObjects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  1391. let {
  1392. depth,
  1393. asTree
  1394. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  1395. let group;
  1396. if (asTree) {
  1397. if (depth == null) {
  1398. depth = 0;
  1399. }
  1400. }
  1401. const objects = [];
  1402. Array.from(ungroupedObjects).forEach(object => {
  1403. var _object$canBeGrouped2;
  1404. if (group) {
  1405. var _object$canBeGrouped, _group$canBeGroupedWi, _group;
  1406. 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)) {
  1407. group.push(object);
  1408. return;
  1409. } else {
  1410. objects.push(new this(group, {
  1411. depth,
  1412. asTree
  1413. }));
  1414. group = null;
  1415. }
  1416. }
  1417. if ((_object$canBeGrouped2 = object.canBeGrouped) !== null && _object$canBeGrouped2 !== void 0 && _object$canBeGrouped2.call(object, depth)) {
  1418. group = [object];
  1419. } else {
  1420. objects.push(object);
  1421. }
  1422. });
  1423. if (group) {
  1424. objects.push(new this(group, {
  1425. depth,
  1426. asTree
  1427. }));
  1428. }
  1429. return objects;
  1430. }
  1431. constructor() {
  1432. let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  1433. let {
  1434. depth,
  1435. asTree
  1436. } = arguments.length > 1 ? arguments[1] : undefined;
  1437. this.objects = objects;
  1438. if (asTree) {
  1439. this.depth = depth;
  1440. this.objects = this.constructor.groupObjects(this.objects, {
  1441. asTree,
  1442. depth: this.depth + 1
  1443. });
  1444. }
  1445. }
  1446. getObjects() {
  1447. return this.objects;
  1448. }
  1449. getDepth() {
  1450. return this.depth;
  1451. }
  1452. getCacheKey() {
  1453. const keys = ["objectGroup"];
  1454. Array.from(this.getObjects()).forEach(object => {
  1455. keys.push(object.getCacheKey());
  1456. });
  1457. return keys.join("/");
  1458. }
  1459. }
  1460. class ObjectMap extends BasicObject {
  1461. constructor() {
  1462. let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  1463. super(...arguments);
  1464. this.objects = {};
  1465. Array.from(objects).forEach(object => {
  1466. const hash = JSON.stringify(object);
  1467. if (this.objects[hash] == null) {
  1468. this.objects[hash] = object;
  1469. }
  1470. });
  1471. }
  1472. find(object) {
  1473. const hash = JSON.stringify(object);
  1474. return this.objects[hash];
  1475. }
  1476. }
  1477. class ElementStore {
  1478. constructor(elements) {
  1479. this.reset(elements);
  1480. }
  1481. add(element) {
  1482. const key = getKey(element);
  1483. this.elements[key] = element;
  1484. }
  1485. remove(element) {
  1486. const key = getKey(element);
  1487. const value = this.elements[key];
  1488. if (value) {
  1489. delete this.elements[key];
  1490. return value;
  1491. }
  1492. }
  1493. reset() {
  1494. let elements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  1495. this.elements = {};
  1496. Array.from(elements).forEach(element => {
  1497. this.add(element);
  1498. });
  1499. return elements;
  1500. }
  1501. }
  1502. const getKey = element => element.dataset.trixStoreKey;
  1503. class Operation extends BasicObject {
  1504. isPerforming() {
  1505. return this.performing === true;
  1506. }
  1507. hasPerformed() {
  1508. return this.performed === true;
  1509. }
  1510. hasSucceeded() {
  1511. return this.performed && this.succeeded;
  1512. }
  1513. hasFailed() {
  1514. return this.performed && !this.succeeded;
  1515. }
  1516. getPromise() {
  1517. if (!this.promise) {
  1518. this.promise = new Promise((resolve, reject) => {
  1519. this.performing = true;
  1520. return this.perform((succeeded, result) => {
  1521. this.succeeded = succeeded;
  1522. this.performing = false;
  1523. this.performed = true;
  1524. if (this.succeeded) {
  1525. resolve(result);
  1526. } else {
  1527. reject(result);
  1528. }
  1529. });
  1530. });
  1531. }
  1532. return this.promise;
  1533. }
  1534. perform(callback) {
  1535. return callback(false);
  1536. }
  1537. release() {
  1538. var _this$promise, _this$promise$cancel;
  1539. (_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);
  1540. this.promise = null;
  1541. this.performing = null;
  1542. this.performed = null;
  1543. this.succeeded = null;
  1544. }
  1545. }
  1546. Operation.proxyMethod("getPromise().then");
  1547. Operation.proxyMethod("getPromise().catch");
  1548. class ObjectView extends BasicObject {
  1549. constructor(object) {
  1550. let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  1551. super(...arguments);
  1552. this.object = object;
  1553. this.options = options;
  1554. this.childViews = [];
  1555. this.rootView = this;
  1556. }
  1557. getNodes() {
  1558. if (!this.nodes) {
  1559. this.nodes = this.createNodes();
  1560. }
  1561. return this.nodes.map(node => node.cloneNode(true));
  1562. }
  1563. invalidate() {
  1564. var _this$parentView;
  1565. this.nodes = null;
  1566. this.childViews = [];
  1567. return (_this$parentView = this.parentView) === null || _this$parentView === void 0 ? void 0 : _this$parentView.invalidate();
  1568. }
  1569. invalidateViewForObject(object) {
  1570. var _this$findViewForObje;
  1571. return (_this$findViewForObje = this.findViewForObject(object)) === null || _this$findViewForObje === void 0 ? void 0 : _this$findViewForObje.invalidate();
  1572. }
  1573. findOrCreateCachedChildView(viewClass, object, options) {
  1574. let view = this.getCachedViewForObject(object);
  1575. if (view) {
  1576. this.recordChildView(view);
  1577. } else {
  1578. view = this.createChildView(...arguments);
  1579. this.cacheViewForObject(view, object);
  1580. }
  1581. return view;
  1582. }
  1583. createChildView(viewClass, object) {
  1584. let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  1585. if (object instanceof ObjectGroup) {
  1586. options.viewClass = viewClass;
  1587. viewClass = ObjectGroupView;
  1588. }
  1589. const view = new viewClass(object, options);
  1590. return this.recordChildView(view);
  1591. }
  1592. recordChildView(view) {
  1593. view.parentView = this;
  1594. view.rootView = this.rootView;
  1595. this.childViews.push(view);
  1596. return view;
  1597. }
  1598. getAllChildViews() {
  1599. let views = [];
  1600. this.childViews.forEach(childView => {
  1601. views.push(childView);
  1602. views = views.concat(childView.getAllChildViews());
  1603. });
  1604. return views;
  1605. }
  1606. findElement() {
  1607. return this.findElementForObject(this.object);
  1608. }
  1609. findElementForObject(object) {
  1610. const id = object === null || object === void 0 ? void 0 : object.id;
  1611. if (id) {
  1612. return this.rootView.element.querySelector("[data-trix-id='".concat(id, "']"));
  1613. }
  1614. }
  1615. findViewForObject(object) {
  1616. for (const view of this.getAllChildViews()) {
  1617. if (view.object === object) {
  1618. return view;
  1619. }
  1620. }
  1621. }
  1622. getViewCache() {
  1623. if (this.rootView === this) {
  1624. if (this.isViewCachingEnabled()) {
  1625. if (!this.viewCache) {
  1626. this.viewCache = {};
  1627. }
  1628. return this.viewCache;
  1629. }
  1630. } else {
  1631. return this.rootView.getViewCache();
  1632. }
  1633. }
  1634. isViewCachingEnabled() {
  1635. return this.shouldCacheViews !== false;
  1636. }
  1637. enableViewCaching() {
  1638. this.shouldCacheViews = true;
  1639. }
  1640. disableViewCaching() {
  1641. this.shouldCacheViews = false;
  1642. }
  1643. getCachedViewForObject(object) {
  1644. var _this$getViewCache;
  1645. return (_this$getViewCache = this.getViewCache()) === null || _this$getViewCache === void 0 ? void 0 : _this$getViewCache[object.getCacheKey()];
  1646. }
  1647. cacheViewForObject(view, object) {
  1648. const cache = this.getViewCache();
  1649. if (cache) {
  1650. cache[object.getCacheKey()] = view;
  1651. }
  1652. }
  1653. garbageCollectCachedViews() {
  1654. const cache = this.getViewCache();
  1655. if (cache) {
  1656. const views = this.getAllChildViews().concat(this);
  1657. const objectKeys = views.map(view => view.object.getCacheKey());
  1658. for (const key in cache) {
  1659. if (!objectKeys.includes(key)) {
  1660. delete cache[key];
  1661. }
  1662. }
  1663. }
  1664. }
  1665. }
  1666. class ObjectGroupView extends ObjectView {
  1667. constructor() {
  1668. super(...arguments);
  1669. this.objectGroup = this.object;
  1670. this.viewClass = this.options.viewClass;
  1671. delete this.options.viewClass;
  1672. }
  1673. getChildViews() {
  1674. if (!this.childViews.length) {
  1675. Array.from(this.objectGroup.getObjects()).forEach(object => {
  1676. this.findOrCreateCachedChildView(this.viewClass, object, this.options);
  1677. });
  1678. }
  1679. return this.childViews;
  1680. }
  1681. createNodes() {
  1682. const element = this.createContainerElement();
  1683. this.getChildViews().forEach(view => {
  1684. Array.from(view.getNodes()).forEach(node => {
  1685. element.appendChild(node);
  1686. });
  1687. });
  1688. return [element];
  1689. }
  1690. createContainerElement() {
  1691. let depth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.objectGroup.getDepth();
  1692. return this.getChildViews()[0].createContainerElement(depth);
  1693. }
  1694. }
  1695. /*! @license DOMPurify 3.2.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.3/LICENSE */
  1696. const {
  1697. entries,
  1698. setPrototypeOf,
  1699. isFrozen,
  1700. getPrototypeOf,
  1701. getOwnPropertyDescriptor
  1702. } = Object;
  1703. let {
  1704. freeze,
  1705. seal,
  1706. create
  1707. } = Object; // eslint-disable-line import/no-mutable-exports
  1708. let {
  1709. apply,
  1710. construct
  1711. } = typeof Reflect !== 'undefined' && Reflect;
  1712. if (!freeze) {
  1713. freeze = function freeze(x) {
  1714. return x;
  1715. };
  1716. }
  1717. if (!seal) {
  1718. seal = function seal(x) {
  1719. return x;
  1720. };
  1721. }
  1722. if (!apply) {
  1723. apply = function apply(fun, thisValue, args) {
  1724. return fun.apply(thisValue, args);
  1725. };
  1726. }
  1727. if (!construct) {
  1728. construct = function construct(Func, args) {
  1729. return new Func(...args);
  1730. };
  1731. }
  1732. const arrayForEach = unapply(Array.prototype.forEach);
  1733. const arrayPop = unapply(Array.prototype.pop);
  1734. const arrayPush = unapply(Array.prototype.push);
  1735. const stringToLowerCase = unapply(String.prototype.toLowerCase);
  1736. const stringToString = unapply(String.prototype.toString);
  1737. const stringMatch = unapply(String.prototype.match);
  1738. const stringReplace = unapply(String.prototype.replace);
  1739. const stringIndexOf = unapply(String.prototype.indexOf);
  1740. const stringTrim = unapply(String.prototype.trim);
  1741. const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
  1742. const regExpTest = unapply(RegExp.prototype.test);
  1743. const typeErrorCreate = unconstruct(TypeError);
  1744. /**
  1745. * Creates a new function that calls the given function with a specified thisArg and arguments.
  1746. *
  1747. * @param func - The function to be wrapped and called.
  1748. * @returns A new function that calls the given function with a specified thisArg and arguments.
  1749. */
  1750. function unapply(func) {
  1751. return function (thisArg) {
  1752. for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  1753. args[_key - 1] = arguments[_key];
  1754. }
  1755. return apply(func, thisArg, args);
  1756. };
  1757. }
  1758. /**
  1759. * Creates a new function that constructs an instance of the given constructor function with the provided arguments.
  1760. *
  1761. * @param func - The constructor function to be wrapped and called.
  1762. * @returns A new function that constructs an instance of the given constructor function with the provided arguments.
  1763. */
  1764. function unconstruct(func) {
  1765. return function () {
  1766. for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  1767. args[_key2] = arguments[_key2];
  1768. }
  1769. return construct(func, args);
  1770. };
  1771. }
  1772. /**
  1773. * Add properties to a lookup table
  1774. *
  1775. * @param set - The set to which elements will be added.
  1776. * @param array - The array containing elements to be added to the set.
  1777. * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.
  1778. * @returns The modified set with added elements.
  1779. */
  1780. function addToSet(set, array) {
  1781. let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
  1782. if (setPrototypeOf) {
  1783. // Make 'in' and truthy checks like Boolean(set.constructor)
  1784. // independent of any properties defined on Object.prototype.
  1785. // Prevent prototype setters from intercepting set as a this value.
  1786. setPrototypeOf(set, null);
  1787. }
  1788. let l = array.length;
  1789. while (l--) {
  1790. let element = array[l];
  1791. if (typeof element === 'string') {
  1792. const lcElement = transformCaseFunc(element);
  1793. if (lcElement !== element) {
  1794. // Config presets (e.g. tags.js, attrs.js) are immutable.
  1795. if (!isFrozen(array)) {
  1796. array[l] = lcElement;
  1797. }
  1798. element = lcElement;
  1799. }
  1800. }
  1801. set[element] = true;
  1802. }
  1803. return set;
  1804. }
  1805. /**
  1806. * Clean up an array to harden against CSPP
  1807. *
  1808. * @param array - The array to be cleaned.
  1809. * @returns The cleaned version of the array
  1810. */
  1811. function cleanArray(array) {
  1812. for (let index = 0; index < array.length; index++) {
  1813. const isPropertyExist = objectHasOwnProperty(array, index);
  1814. if (!isPropertyExist) {
  1815. array[index] = null;
  1816. }
  1817. }
  1818. return array;
  1819. }
  1820. /**
  1821. * Shallow clone an object
  1822. *
  1823. * @param object - The object to be cloned.
  1824. * @returns A new object that copies the original.
  1825. */
  1826. function clone(object) {
  1827. const newObject = create(null);
  1828. for (const [property, value] of entries(object)) {
  1829. const isPropertyExist = objectHasOwnProperty(object, property);
  1830. if (isPropertyExist) {
  1831. if (Array.isArray(value)) {
  1832. newObject[property] = cleanArray(value);
  1833. } else if (value && typeof value === 'object' && value.constructor === Object) {
  1834. newObject[property] = clone(value);
  1835. } else {
  1836. newObject[property] = value;
  1837. }
  1838. }
  1839. }
  1840. return newObject;
  1841. }
  1842. /**
  1843. * This method automatically checks if the prop is function or getter and behaves accordingly.
  1844. *
  1845. * @param object - The object to look up the getter function in its prototype chain.
  1846. * @param prop - The property name for which to find the getter function.
  1847. * @returns The getter function found in the prototype chain or a fallback function.
  1848. */
  1849. function lookupGetter(object, prop) {
  1850. while (object !== null) {
  1851. const desc = getOwnPropertyDescriptor(object, prop);
  1852. if (desc) {
  1853. if (desc.get) {
  1854. return unapply(desc.get);
  1855. }
  1856. if (typeof desc.value === 'function') {
  1857. return unapply(desc.value);
  1858. }
  1859. }
  1860. object = getPrototypeOf(object);
  1861. }
  1862. function fallbackValue() {
  1863. return null;
  1864. }
  1865. return fallbackValue;
  1866. }
  1867. const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
  1868. const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
  1869. 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']);
  1870. // List of SVG elements that are disallowed by default.
  1871. // We still need to know them so that we can do namespace
  1872. // checks properly in case one wants to add them to
  1873. // allow-list.
  1874. 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']);
  1875. 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']);
  1876. // Similarly to SVG, we want to know all MathML elements,
  1877. // even those that we disallow by default.
  1878. const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
  1879. const text = freeze(['#text']);
  1880. const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
  1881. const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
  1882. const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
  1883. const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
  1884. // eslint-disable-next-line unicorn/better-regex
  1885. const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
  1886. const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
  1887. const TMPLIT_EXPR = seal(/\$\{[\w\W]*}/gm); // eslint-disable-line unicorn/better-regex
  1888. const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
  1889. const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
  1890. const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
  1891. );
  1892. const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
  1893. const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
  1894. );
  1895. const DOCTYPE_NAME = seal(/^html$/i);
  1896. const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
  1897. var EXPRESSIONS = /*#__PURE__*/Object.freeze({
  1898. __proto__: null,
  1899. ARIA_ATTR: ARIA_ATTR,
  1900. ATTR_WHITESPACE: ATTR_WHITESPACE,
  1901. CUSTOM_ELEMENT: CUSTOM_ELEMENT,
  1902. DATA_ATTR: DATA_ATTR,
  1903. DOCTYPE_NAME: DOCTYPE_NAME,
  1904. ERB_EXPR: ERB_EXPR,
  1905. IS_ALLOWED_URI: IS_ALLOWED_URI,
  1906. IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
  1907. MUSTACHE_EXPR: MUSTACHE_EXPR,
  1908. TMPLIT_EXPR: TMPLIT_EXPR
  1909. });
  1910. /* eslint-disable @typescript-eslint/indent */
  1911. // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
  1912. const NODE_TYPE = {
  1913. element: 1,
  1914. attribute: 2,
  1915. text: 3,
  1916. cdataSection: 4,
  1917. entityReference: 5,
  1918. // Deprecated
  1919. entityNode: 6,
  1920. // Deprecated
  1921. progressingInstruction: 7,
  1922. comment: 8,
  1923. document: 9,
  1924. documentType: 10,
  1925. documentFragment: 11,
  1926. notation: 12 // Deprecated
  1927. };
  1928. const getGlobal = function getGlobal() {
  1929. return typeof window === 'undefined' ? null : window;
  1930. };
  1931. /**
  1932. * Creates a no-op policy for internal use only.
  1933. * Don't export this function outside this module!
  1934. * @param trustedTypes The policy factory.
  1935. * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).
  1936. * @return The policy created (or null, if Trusted Types
  1937. * are not supported or creating the policy failed).
  1938. */
  1939. const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
  1940. if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
  1941. return null;
  1942. }
  1943. // Allow the callers to control the unique policy name
  1944. // by adding a data-tt-policy-suffix to the script element with the DOMPurify.
  1945. // Policy creation with duplicate names throws in Trusted Types.
  1946. let suffix = null;
  1947. const ATTR_NAME = 'data-tt-policy-suffix';
  1948. if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
  1949. suffix = purifyHostElement.getAttribute(ATTR_NAME);
  1950. }
  1951. const policyName = 'dompurify' + (suffix ? '#' + suffix : '');
  1952. try {
  1953. return trustedTypes.createPolicy(policyName, {
  1954. createHTML(html) {
  1955. return html;
  1956. },
  1957. createScriptURL(scriptUrl) {
  1958. return scriptUrl;
  1959. }
  1960. });
  1961. } catch (_) {
  1962. // Policy creation failed (most likely another DOMPurify script has
  1963. // already run). Skip creating the policy, as this will only cause errors
  1964. // if TT are enforced.
  1965. console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
  1966. return null;
  1967. }
  1968. };
  1969. const _createHooksMap = function _createHooksMap() {
  1970. return {
  1971. afterSanitizeAttributes: [],
  1972. afterSanitizeElements: [],
  1973. afterSanitizeShadowDOM: [],
  1974. beforeSanitizeAttributes: [],
  1975. beforeSanitizeElements: [],
  1976. beforeSanitizeShadowDOM: [],
  1977. uponSanitizeAttribute: [],
  1978. uponSanitizeElement: [],
  1979. uponSanitizeShadowNode: []
  1980. };
  1981. };
  1982. function createDOMPurify() {
  1983. let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
  1984. const DOMPurify = root => createDOMPurify(root);
  1985. DOMPurify.version = '3.2.3';
  1986. DOMPurify.removed = [];
  1987. if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document) {
  1988. // Not running in a browser, provide a factory function
  1989. // so that you can pass your own Window
  1990. DOMPurify.isSupported = false;
  1991. return DOMPurify;
  1992. }
  1993. let {
  1994. document
  1995. } = window;
  1996. const originalDocument = document;
  1997. const currentScript = originalDocument.currentScript;
  1998. const {
  1999. DocumentFragment,
  2000. HTMLTemplateElement,
  2001. Node,
  2002. Element,
  2003. NodeFilter,
  2004. NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,
  2005. HTMLFormElement,
  2006. DOMParser,
  2007. trustedTypes
  2008. } = window;
  2009. const ElementPrototype = Element.prototype;
  2010. const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
  2011. const remove = lookupGetter(ElementPrototype, 'remove');
  2012. const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
  2013. const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
  2014. const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
  2015. // As per issue #47, the web-components registry is inherited by a
  2016. // new document created via createHTMLDocument. As per the spec
  2017. // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
  2018. // a new empty registry is used when creating a template contents owner
  2019. // document, so we use that as our parent document to ensure nothing
  2020. // is inherited.
  2021. if (typeof HTMLTemplateElement === 'function') {
  2022. const template = document.createElement('template');
  2023. if (template.content && template.content.ownerDocument) {
  2024. document = template.content.ownerDocument;
  2025. }
  2026. }
  2027. let trustedTypesPolicy;
  2028. let emptyHTML = '';
  2029. const {
  2030. implementation,
  2031. createNodeIterator,
  2032. createDocumentFragment,
  2033. getElementsByTagName
  2034. } = document;
  2035. const {
  2036. importNode
  2037. } = originalDocument;
  2038. let hooks = _createHooksMap();
  2039. /**
  2040. * Expose whether this browser supports running the full DOMPurify.
  2041. */
  2042. DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
  2043. const {
  2044. MUSTACHE_EXPR,
  2045. ERB_EXPR,
  2046. TMPLIT_EXPR,
  2047. DATA_ATTR,
  2048. ARIA_ATTR,
  2049. IS_SCRIPT_OR_DATA,
  2050. ATTR_WHITESPACE,
  2051. CUSTOM_ELEMENT
  2052. } = EXPRESSIONS;
  2053. let {
  2054. IS_ALLOWED_URI: IS_ALLOWED_URI$1
  2055. } = EXPRESSIONS;
  2056. /**
  2057. * We consider the elements and attributes below to be safe. Ideally
  2058. * don't add any new ones but feel free to remove unwanted ones.
  2059. */
  2060. /* allowed element names */
  2061. let ALLOWED_TAGS = null;
  2062. const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
  2063. /* Allowed attribute names */
  2064. let ALLOWED_ATTR = null;
  2065. const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
  2066. /*
  2067. * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.
  2068. * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
  2069. * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
  2070. * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
  2071. */
  2072. let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
  2073. tagNameCheck: {
  2074. writable: true,
  2075. configurable: false,
  2076. enumerable: true,
  2077. value: null
  2078. },
  2079. attributeNameCheck: {
  2080. writable: true,
  2081. configurable: false,
  2082. enumerable: true,
  2083. value: null
  2084. },
  2085. allowCustomizedBuiltInElements: {
  2086. writable: true,
  2087. configurable: false,
  2088. enumerable: true,
  2089. value: false
  2090. }
  2091. }));
  2092. /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
  2093. let FORBID_TAGS = null;
  2094. /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
  2095. let FORBID_ATTR = null;
  2096. /* Decide if ARIA attributes are okay */
  2097. let ALLOW_ARIA_ATTR = true;
  2098. /* Decide if custom data attributes are okay */
  2099. let ALLOW_DATA_ATTR = true;
  2100. /* Decide if unknown protocols are okay */
  2101. let ALLOW_UNKNOWN_PROTOCOLS = false;
  2102. /* Decide if self-closing tags in attributes are allowed.
  2103. * Usually removed due to a mXSS issue in jQuery 3.0 */
  2104. let ALLOW_SELF_CLOSE_IN_ATTR = true;
  2105. /* Output should be safe for common template engines.
  2106. * This means, DOMPurify removes data attributes, mustaches and ERB
  2107. */
  2108. let SAFE_FOR_TEMPLATES = false;
  2109. /* Output should be safe even for XML used within HTML and alike.
  2110. * This means, DOMPurify removes comments when containing risky content.
  2111. */
  2112. let SAFE_FOR_XML = true;
  2113. /* Decide if document with <html>... should be returned */
  2114. let WHOLE_DOCUMENT = false;
  2115. /* Track whether config is already set on this instance of DOMPurify. */
  2116. let SET_CONFIG = false;
  2117. /* Decide if all elements (e.g. style, script) must be children of
  2118. * document.body. By default, browsers might move them to document.head */
  2119. let FORCE_BODY = false;
  2120. /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
  2121. * string (or a TrustedHTML object if Trusted Types are supported).
  2122. * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
  2123. */
  2124. let RETURN_DOM = false;
  2125. /* Decide if a DOM `DocumentFragment` should be returned, instead of a html
  2126. * string (or a TrustedHTML object if Trusted Types are supported) */
  2127. let RETURN_DOM_FRAGMENT = false;
  2128. /* Try to return a Trusted Type object instead of a string, return a string in
  2129. * case Trusted Types are not supported */
  2130. let RETURN_TRUSTED_TYPE = false;
  2131. /* Output should be free from DOM clobbering attacks?
  2132. * This sanitizes markups named with colliding, clobberable built-in DOM APIs.
  2133. */
  2134. let SANITIZE_DOM = true;
  2135. /* Achieve full DOM Clobbering protection by isolating the namespace of named
  2136. * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
  2137. *
  2138. * HTML/DOM spec rules that enable DOM Clobbering:
  2139. * - Named Access on Window (§7.3.3)
  2140. * - DOM Tree Accessors (§3.1.5)
  2141. * - Form Element Parent-Child Relations (§4.10.3)
  2142. * - Iframe srcdoc / Nested WindowProxies (§4.8.5)
  2143. * - HTMLCollection (§4.2.10.2)
  2144. *
  2145. * Namespace isolation is implemented by prefixing `id` and `name` attributes
  2146. * with a constant string, i.e., `user-content-`
  2147. */
  2148. let SANITIZE_NAMED_PROPS = false;
  2149. const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
  2150. /* Keep element content when removing element? */
  2151. let KEEP_CONTENT = true;
  2152. /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
  2153. * of importing it into a new Document and returning a sanitized copy */
  2154. let IN_PLACE = false;
  2155. /* Allow usage of profiles like html, svg and mathMl */
  2156. let USE_PROFILES = {};
  2157. /* Tags to ignore content of when KEEP_CONTENT is true */
  2158. let FORBID_CONTENTS = null;
  2159. 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']);
  2160. /* Tags that are safe for data: URIs */
  2161. let DATA_URI_TAGS = null;
  2162. const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
  2163. /* Attributes safe for values like "javascript:" */
  2164. let URI_SAFE_ATTRIBUTES = null;
  2165. const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
  2166. const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
  2167. const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
  2168. const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
  2169. /* Document namespace */
  2170. let NAMESPACE = HTML_NAMESPACE;
  2171. let IS_EMPTY_INPUT = false;
  2172. /* Allowed XHTML+XML namespaces */
  2173. let ALLOWED_NAMESPACES = null;
  2174. const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
  2175. let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
  2176. let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);
  2177. // Certain elements are allowed in both SVG and HTML
  2178. // namespace. We need to specify them explicitly
  2179. // so that they don't get erroneously deleted from
  2180. // HTML namespace.
  2181. const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
  2182. /* Parsing of strict XHTML documents */
  2183. let PARSER_MEDIA_TYPE = null;
  2184. const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
  2185. const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
  2186. let transformCaseFunc = null;
  2187. /* Keep a reference to config to pass to hooks */
  2188. let CONFIG = null;
  2189. /* Ideally, do not touch anything below this line */
  2190. /* ______________________________________________ */
  2191. const formElement = document.createElement('form');
  2192. const isRegexOrFunction = function isRegexOrFunction(testValue) {
  2193. return testValue instanceof RegExp || testValue instanceof Function;
  2194. };
  2195. /**
  2196. * _parseConfig
  2197. *
  2198. * @param cfg optional config literal
  2199. */
  2200. // eslint-disable-next-line complexity
  2201. const _parseConfig = function _parseConfig() {
  2202. let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  2203. if (CONFIG && CONFIG === cfg) {
  2204. return;
  2205. }
  2206. /* Shield configuration object from tampering */
  2207. if (!cfg || typeof cfg !== 'object') {
  2208. cfg = {};
  2209. }
  2210. /* Shield configuration object from prototype pollution */
  2211. cfg = clone(cfg);
  2212. PARSER_MEDIA_TYPE =
  2213. // eslint-disable-next-line unicorn/prefer-includes
  2214. SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
  2215. // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
  2216. transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
  2217. /* Set configuration parameters */
  2218. ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
  2219. ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
  2220. ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
  2221. URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
  2222. DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
  2223. FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
  2224. FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
  2225. FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
  2226. USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;
  2227. ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
  2228. ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
  2229. ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
  2230. ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
  2231. SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
  2232. SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true
  2233. WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
  2234. RETURN_DOM = cfg.RETURN_DOM || false; // Default false
  2235. RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
  2236. RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
  2237. FORCE_BODY = cfg.FORCE_BODY || false; // Default false
  2238. SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
  2239. SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
  2240. KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
  2241. IN_PLACE = cfg.IN_PLACE || false; // Default false
  2242. IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;
  2243. NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
  2244. MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;
  2245. HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;
  2246. CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
  2247. if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
  2248. CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
  2249. }
  2250. if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {
  2251. CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;
  2252. }
  2253. if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {
  2254. CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
  2255. }
  2256. if (SAFE_FOR_TEMPLATES) {
  2257. ALLOW_DATA_ATTR = false;
  2258. }
  2259. if (RETURN_DOM_FRAGMENT) {
  2260. RETURN_DOM = true;
  2261. }
  2262. /* Parse profile info */
  2263. if (USE_PROFILES) {
  2264. ALLOWED_TAGS = addToSet({}, text);
  2265. ALLOWED_ATTR = [];
  2266. if (USE_PROFILES.html === true) {
  2267. addToSet(ALLOWED_TAGS, html$1);
  2268. addToSet(ALLOWED_ATTR, html);
  2269. }
  2270. if (USE_PROFILES.svg === true) {
  2271. addToSet(ALLOWED_TAGS, svg$1);
  2272. addToSet(ALLOWED_ATTR, svg);
  2273. addToSet(ALLOWED_ATTR, xml);
  2274. }
  2275. if (USE_PROFILES.svgFilters === true) {
  2276. addToSet(ALLOWED_TAGS, svgFilters);
  2277. addToSet(ALLOWED_ATTR, svg);
  2278. addToSet(ALLOWED_ATTR, xml);
  2279. }
  2280. if (USE_PROFILES.mathMl === true) {
  2281. addToSet(ALLOWED_TAGS, mathMl$1);
  2282. addToSet(ALLOWED_ATTR, mathMl);
  2283. addToSet(ALLOWED_ATTR, xml);
  2284. }
  2285. }
  2286. /* Merge configuration parameters */
  2287. if (cfg.ADD_TAGS) {
  2288. if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
  2289. ALLOWED_TAGS = clone(ALLOWED_TAGS);
  2290. }
  2291. addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
  2292. }
  2293. if (cfg.ADD_ATTR) {
  2294. if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
  2295. ALLOWED_ATTR = clone(ALLOWED_ATTR);
  2296. }
  2297. addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
  2298. }
  2299. if (cfg.ADD_URI_SAFE_ATTR) {
  2300. addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
  2301. }
  2302. if (cfg.FORBID_CONTENTS) {
  2303. if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
  2304. FORBID_CONTENTS = clone(FORBID_CONTENTS);
  2305. }
  2306. addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
  2307. }
  2308. /* Add #text in case KEEP_CONTENT is set to true */
  2309. if (KEEP_CONTENT) {
  2310. ALLOWED_TAGS['#text'] = true;
  2311. }
  2312. /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
  2313. if (WHOLE_DOCUMENT) {
  2314. addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
  2315. }
  2316. /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
  2317. if (ALLOWED_TAGS.table) {
  2318. addToSet(ALLOWED_TAGS, ['tbody']);
  2319. delete FORBID_TAGS.tbody;
  2320. }
  2321. if (cfg.TRUSTED_TYPES_POLICY) {
  2322. if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {
  2323. throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
  2324. }
  2325. if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {
  2326. throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
  2327. }
  2328. // Overwrite existing TrustedTypes policy.
  2329. trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
  2330. // Sign local variables required by `sanitize`.
  2331. emptyHTML = trustedTypesPolicy.createHTML('');
  2332. } else {
  2333. // Uninitialized policy, attempt to initialize the internal dompurify policy.
  2334. if (trustedTypesPolicy === undefined) {
  2335. trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
  2336. }
  2337. // If creating the internal policy succeeded sign internal variables.
  2338. if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {
  2339. emptyHTML = trustedTypesPolicy.createHTML('');
  2340. }
  2341. }
  2342. // Prevent further manipulation of configuration.
  2343. // Not available in IE8, Safari 5, etc.
  2344. if (freeze) {
  2345. freeze(cfg);
  2346. }
  2347. CONFIG = cfg;
  2348. };
  2349. /* Keep track of all possible SVG and MathML tags
  2350. * so that we can perform the namespace checks
  2351. * correctly. */
  2352. const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
  2353. const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
  2354. /**
  2355. * @param element a DOM element whose namespace is being checked
  2356. * @returns Return false if the element has a
  2357. * namespace that a spec-compliant parser would never
  2358. * return. Return true otherwise.
  2359. */
  2360. const _checkValidNamespace = function _checkValidNamespace(element) {
  2361. let parent = getParentNode(element);
  2362. // In JSDOM, if we're inside shadow DOM, then parentNode
  2363. // can be null. We just simulate parent in this case.
  2364. if (!parent || !parent.tagName) {
  2365. parent = {
  2366. namespaceURI: NAMESPACE,
  2367. tagName: 'template'
  2368. };
  2369. }
  2370. const tagName = stringToLowerCase(element.tagName);
  2371. const parentTagName = stringToLowerCase(parent.tagName);
  2372. if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
  2373. return false;
  2374. }
  2375. if (element.namespaceURI === SVG_NAMESPACE) {
  2376. // The only way to switch from HTML namespace to SVG
  2377. // is via <svg>. If it happens via any other tag, then
  2378. // it should be killed.
  2379. if (parent.namespaceURI === HTML_NAMESPACE) {
  2380. return tagName === 'svg';
  2381. }
  2382. // The only way to switch from MathML to SVG is via`
  2383. // svg if parent is either <annotation-xml> or MathML
  2384. // text integration points.
  2385. if (parent.namespaceURI === MATHML_NAMESPACE) {
  2386. return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
  2387. }
  2388. // We only allow elements that are defined in SVG
  2389. // spec. All others are disallowed in SVG namespace.
  2390. return Boolean(ALL_SVG_TAGS[tagName]);
  2391. }
  2392. if (element.namespaceURI === MATHML_NAMESPACE) {
  2393. // The only way to switch from HTML namespace to MathML
  2394. // is via <math>. If it happens via any other tag, then
  2395. // it should be killed.
  2396. if (parent.namespaceURI === HTML_NAMESPACE) {
  2397. return tagName === 'math';
  2398. }
  2399. // The only way to switch from SVG to MathML is via
  2400. // <math> and HTML integration points
  2401. if (parent.namespaceURI === SVG_NAMESPACE) {
  2402. return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
  2403. }
  2404. // We only allow elements that are defined in MathML
  2405. // spec. All others are disallowed in MathML namespace.
  2406. return Boolean(ALL_MATHML_TAGS[tagName]);
  2407. }
  2408. if (element.namespaceURI === HTML_NAMESPACE) {
  2409. // The only way to switch from SVG to HTML is via
  2410. // HTML integration points, and from MathML to HTML
  2411. // is via MathML text integration points
  2412. if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
  2413. return false;
  2414. }
  2415. if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
  2416. return false;
  2417. }
  2418. // We disallow tags that are specific for MathML
  2419. // or SVG and should never appear in HTML namespace
  2420. return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
  2421. }
  2422. // For XHTML and XML documents that support custom namespaces
  2423. if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {
  2424. return true;
  2425. }
  2426. // The code should never reach this place (this means
  2427. // that the element somehow got namespace that is not
  2428. // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).
  2429. // Return false just in case.
  2430. return false;
  2431. };
  2432. /**
  2433. * _forceRemove
  2434. *
  2435. * @param node a DOM node
  2436. */
  2437. const _forceRemove = function _forceRemove(node) {
  2438. arrayPush(DOMPurify.removed, {
  2439. element: node
  2440. });
  2441. try {
  2442. // eslint-disable-next-line unicorn/prefer-dom-node-remove
  2443. getParentNode(node).removeChild(node);
  2444. } catch (_) {
  2445. remove(node);
  2446. }
  2447. };
  2448. /**
  2449. * _removeAttribute
  2450. *
  2451. * @param name an Attribute name
  2452. * @param element a DOM node
  2453. */
  2454. const _removeAttribute = function _removeAttribute(name, element) {
  2455. try {
  2456. arrayPush(DOMPurify.removed, {
  2457. attribute: element.getAttributeNode(name),
  2458. from: element
  2459. });
  2460. } catch (_) {
  2461. arrayPush(DOMPurify.removed, {
  2462. attribute: null,
  2463. from: element
  2464. });
  2465. }
  2466. element.removeAttribute(name);
  2467. // We void attribute values for unremovable "is" attributes
  2468. if (name === 'is') {
  2469. if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
  2470. try {
  2471. _forceRemove(element);
  2472. } catch (_) {}
  2473. } else {
  2474. try {
  2475. element.setAttribute(name, '');
  2476. } catch (_) {}
  2477. }
  2478. }
  2479. };
  2480. /**
  2481. * _initDocument
  2482. *
  2483. * @param dirty - a string of dirty markup
  2484. * @return a DOM, filled with the dirty markup
  2485. */
  2486. const _initDocument = function _initDocument(dirty) {
  2487. /* Create a HTML document */
  2488. let doc = null;
  2489. let leadingWhitespace = null;
  2490. if (FORCE_BODY) {
  2491. dirty = '<remove></remove>' + dirty;
  2492. } else {
  2493. /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
  2494. const matches = stringMatch(dirty, /^[\r\n\t ]+/);
  2495. leadingWhitespace = matches && matches[0];
  2496. }
  2497. if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {
  2498. // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
  2499. dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
  2500. }
  2501. const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
  2502. /*
  2503. * Use the DOMParser API by default, fallback later if needs be
  2504. * DOMParser not work for svg when has multiple root element.
  2505. */
  2506. if (NAMESPACE === HTML_NAMESPACE) {
  2507. try {
  2508. doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
  2509. } catch (_) {}
  2510. }
  2511. /* Use createHTMLDocument in case DOMParser is not available */
  2512. if (!doc || !doc.documentElement) {
  2513. doc = implementation.createDocument(NAMESPACE, 'template', null);
  2514. try {
  2515. doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
  2516. } catch (_) {
  2517. // Syntax error if dirtyPayload is invalid xml
  2518. }
  2519. }
  2520. const body = doc.body || doc.documentElement;
  2521. if (dirty && leadingWhitespace) {
  2522. body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
  2523. }
  2524. /* Work on whole document or just its body */
  2525. if (NAMESPACE === HTML_NAMESPACE) {
  2526. return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
  2527. }
  2528. return WHOLE_DOCUMENT ? doc.documentElement : body;
  2529. };
  2530. /**
  2531. * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
  2532. *
  2533. * @param root The root element or node to start traversing on.
  2534. * @return The created NodeIterator
  2535. */
  2536. const _createNodeIterator = function _createNodeIterator(root) {
  2537. return createNodeIterator.call(root.ownerDocument || root, root,
  2538. // eslint-disable-next-line no-bitwise
  2539. NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
  2540. };
  2541. /**
  2542. * _isClobbered
  2543. *
  2544. * @param element element to check for clobbering attacks
  2545. * @return true if clobbered, false if safe
  2546. */
  2547. const _isClobbered = function _isClobbered(element) {
  2548. 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');
  2549. };
  2550. /**
  2551. * Checks whether the given object is a DOM node.
  2552. *
  2553. * @param value object to check whether it's a DOM node
  2554. * @return true is object is a DOM node
  2555. */
  2556. const _isNode = function _isNode(value) {
  2557. return typeof Node === 'function' && value instanceof Node;
  2558. };
  2559. function _executeHooks(hooks, currentNode, data) {
  2560. arrayForEach(hooks, hook => {
  2561. hook.call(DOMPurify, currentNode, data, CONFIG);
  2562. });
  2563. }
  2564. /**
  2565. * _sanitizeElements
  2566. *
  2567. * @protect nodeName
  2568. * @protect textContent
  2569. * @protect removeChild
  2570. * @param currentNode to check for permission to exist
  2571. * @return true if node was killed, false if left alive
  2572. */
  2573. const _sanitizeElements = function _sanitizeElements(currentNode) {
  2574. let content = null;
  2575. /* Execute a hook if present */
  2576. _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
  2577. /* Check if element is clobbered or can clobber */
  2578. if (_isClobbered(currentNode)) {
  2579. _forceRemove(currentNode);
  2580. return true;
  2581. }
  2582. /* Now let's check the element's type and name */
  2583. const tagName = transformCaseFunc(currentNode.nodeName);
  2584. /* Execute a hook if present */
  2585. _executeHooks(hooks.uponSanitizeElement, currentNode, {
  2586. tagName,
  2587. allowedTags: ALLOWED_TAGS
  2588. });
  2589. /* Detect mXSS attempts abusing namespace confusion */
  2590. if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
  2591. _forceRemove(currentNode);
  2592. return true;
  2593. }
  2594. /* Remove any occurrence of processing instructions */
  2595. if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
  2596. _forceRemove(currentNode);
  2597. return true;
  2598. }
  2599. /* Remove any kind of possibly harmful comments */
  2600. if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
  2601. _forceRemove(currentNode);
  2602. return true;
  2603. }
  2604. /* Remove element if anything forbids its presence */
  2605. if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
  2606. /* Check if we have a custom element to handle */
  2607. if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
  2608. if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
  2609. return false;
  2610. }
  2611. if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
  2612. return false;
  2613. }
  2614. }
  2615. /* Keep content except for bad-listed elements */
  2616. if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
  2617. const parentNode = getParentNode(currentNode) || currentNode.parentNode;
  2618. const childNodes = getChildNodes(currentNode) || currentNode.childNodes;
  2619. if (childNodes && parentNode) {
  2620. const childCount = childNodes.length;
  2621. for (let i = childCount - 1; i >= 0; --i) {
  2622. const childClone = cloneNode(childNodes[i], true);
  2623. childClone.__removalCount = (currentNode.__removalCount || 0) + 1;
  2624. parentNode.insertBefore(childClone, getNextSibling(currentNode));
  2625. }
  2626. }
  2627. }
  2628. _forceRemove(currentNode);
  2629. return true;
  2630. }
  2631. /* Check whether element has a valid namespace */
  2632. if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
  2633. _forceRemove(currentNode);
  2634. return true;
  2635. }
  2636. /* Make sure that older browsers don't get fallback-tag mXSS */
  2637. if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
  2638. _forceRemove(currentNode);
  2639. return true;
  2640. }
  2641. /* Sanitize element content to be template-safe */
  2642. if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
  2643. /* Get the element's text content */
  2644. content = currentNode.textContent;
  2645. arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
  2646. content = stringReplace(content, expr, ' ');
  2647. });
  2648. if (currentNode.textContent !== content) {
  2649. arrayPush(DOMPurify.removed, {
  2650. element: currentNode.cloneNode()
  2651. });
  2652. currentNode.textContent = content;
  2653. }
  2654. }
  2655. /* Execute a hook if present */
  2656. _executeHooks(hooks.afterSanitizeElements, currentNode, null);
  2657. return false;
  2658. };
  2659. /**
  2660. * _isValidAttribute
  2661. *
  2662. * @param lcTag Lowercase tag name of containing element.
  2663. * @param lcName Lowercase attribute name.
  2664. * @param value Attribute value.
  2665. * @return Returns true if `value` is valid, otherwise false.
  2666. */
  2667. // eslint-disable-next-line complexity
  2668. const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
  2669. /* Make sure attribute cannot clobber */
  2670. if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
  2671. return false;
  2672. }
  2673. /* Allow valid data-* attributes: At least one character after "-"
  2674. (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
  2675. XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
  2676. We don't need to check the value; it's always URI safe. */
  2677. if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ;else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ;else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
  2678. if (
  2679. // First condition does a very basic check if a) it's basically a valid custom element tagname AND
  2680. // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
  2681. // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
  2682. _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)) ||
  2683. // Alternative, second condition checks if it's an `is`-attribute, AND
  2684. // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
  2685. 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 {
  2686. return false;
  2687. }
  2688. /* Check value is safe. First, is attr inert? If so, is safe */
  2689. } 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) {
  2690. return false;
  2691. } else ;
  2692. return true;
  2693. };
  2694. /**
  2695. * _isBasicCustomElement
  2696. * checks if at least one dash is included in tagName, and it's not the first char
  2697. * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
  2698. *
  2699. * @param tagName name of the tag of the node to sanitize
  2700. * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
  2701. */
  2702. const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
  2703. return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);
  2704. };
  2705. /**
  2706. * _sanitizeAttributes
  2707. *
  2708. * @protect attributes
  2709. * @protect nodeName
  2710. * @protect removeAttribute
  2711. * @protect setAttribute
  2712. *
  2713. * @param currentNode to sanitize
  2714. */
  2715. const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
  2716. /* Execute a hook if present */
  2717. _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
  2718. const {
  2719. attributes
  2720. } = currentNode;
  2721. /* Check if we have attributes; if not we might have a text node */
  2722. if (!attributes || _isClobbered(currentNode)) {
  2723. return;
  2724. }
  2725. const hookEvent = {
  2726. attrName: '',
  2727. attrValue: '',
  2728. keepAttr: true,
  2729. allowedAttributes: ALLOWED_ATTR,
  2730. forceKeepAttr: undefined
  2731. };
  2732. let l = attributes.length;
  2733. /* Go backwards over all attributes; safely remove bad ones */
  2734. while (l--) {
  2735. const attr = attributes[l];
  2736. const {
  2737. name,
  2738. namespaceURI,
  2739. value: attrValue
  2740. } = attr;
  2741. const lcName = transformCaseFunc(name);
  2742. let value = name === 'value' ? attrValue : stringTrim(attrValue);
  2743. /* Execute a hook if present */
  2744. hookEvent.attrName = lcName;
  2745. hookEvent.attrValue = value;
  2746. hookEvent.keepAttr = true;
  2747. hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
  2748. _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
  2749. value = hookEvent.attrValue;
  2750. /* Full DOM Clobbering protection via namespace isolation,
  2751. * Prefix id and name attributes with `user-content-`
  2752. */
  2753. if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
  2754. // Remove the attribute with this value
  2755. _removeAttribute(name, currentNode);
  2756. // Prefix the value and later re-create the attribute with the sanitized value
  2757. value = SANITIZE_NAMED_PROPS_PREFIX + value;
  2758. }
  2759. /* Work around a security issue with comments inside attributes */
  2760. if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
  2761. _removeAttribute(name, currentNode);
  2762. continue;
  2763. }
  2764. /* Did the hooks approve of the attribute? */
  2765. if (hookEvent.forceKeepAttr) {
  2766. continue;
  2767. }
  2768. /* Remove attribute */
  2769. _removeAttribute(name, currentNode);
  2770. /* Did the hooks approve of the attribute? */
  2771. if (!hookEvent.keepAttr) {
  2772. continue;
  2773. }
  2774. /* Work around a security issue in jQuery 3.0 */
  2775. if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
  2776. _removeAttribute(name, currentNode);
  2777. continue;
  2778. }
  2779. /* Sanitize attribute content to be template-safe */
  2780. if (SAFE_FOR_TEMPLATES) {
  2781. arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
  2782. value = stringReplace(value, expr, ' ');
  2783. });
  2784. }
  2785. /* Is `value` valid for this attribute? */
  2786. const lcTag = transformCaseFunc(currentNode.nodeName);
  2787. if (!_isValidAttribute(lcTag, lcName, value)) {
  2788. continue;
  2789. }
  2790. /* Handle attributes that require Trusted Types */
  2791. if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {
  2792. if (namespaceURI) ;else {
  2793. switch (trustedTypes.getAttributeType(lcTag, lcName)) {
  2794. case 'TrustedHTML':
  2795. {
  2796. value = trustedTypesPolicy.createHTML(value);
  2797. break;
  2798. }
  2799. case 'TrustedScriptURL':
  2800. {
  2801. value = trustedTypesPolicy.createScriptURL(value);
  2802. break;
  2803. }
  2804. }
  2805. }
  2806. }
  2807. /* Handle invalid data-* attribute set by try-catching it */
  2808. try {
  2809. if (namespaceURI) {
  2810. currentNode.setAttributeNS(namespaceURI, name, value);
  2811. } else {
  2812. /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
  2813. currentNode.setAttribute(name, value);
  2814. }
  2815. if (_isClobbered(currentNode)) {
  2816. _forceRemove(currentNode);
  2817. } else {
  2818. arrayPop(DOMPurify.removed);
  2819. }
  2820. } catch (_) {}
  2821. }
  2822. /* Execute a hook if present */
  2823. _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
  2824. };
  2825. /**
  2826. * _sanitizeShadowDOM
  2827. *
  2828. * @param fragment to iterate over recursively
  2829. */
  2830. const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
  2831. let shadowNode = null;
  2832. const shadowIterator = _createNodeIterator(fragment);
  2833. /* Execute a hook if present */
  2834. _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
  2835. while (shadowNode = shadowIterator.nextNode()) {
  2836. /* Execute a hook if present */
  2837. _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
  2838. /* Sanitize tags and elements */
  2839. _sanitizeElements(shadowNode);
  2840. /* Check attributes next */
  2841. _sanitizeAttributes(shadowNode);
  2842. /* Deep shadow DOM detected */
  2843. if (shadowNode.content instanceof DocumentFragment) {
  2844. _sanitizeShadowDOM(shadowNode.content);
  2845. }
  2846. }
  2847. /* Execute a hook if present */
  2848. _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
  2849. };
  2850. // eslint-disable-next-line complexity
  2851. DOMPurify.sanitize = function (dirty) {
  2852. let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  2853. let body = null;
  2854. let importedNode = null;
  2855. let currentNode = null;
  2856. let returnNode = null;
  2857. /* Make sure we have a string to sanitize.
  2858. DO NOT return early, as this will return the wrong type if
  2859. the user has requested a DOM object rather than a string */
  2860. IS_EMPTY_INPUT = !dirty;
  2861. if (IS_EMPTY_INPUT) {
  2862. dirty = '<!-->';
  2863. }
  2864. /* Stringify, in case dirty is an object */
  2865. if (typeof dirty !== 'string' && !_isNode(dirty)) {
  2866. if (typeof dirty.toString === 'function') {
  2867. dirty = dirty.toString();
  2868. if (typeof dirty !== 'string') {
  2869. throw typeErrorCreate('dirty is not a string, aborting');
  2870. }
  2871. } else {
  2872. throw typeErrorCreate('toString is not a function');
  2873. }
  2874. }
  2875. /* Return dirty HTML if DOMPurify cannot run */
  2876. if (!DOMPurify.isSupported) {
  2877. return dirty;
  2878. }
  2879. /* Assign config vars */
  2880. if (!SET_CONFIG) {
  2881. _parseConfig(cfg);
  2882. }
  2883. /* Clean up removed elements */
  2884. DOMPurify.removed = [];
  2885. /* Check if dirty is correctly typed for IN_PLACE */
  2886. if (typeof dirty === 'string') {
  2887. IN_PLACE = false;
  2888. }
  2889. if (IN_PLACE) {
  2890. /* Do some early pre-sanitization to avoid unsafe root nodes */
  2891. if (dirty.nodeName) {
  2892. const tagName = transformCaseFunc(dirty.nodeName);
  2893. if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
  2894. throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
  2895. }
  2896. }
  2897. } else if (dirty instanceof Node) {
  2898. /* If dirty is a DOM element, append to an empty document to avoid
  2899. elements being stripped by the parser */
  2900. body = _initDocument('<!---->');
  2901. importedNode = body.ownerDocument.importNode(dirty, true);
  2902. if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {
  2903. /* Node is already a body, use as is */
  2904. body = importedNode;
  2905. } else if (importedNode.nodeName === 'HTML') {
  2906. body = importedNode;
  2907. } else {
  2908. // eslint-disable-next-line unicorn/prefer-dom-node-append
  2909. body.appendChild(importedNode);
  2910. }
  2911. } else {
  2912. /* Exit directly if we have nothing to do */
  2913. if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
  2914. // eslint-disable-next-line unicorn/prefer-includes
  2915. dirty.indexOf('<') === -1) {
  2916. return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
  2917. }
  2918. /* Initialize the document to work on */
  2919. body = _initDocument(dirty);
  2920. /* Check we have a DOM node from the data */
  2921. if (!body) {
  2922. return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
  2923. }
  2924. }
  2925. /* Remove first element node (ours) if FORCE_BODY is set */
  2926. if (body && FORCE_BODY) {
  2927. _forceRemove(body.firstChild);
  2928. }
  2929. /* Get node iterator */
  2930. const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
  2931. /* Now start iterating over the created document */
  2932. while (currentNode = nodeIterator.nextNode()) {
  2933. /* Sanitize tags and elements */
  2934. _sanitizeElements(currentNode);
  2935. /* Check attributes next */
  2936. _sanitizeAttributes(currentNode);
  2937. /* Shadow DOM detected, sanitize it */
  2938. if (currentNode.content instanceof DocumentFragment) {
  2939. _sanitizeShadowDOM(currentNode.content);
  2940. }
  2941. }
  2942. /* If we sanitized `dirty` in-place, return it. */
  2943. if (IN_PLACE) {
  2944. return dirty;
  2945. }
  2946. /* Return sanitized string or DOM */
  2947. if (RETURN_DOM) {
  2948. if (RETURN_DOM_FRAGMENT) {
  2949. returnNode = createDocumentFragment.call(body.ownerDocument);
  2950. while (body.firstChild) {
  2951. // eslint-disable-next-line unicorn/prefer-dom-node-append
  2952. returnNode.appendChild(body.firstChild);
  2953. }
  2954. } else {
  2955. returnNode = body;
  2956. }
  2957. if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
  2958. /*
  2959. AdoptNode() is not used because internal state is not reset
  2960. (e.g. the past names map of a HTMLFormElement), this is safe
  2961. in theory but we would rather not risk another attack vector.
  2962. The state that is cloned by importNode() is explicitly defined
  2963. by the specs.
  2964. */
  2965. returnNode = importNode.call(originalDocument, returnNode, true);
  2966. }
  2967. return returnNode;
  2968. }
  2969. let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
  2970. /* Serialize doctype if allowed */
  2971. if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
  2972. serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
  2973. }
  2974. /* Sanitize final string template-safe */
  2975. if (SAFE_FOR_TEMPLATES) {
  2976. arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
  2977. serializedHTML = stringReplace(serializedHTML, expr, ' ');
  2978. });
  2979. }
  2980. return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
  2981. };
  2982. DOMPurify.setConfig = function () {
  2983. let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  2984. _parseConfig(cfg);
  2985. SET_CONFIG = true;
  2986. };
  2987. DOMPurify.clearConfig = function () {
  2988. CONFIG = null;
  2989. SET_CONFIG = false;
  2990. };
  2991. DOMPurify.isValidAttribute = function (tag, attr, value) {
  2992. /* Initialize shared config vars if necessary. */
  2993. if (!CONFIG) {
  2994. _parseConfig({});
  2995. }
  2996. const lcTag = transformCaseFunc(tag);
  2997. const lcName = transformCaseFunc(attr);
  2998. return _isValidAttribute(lcTag, lcName, value);
  2999. };
  3000. DOMPurify.addHook = function (entryPoint, hookFunction) {
  3001. if (typeof hookFunction !== 'function') {
  3002. return;
  3003. }
  3004. arrayPush(hooks[entryPoint], hookFunction);
  3005. };
  3006. DOMPurify.removeHook = function (entryPoint) {
  3007. return arrayPop(hooks[entryPoint]);
  3008. };
  3009. DOMPurify.removeHooks = function (entryPoint) {
  3010. hooks[entryPoint] = [];
  3011. };
  3012. DOMPurify.removeAllHooks = function () {
  3013. hooks = _createHooksMap();
  3014. };
  3015. return DOMPurify;
  3016. }
  3017. var purify = createDOMPurify();
  3018. const DEFAULT_ALLOWED_ATTRIBUTES = "style href src width height language class".split(" ");
  3019. const DEFAULT_FORBIDDEN_PROTOCOLS = "javascript:".split(" ");
  3020. const DEFAULT_FORBIDDEN_ELEMENTS = "script iframe form noscript".split(" ");
  3021. class HTMLSanitizer extends BasicObject {
  3022. static setHTML(element, html) {
  3023. const sanitizedElement = new this(html).sanitize();
  3024. const sanitizedHtml = sanitizedElement.getHTML ? sanitizedElement.getHTML() : sanitizedElement.outerHTML;
  3025. element.innerHTML = sanitizedHtml;
  3026. }
  3027. static sanitize(html, options) {
  3028. const sanitizer = new this(html, options);
  3029. sanitizer.sanitize();
  3030. return sanitizer;
  3031. }
  3032. constructor(html) {
  3033. let {
  3034. allowedAttributes,
  3035. forbiddenProtocols,
  3036. forbiddenElements
  3037. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  3038. super(...arguments);
  3039. this.allowedAttributes = allowedAttributes || DEFAULT_ALLOWED_ATTRIBUTES;
  3040. this.forbiddenProtocols = forbiddenProtocols || DEFAULT_FORBIDDEN_PROTOCOLS;
  3041. this.forbiddenElements = forbiddenElements || DEFAULT_FORBIDDEN_ELEMENTS;
  3042. this.body = createBodyElementForHTML(html);
  3043. }
  3044. sanitize() {
  3045. this.sanitizeElements();
  3046. this.normalizeListElementNesting();
  3047. return purify.sanitize(this.body, {
  3048. ADD_ATTR: ["language"],
  3049. RETURN_DOM: true
  3050. });
  3051. }
  3052. getHTML() {
  3053. return this.body.innerHTML;
  3054. }
  3055. getBody() {
  3056. return this.body;
  3057. }
  3058. // Private
  3059. sanitizeElements() {
  3060. const walker = walkTree(this.body);
  3061. const nodesToRemove = [];
  3062. while (walker.nextNode()) {
  3063. const node = walker.currentNode;
  3064. switch (node.nodeType) {
  3065. case Node.ELEMENT_NODE:
  3066. if (this.elementIsRemovable(node)) {
  3067. nodesToRemove.push(node);
  3068. } else {
  3069. this.sanitizeElement(node);
  3070. }
  3071. break;
  3072. case Node.COMMENT_NODE:
  3073. nodesToRemove.push(node);
  3074. break;
  3075. }
  3076. }
  3077. nodesToRemove.forEach(node => removeNode(node));
  3078. return this.body;
  3079. }
  3080. sanitizeElement(element) {
  3081. if (element.hasAttribute("href")) {
  3082. if (this.forbiddenProtocols.includes(element.protocol)) {
  3083. element.removeAttribute("href");
  3084. }
  3085. }
  3086. Array.from(element.attributes).forEach(_ref => {
  3087. let {
  3088. name
  3089. } = _ref;
  3090. if (!this.allowedAttributes.includes(name) && name.indexOf("data-trix") !== 0) {
  3091. element.removeAttribute(name);
  3092. }
  3093. });
  3094. return element;
  3095. }
  3096. normalizeListElementNesting() {
  3097. Array.from(this.body.querySelectorAll("ul,ol")).forEach(listElement => {
  3098. const previousElement = listElement.previousElementSibling;
  3099. if (previousElement) {
  3100. if (tagName(previousElement) === "li") {
  3101. previousElement.appendChild(listElement);
  3102. }
  3103. }
  3104. });
  3105. return this.body;
  3106. }
  3107. elementIsRemovable(element) {
  3108. if ((element === null || element === void 0 ? void 0 : element.nodeType) !== Node.ELEMENT_NODE) return;
  3109. return this.elementIsForbidden(element) || this.elementIsntSerializable(element);
  3110. }
  3111. elementIsForbidden(element) {
  3112. return this.forbiddenElements.includes(tagName(element));
  3113. }
  3114. elementIsntSerializable(element) {
  3115. return element.getAttribute("data-trix-serialize") === "false" && !nodeIsAttachmentElement(element);
  3116. }
  3117. }
  3118. const createBodyElementForHTML = function () {
  3119. let html = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
  3120. // Remove everything after </html>
  3121. html = html.replace(/<\/html[^>]*>[^]*$/i, "</html>");
  3122. const doc = document.implementation.createHTMLDocument("");
  3123. doc.documentElement.innerHTML = html;
  3124. Array.from(doc.head.querySelectorAll("style")).forEach(element => {
  3125. doc.body.appendChild(element);
  3126. });
  3127. return doc.body;
  3128. };
  3129. const {
  3130. css: css$2
  3131. } = config;
  3132. class AttachmentView extends ObjectView {
  3133. constructor() {
  3134. super(...arguments);
  3135. this.attachment = this.object;
  3136. this.attachment.uploadProgressDelegate = this;
  3137. this.attachmentPiece = this.options.piece;
  3138. }
  3139. createContentNodes() {
  3140. return [];
  3141. }
  3142. createNodes() {
  3143. let innerElement;
  3144. const figure = innerElement = makeElement({
  3145. tagName: "figure",
  3146. className: this.getClassName(),
  3147. data: this.getData(),
  3148. editable: false
  3149. });
  3150. const href = this.getHref();
  3151. if (href) {
  3152. innerElement = makeElement({
  3153. tagName: "a",
  3154. editable: false,
  3155. attributes: {
  3156. href,
  3157. tabindex: -1
  3158. }
  3159. });
  3160. figure.appendChild(innerElement);
  3161. }
  3162. if (this.attachment.hasContent()) {
  3163. HTMLSanitizer.setHTML(innerElement, this.attachment.getContent());
  3164. } else {
  3165. this.createContentNodes().forEach(node => {
  3166. innerElement.appendChild(node);
  3167. });
  3168. }
  3169. innerElement.appendChild(this.createCaptionElement());
  3170. if (this.attachment.isPending()) {
  3171. this.progressElement = makeElement({
  3172. tagName: "progress",
  3173. attributes: {
  3174. class: css$2.attachmentProgress,
  3175. value: this.attachment.getUploadProgress(),
  3176. max: 100
  3177. },
  3178. data: {
  3179. trixMutable: true,
  3180. trixStoreKey: ["progressElement", this.attachment.id].join("/")
  3181. }
  3182. });
  3183. figure.appendChild(this.progressElement);
  3184. }
  3185. return [createCursorTarget("left"), figure, createCursorTarget("right")];
  3186. }
  3187. createCaptionElement() {
  3188. const figcaption = makeElement({
  3189. tagName: "figcaption",
  3190. className: css$2.attachmentCaption
  3191. });
  3192. const caption = this.attachmentPiece.getCaption();
  3193. if (caption) {
  3194. figcaption.classList.add("".concat(css$2.attachmentCaption, "--edited"));
  3195. figcaption.textContent = caption;
  3196. } else {
  3197. let name, size;
  3198. const captionConfig = this.getCaptionConfig();
  3199. if (captionConfig.name) {
  3200. name = this.attachment.getFilename();
  3201. }
  3202. if (captionConfig.size) {
  3203. size = this.attachment.getFormattedFilesize();
  3204. }
  3205. if (name) {
  3206. const nameElement = makeElement({
  3207. tagName: "span",
  3208. className: css$2.attachmentName,
  3209. textContent: name
  3210. });
  3211. figcaption.appendChild(nameElement);
  3212. }
  3213. if (size) {
  3214. if (name) {
  3215. figcaption.appendChild(document.createTextNode(" "));
  3216. }
  3217. const sizeElement = makeElement({
  3218. tagName: "span",
  3219. className: css$2.attachmentSize,
  3220. textContent: size
  3221. });
  3222. figcaption.appendChild(sizeElement);
  3223. }
  3224. }
  3225. return figcaption;
  3226. }
  3227. getClassName() {
  3228. const names = [css$2.attachment, "".concat(css$2.attachment, "--").concat(this.attachment.getType())];
  3229. const extension = this.attachment.getExtension();
  3230. if (extension) {
  3231. names.push("".concat(css$2.attachment, "--").concat(extension));
  3232. }
  3233. return names.join(" ");
  3234. }
  3235. getData() {
  3236. const data = {
  3237. trixAttachment: JSON.stringify(this.attachment),
  3238. trixContentType: this.attachment.getContentType(),
  3239. trixId: this.attachment.id
  3240. };
  3241. const {
  3242. attributes
  3243. } = this.attachmentPiece;
  3244. if (!attributes.isEmpty()) {
  3245. data.trixAttributes = JSON.stringify(attributes);
  3246. }
  3247. if (this.attachment.isPending()) {
  3248. data.trixSerialize = false;
  3249. }
  3250. return data;
  3251. }
  3252. getHref() {
  3253. if (!htmlContainsTagName(this.attachment.getContent(), "a")) {
  3254. return this.attachment.getHref();
  3255. }
  3256. }
  3257. getCaptionConfig() {
  3258. var _config$attachments$t;
  3259. const type = this.attachment.getType();
  3260. const captionConfig = copyObject((_config$attachments$t = attachments[type]) === null || _config$attachments$t === void 0 ? void 0 : _config$attachments$t.caption);
  3261. if (type === "file") {
  3262. captionConfig.name = true;
  3263. }
  3264. return captionConfig;
  3265. }
  3266. findProgressElement() {
  3267. var _this$findElement;
  3268. return (_this$findElement = this.findElement()) === null || _this$findElement === void 0 ? void 0 : _this$findElement.querySelector("progress");
  3269. }
  3270. // Attachment delegate
  3271. attachmentDidChangeUploadProgress() {
  3272. const value = this.attachment.getUploadProgress();
  3273. const progressElement = this.findProgressElement();
  3274. if (progressElement) {
  3275. progressElement.value = value;
  3276. }
  3277. }
  3278. }
  3279. const createCursorTarget = name => makeElement({
  3280. tagName: "span",
  3281. textContent: ZERO_WIDTH_SPACE,
  3282. data: {
  3283. trixCursorTarget: name,
  3284. trixSerialize: false
  3285. }
  3286. });
  3287. const htmlContainsTagName = function (html, tagName) {
  3288. const div = makeElement("div");
  3289. HTMLSanitizer.setHTML(div, html || "");
  3290. return div.querySelector(tagName);
  3291. };
  3292. class PreviewableAttachmentView extends AttachmentView {
  3293. constructor() {
  3294. super(...arguments);
  3295. this.attachment.previewDelegate = this;
  3296. }
  3297. createContentNodes() {
  3298. this.image = makeElement({
  3299. tagName: "img",
  3300. attributes: {
  3301. src: ""
  3302. },
  3303. data: {
  3304. trixMutable: true
  3305. }
  3306. });
  3307. this.refresh(this.image);
  3308. return [this.image];
  3309. }
  3310. createCaptionElement() {
  3311. const figcaption = super.createCaptionElement(...arguments);
  3312. if (!figcaption.textContent) {
  3313. figcaption.setAttribute("data-trix-placeholder", lang$1.captionPlaceholder);
  3314. }
  3315. return figcaption;
  3316. }
  3317. refresh(image) {
  3318. if (!image) {
  3319. var _this$findElement;
  3320. image = (_this$findElement = this.findElement()) === null || _this$findElement === void 0 ? void 0 : _this$findElement.querySelector("img");
  3321. }
  3322. if (image) {
  3323. return this.updateAttributesForImage(image);
  3324. }
  3325. }
  3326. updateAttributesForImage(image) {
  3327. const url = this.attachment.getURL();
  3328. const previewURL = this.attachment.getPreviewURL();
  3329. image.src = previewURL || url;
  3330. if (previewURL === url) {
  3331. image.removeAttribute("data-trix-serialized-attributes");
  3332. } else {
  3333. const serializedAttributes = JSON.stringify({
  3334. src: url
  3335. });
  3336. image.setAttribute("data-trix-serialized-attributes", serializedAttributes);
  3337. }
  3338. const width = this.attachment.getWidth();
  3339. const height = this.attachment.getHeight();
  3340. if (width != null) {
  3341. image.width = width;
  3342. }
  3343. if (height != null) {
  3344. image.height = height;
  3345. }
  3346. const storeKey = ["imageElement", this.attachment.id, image.src, image.width, image.height].join("/");
  3347. image.dataset.trixStoreKey = storeKey;
  3348. }
  3349. // Attachment delegate
  3350. attachmentDidChangeAttributes() {
  3351. this.refresh(this.image);
  3352. return this.refresh();
  3353. }
  3354. }
  3355. /* eslint-disable
  3356. no-useless-escape,
  3357. no-var,
  3358. */
  3359. class PieceView extends ObjectView {
  3360. constructor() {
  3361. super(...arguments);
  3362. this.piece = this.object;
  3363. this.attributes = this.piece.getAttributes();
  3364. this.textConfig = this.options.textConfig;
  3365. this.context = this.options.context;
  3366. if (this.piece.attachment) {
  3367. this.attachment = this.piece.attachment;
  3368. } else {
  3369. this.string = this.piece.toString();
  3370. }
  3371. }
  3372. createNodes() {
  3373. let nodes = this.attachment ? this.createAttachmentNodes() : this.createStringNodes();
  3374. const element = this.createElement();
  3375. if (element) {
  3376. const innerElement = findInnerElement(element);
  3377. Array.from(nodes).forEach(node => {
  3378. innerElement.appendChild(node);
  3379. });
  3380. nodes = [element];
  3381. }
  3382. return nodes;
  3383. }
  3384. createAttachmentNodes() {
  3385. const constructor = this.attachment.isPreviewable() ? PreviewableAttachmentView : AttachmentView;
  3386. const view = this.createChildView(constructor, this.piece.attachment, {
  3387. piece: this.piece
  3388. });
  3389. return view.getNodes();
  3390. }
  3391. createStringNodes() {
  3392. var _this$textConfig;
  3393. if ((_this$textConfig = this.textConfig) !== null && _this$textConfig !== void 0 && _this$textConfig.plaintext) {
  3394. return [document.createTextNode(this.string)];
  3395. } else {
  3396. const nodes = [];
  3397. const iterable = this.string.split("\n");
  3398. for (let index = 0; index < iterable.length; index++) {
  3399. const substring = iterable[index];
  3400. if (index > 0) {
  3401. const element = makeElement("br");
  3402. nodes.push(element);
  3403. }
  3404. if (substring.length) {
  3405. const node = document.createTextNode(this.preserveSpaces(substring));
  3406. nodes.push(node);
  3407. }
  3408. }
  3409. return nodes;
  3410. }
  3411. }
  3412. createElement() {
  3413. let element, key, value;
  3414. const styles = {};
  3415. for (key in this.attributes) {
  3416. value = this.attributes[key];
  3417. const config = getTextConfig(key);
  3418. if (config) {
  3419. if (config.tagName) {
  3420. var innerElement;
  3421. const pendingElement = makeElement(config.tagName);
  3422. if (innerElement) {
  3423. innerElement.appendChild(pendingElement);
  3424. innerElement = pendingElement;
  3425. } else {
  3426. element = innerElement = pendingElement;
  3427. }
  3428. }
  3429. if (config.styleProperty) {
  3430. styles[config.styleProperty] = value;
  3431. }
  3432. if (config.style) {
  3433. for (key in config.style) {
  3434. value = config.style[key];
  3435. styles[key] = value;
  3436. }
  3437. }
  3438. }
  3439. }
  3440. if (Object.keys(styles).length) {
  3441. if (!element) {
  3442. element = makeElement("span");
  3443. }
  3444. for (key in styles) {
  3445. value = styles[key];
  3446. element.style[key] = value;
  3447. }
  3448. }
  3449. return element;
  3450. }
  3451. createContainerElement() {
  3452. for (const key in this.attributes) {
  3453. const value = this.attributes[key];
  3454. const config = getTextConfig(key);
  3455. if (config) {
  3456. if (config.groupTagName) {
  3457. const attributes = {};
  3458. attributes[key] = value;
  3459. return makeElement(config.groupTagName, attributes);
  3460. }
  3461. }
  3462. }
  3463. }
  3464. preserveSpaces(string) {
  3465. if (this.context.isLast) {
  3466. string = string.replace(/\ $/, NON_BREAKING_SPACE);
  3467. }
  3468. 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));
  3469. if (this.context.isFirst || this.context.followsWhitespace) {
  3470. string = string.replace(/^\ /, NON_BREAKING_SPACE);
  3471. }
  3472. return string;
  3473. }
  3474. }
  3475. /* eslint-disable
  3476. no-var,
  3477. */
  3478. class TextView extends ObjectView {
  3479. constructor() {
  3480. super(...arguments);
  3481. this.text = this.object;
  3482. this.textConfig = this.options.textConfig;
  3483. }
  3484. createNodes() {
  3485. const nodes = [];
  3486. const pieces = ObjectGroup.groupObjects(this.getPieces());
  3487. const lastIndex = pieces.length - 1;
  3488. for (let index = 0; index < pieces.length; index++) {
  3489. const piece = pieces[index];
  3490. const context = {};
  3491. if (index === 0) {
  3492. context.isFirst = true;
  3493. }
  3494. if (index === lastIndex) {
  3495. context.isLast = true;
  3496. }
  3497. if (endsWithWhitespace(previousPiece)) {
  3498. context.followsWhitespace = true;
  3499. }
  3500. const view = this.findOrCreateCachedChildView(PieceView, piece, {
  3501. textConfig: this.textConfig,
  3502. context
  3503. });
  3504. nodes.push(...Array.from(view.getNodes() || []));
  3505. var previousPiece = piece;
  3506. }
  3507. return nodes;
  3508. }
  3509. getPieces() {
  3510. return Array.from(this.text.getPieces()).filter(piece => !piece.hasAttribute("blockBreak"));
  3511. }
  3512. }
  3513. const endsWithWhitespace = piece => /\s$/.test(piece === null || piece === void 0 ? void 0 : piece.toString());
  3514. const {
  3515. css: css$1
  3516. } = config;
  3517. class BlockView extends ObjectView {
  3518. constructor() {
  3519. super(...arguments);
  3520. this.block = this.object;
  3521. this.attributes = this.block.getAttributes();
  3522. }
  3523. createNodes() {
  3524. const comment = document.createComment("block");
  3525. const nodes = [comment];
  3526. if (this.block.isEmpty()) {
  3527. nodes.push(makeElement("br"));
  3528. } else {
  3529. var _getBlockConfig;
  3530. const textConfig = (_getBlockConfig = getBlockConfig(this.block.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.text;
  3531. const textView = this.findOrCreateCachedChildView(TextView, this.block.text, {
  3532. textConfig
  3533. });
  3534. nodes.push(...Array.from(textView.getNodes() || []));
  3535. if (this.shouldAddExtraNewlineElement()) {
  3536. nodes.push(makeElement("br"));
  3537. }
  3538. }
  3539. if (this.attributes.length) {
  3540. return nodes;
  3541. } else {
  3542. let attributes$1;
  3543. const {
  3544. tagName
  3545. } = attributes.default;
  3546. if (this.block.isRTL()) {
  3547. attributes$1 = {
  3548. dir: "rtl"
  3549. };
  3550. }
  3551. const element = makeElement({
  3552. tagName,
  3553. attributes: attributes$1
  3554. });
  3555. nodes.forEach(node => element.appendChild(node));
  3556. return [element];
  3557. }
  3558. }
  3559. createContainerElement(depth) {
  3560. const attributes = {};
  3561. let className;
  3562. const attributeName = this.attributes[depth];
  3563. const {
  3564. tagName,
  3565. htmlAttributes = []
  3566. } = getBlockConfig(attributeName);
  3567. if (depth === 0 && this.block.isRTL()) {
  3568. Object.assign(attributes, {
  3569. dir: "rtl"
  3570. });
  3571. }
  3572. if (attributeName === "attachmentGallery") {
  3573. const size = this.block.getBlockBreakPosition();
  3574. className = "".concat(css$1.attachmentGallery, " ").concat(css$1.attachmentGallery, "--").concat(size);
  3575. }
  3576. Object.entries(this.block.htmlAttributes).forEach(_ref => {
  3577. let [name, value] = _ref;
  3578. if (htmlAttributes.includes(name)) {
  3579. attributes[name] = value;
  3580. }
  3581. });
  3582. return makeElement({
  3583. tagName,
  3584. className,
  3585. attributes
  3586. });
  3587. }
  3588. // A single <br> at the end of a block element has no visual representation
  3589. // so add an extra one.
  3590. shouldAddExtraNewlineElement() {
  3591. return /\n\n$/.test(this.block.toString());
  3592. }
  3593. }
  3594. class DocumentView extends ObjectView {
  3595. static render(document) {
  3596. const element = makeElement("div");
  3597. const view = new this(document, {
  3598. element
  3599. });
  3600. view.render();
  3601. view.sync();
  3602. return element;
  3603. }
  3604. constructor() {
  3605. super(...arguments);
  3606. this.element = this.options.element;
  3607. this.elementStore = new ElementStore();
  3608. this.setDocument(this.object);
  3609. }
  3610. setDocument(document) {
  3611. if (!document.isEqualTo(this.document)) {
  3612. this.document = this.object = document;
  3613. }
  3614. }
  3615. render() {
  3616. this.childViews = [];
  3617. this.shadowElement = makeElement("div");
  3618. if (!this.document.isEmpty()) {
  3619. const objects = ObjectGroup.groupObjects(this.document.getBlocks(), {
  3620. asTree: true
  3621. });
  3622. Array.from(objects).forEach(object => {
  3623. const view = this.findOrCreateCachedChildView(BlockView, object);
  3624. Array.from(view.getNodes()).map(node => this.shadowElement.appendChild(node));
  3625. });
  3626. }
  3627. }
  3628. isSynced() {
  3629. return elementsHaveEqualHTML(this.shadowElement, this.element);
  3630. }
  3631. sync() {
  3632. const fragment = this.createDocumentFragmentForSync();
  3633. while (this.element.lastChild) {
  3634. this.element.removeChild(this.element.lastChild);
  3635. }
  3636. this.element.appendChild(fragment);
  3637. return this.didSync();
  3638. }
  3639. // Private
  3640. didSync() {
  3641. this.elementStore.reset(findStoredElements(this.element));
  3642. return defer(() => this.garbageCollectCachedViews());
  3643. }
  3644. createDocumentFragmentForSync() {
  3645. const fragment = document.createDocumentFragment();
  3646. Array.from(this.shadowElement.childNodes).forEach(node => {
  3647. fragment.appendChild(node.cloneNode(true));
  3648. });
  3649. Array.from(findStoredElements(fragment)).forEach(element => {
  3650. const storedElement = this.elementStore.remove(element);
  3651. if (storedElement) {
  3652. element.parentNode.replaceChild(storedElement, element);
  3653. }
  3654. });
  3655. return fragment;
  3656. }
  3657. }
  3658. const findStoredElements = element => element.querySelectorAll("[data-trix-store-key]");
  3659. const elementsHaveEqualHTML = (element, otherElement) => ignoreSpaces(element.innerHTML) === ignoreSpaces(otherElement.innerHTML);
  3660. const ignoreSpaces = html => html.replace(/&nbsp;/g, " ");
  3661. function _AsyncGenerator(e) {
  3662. var r, t;
  3663. function resume(r, t) {
  3664. try {
  3665. var n = e[r](t),
  3666. o = n.value,
  3667. u = o instanceof _OverloadYield;
  3668. Promise.resolve(u ? o.v : o).then(function (t) {
  3669. if (u) {
  3670. var i = "return" === r ? "return" : "next";
  3671. if (!o.k || t.done) return resume(i, t);
  3672. t = e[i](t).value;
  3673. }
  3674. settle(n.done ? "return" : "normal", t);
  3675. }, function (e) {
  3676. resume("throw", e);
  3677. });
  3678. } catch (e) {
  3679. settle("throw", e);
  3680. }
  3681. }
  3682. function settle(e, n) {
  3683. switch (e) {
  3684. case "return":
  3685. r.resolve({
  3686. value: n,
  3687. done: !0
  3688. });
  3689. break;
  3690. case "throw":
  3691. r.reject(n);
  3692. break;
  3693. default:
  3694. r.resolve({
  3695. value: n,
  3696. done: !1
  3697. });
  3698. }
  3699. (r = r.next) ? resume(r.key, r.arg) : t = null;
  3700. }
  3701. this._invoke = function (e, n) {
  3702. return new Promise(function (o, u) {
  3703. var i = {
  3704. key: e,
  3705. arg: n,
  3706. resolve: o,
  3707. reject: u,
  3708. next: null
  3709. };
  3710. t ? t = t.next = i : (r = t = i, resume(e, n));
  3711. });
  3712. }, "function" != typeof e.return && (this.return = void 0);
  3713. }
  3714. _AsyncGenerator.prototype["function" == typeof Symbol && Symbol.asyncIterator || "@@asyncIterator"] = function () {
  3715. return this;
  3716. }, _AsyncGenerator.prototype.next = function (e) {
  3717. return this._invoke("next", e);
  3718. }, _AsyncGenerator.prototype.throw = function (e) {
  3719. return this._invoke("throw", e);
  3720. }, _AsyncGenerator.prototype.return = function (e) {
  3721. return this._invoke("return", e);
  3722. };
  3723. function _OverloadYield(t, e) {
  3724. this.v = t, this.k = e;
  3725. }
  3726. function old_createMetadataMethodsForProperty(e, t, a, r) {
  3727. return {
  3728. getMetadata: function (o) {
  3729. old_assertNotFinished(r, "getMetadata"), old_assertMetadataKey(o);
  3730. var i = e[o];
  3731. if (void 0 !== i) if (1 === t) {
  3732. var n = i.public;
  3733. if (void 0 !== n) return n[a];
  3734. } else if (2 === t) {
  3735. var l = i.private;
  3736. if (void 0 !== l) return l.get(a);
  3737. } else if (Object.hasOwnProperty.call(i, "constructor")) return i.constructor;
  3738. },
  3739. setMetadata: function (o, i) {
  3740. old_assertNotFinished(r, "setMetadata"), old_assertMetadataKey(o);
  3741. var n = e[o];
  3742. if (void 0 === n && (n = e[o] = {}), 1 === t) {
  3743. var l = n.public;
  3744. void 0 === l && (l = n.public = {}), l[a] = i;
  3745. } else if (2 === t) {
  3746. var s = n.priv;
  3747. void 0 === s && (s = n.private = new Map()), s.set(a, i);
  3748. } else n.constructor = i;
  3749. }
  3750. };
  3751. }
  3752. function old_convertMetadataMapToFinal(e, t) {
  3753. var a = e[Symbol.metadata || Symbol.for("Symbol.metadata")],
  3754. r = Object.getOwnPropertySymbols(t);
  3755. if (0 !== r.length) {
  3756. for (var o = 0; o < r.length; o++) {
  3757. var i = r[o],
  3758. n = t[i],
  3759. l = a ? a[i] : null,
  3760. s = n.public,
  3761. c = l ? l.public : null;
  3762. s && c && Object.setPrototypeOf(s, c);
  3763. var d = n.private;
  3764. if (d) {
  3765. var u = Array.from(d.values()),
  3766. f = l ? l.private : null;
  3767. f && (u = u.concat(f)), n.private = u;
  3768. }
  3769. l && Object.setPrototypeOf(n, l);
  3770. }
  3771. a && Object.setPrototypeOf(t, a), e[Symbol.metadata || Symbol.for("Symbol.metadata")] = t;
  3772. }
  3773. }
  3774. function old_createAddInitializerMethod(e, t) {
  3775. return function (a) {
  3776. old_assertNotFinished(t, "addInitializer"), old_assertCallable(a, "An initializer"), e.push(a);
  3777. };
  3778. }
  3779. function old_memberDec(e, t, a, r, o, i, n, l, s) {
  3780. var c;
  3781. switch (i) {
  3782. case 1:
  3783. c = "accessor";
  3784. break;
  3785. case 2:
  3786. c = "method";
  3787. break;
  3788. case 3:
  3789. c = "getter";
  3790. break;
  3791. case 4:
  3792. c = "setter";
  3793. break;
  3794. default:
  3795. c = "field";
  3796. }
  3797. var d,
  3798. u,
  3799. f = {
  3800. kind: c,
  3801. name: l ? "#" + t : t,
  3802. isStatic: n,
  3803. isPrivate: l
  3804. },
  3805. p = {
  3806. v: !1
  3807. };
  3808. if (0 !== i && (f.addInitializer = old_createAddInitializerMethod(o, p)), l) {
  3809. d = 2, u = Symbol(t);
  3810. var v = {};
  3811. 0 === i ? (v.get = a.get, v.set = a.set) : 2 === i ? v.get = function () {
  3812. return a.value;
  3813. } : (1 !== i && 3 !== i || (v.get = function () {
  3814. return a.get.call(this);
  3815. }), 1 !== i && 4 !== i || (v.set = function (e) {
  3816. a.set.call(this, e);
  3817. })), f.access = v;
  3818. } else d = 1, u = t;
  3819. try {
  3820. return e(s, Object.assign(f, old_createMetadataMethodsForProperty(r, d, u, p)));
  3821. } finally {
  3822. p.v = !0;
  3823. }
  3824. }
  3825. function old_assertNotFinished(e, t) {
  3826. if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
  3827. }
  3828. function old_assertMetadataKey(e) {
  3829. if ("symbol" != typeof e) throw new TypeError("Metadata keys must be symbols, received: " + e);
  3830. }
  3831. function old_assertCallable(e, t) {
  3832. if ("function" != typeof e) throw new TypeError(t + " must be a function");
  3833. }
  3834. function old_assertValidReturnValue(e, t) {
  3835. var a = typeof t;
  3836. if (1 === e) {
  3837. if ("object" !== a || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
  3838. 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");
  3839. } else if ("function" !== a) {
  3840. var r;
  3841. throw r = 0 === e ? "field" : 10 === e ? "class" : "method", new TypeError(r + " decorators must return a function or void 0");
  3842. }
  3843. }
  3844. function old_getInit(e) {
  3845. var t;
  3846. return null == (t = e.init) && (t = e.initializer) && "undefined" != typeof console && console.warn(".initializer has been renamed to .init as of March 2022"), t;
  3847. }
  3848. function old_applyMemberDec(e, t, a, r, o, i, n, l, s) {
  3849. var c,
  3850. d,
  3851. u,
  3852. f,
  3853. p,
  3854. v,
  3855. h = a[0];
  3856. if (n ? c = 0 === o || 1 === o ? {
  3857. get: a[3],
  3858. set: a[4]
  3859. } : 3 === o ? {
  3860. get: a[3]
  3861. } : 4 === o ? {
  3862. set: a[3]
  3863. } : {
  3864. value: a[3]
  3865. } : 0 !== o && (c = Object.getOwnPropertyDescriptor(t, r)), 1 === o ? u = {
  3866. get: c.get,
  3867. set: c.set
  3868. } : 2 === o ? u = c.value : 3 === o ? u = c.get : 4 === o && (u = c.set), "function" == typeof h) void 0 !== (f = old_memberDec(h, r, c, l, s, o, i, n, u)) && (old_assertValidReturnValue(o, f), 0 === o ? d = f : 1 === o ? (d = old_getInit(f), p = f.get || u.get, v = f.set || u.set, u = {
  3869. get: p,
  3870. set: v
  3871. }) : u = f);else for (var y = h.length - 1; y >= 0; y--) {
  3872. var b;
  3873. if (void 0 !== (f = old_memberDec(h[y], r, c, l, s, o, i, n, u))) old_assertValidReturnValue(o, f), 0 === o ? b = f : 1 === o ? (b = old_getInit(f), p = f.get || u.get, v = f.set || u.set, u = {
  3874. get: p,
  3875. set: v
  3876. }) : u = f, void 0 !== b && (void 0 === d ? d = b : "function" == typeof d ? d = [d, b] : d.push(b));
  3877. }
  3878. if (0 === o || 1 === o) {
  3879. if (void 0 === d) d = function (e, t) {
  3880. return t;
  3881. };else if ("function" != typeof d) {
  3882. var g = d;
  3883. d = function (e, t) {
  3884. for (var a = t, r = 0; r < g.length; r++) a = g[r].call(e, a);
  3885. return a;
  3886. };
  3887. } else {
  3888. var m = d;
  3889. d = function (e, t) {
  3890. return m.call(e, t);
  3891. };
  3892. }
  3893. e.push(d);
  3894. }
  3895. 0 !== o && (1 === o ? (c.get = u.get, c.set = u.set) : 2 === o ? c.value = u : 3 === o ? c.get = u : 4 === o && (c.set = u), n ? 1 === o ? (e.push(function (e, t) {
  3896. return u.get.call(e, t);
  3897. }), e.push(function (e, t) {
  3898. return u.set.call(e, t);
  3899. })) : 2 === o ? e.push(u) : e.push(function (e, t) {
  3900. return u.call(e, t);
  3901. }) : Object.defineProperty(t, r, c));
  3902. }
  3903. function old_applyMemberDecs(e, t, a, r, o) {
  3904. for (var i, n, l = new Map(), s = new Map(), c = 0; c < o.length; c++) {
  3905. var d = o[c];
  3906. if (Array.isArray(d)) {
  3907. var u,
  3908. f,
  3909. p,
  3910. v = d[1],
  3911. h = d[2],
  3912. y = d.length > 3,
  3913. b = v >= 5;
  3914. if (b ? (u = t, f = r, 0 !== (v -= 5) && (p = n = n || [])) : (u = t.prototype, f = a, 0 !== v && (p = i = i || [])), 0 !== v && !y) {
  3915. var g = b ? s : l,
  3916. m = g.get(h) || 0;
  3917. if (!0 === m || 3 === m && 4 !== v || 4 === m && 3 !== v) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + h);
  3918. !m && v > 2 ? g.set(h, v) : g.set(h, !0);
  3919. }
  3920. old_applyMemberDec(e, u, d, h, v, b, y, f, p);
  3921. }
  3922. }
  3923. old_pushInitializers(e, i), old_pushInitializers(e, n);
  3924. }
  3925. function old_pushInitializers(e, t) {
  3926. t && e.push(function (e) {
  3927. for (var a = 0; a < t.length; a++) t[a].call(e);
  3928. return e;
  3929. });
  3930. }
  3931. function old_applyClassDecs(e, t, a, r) {
  3932. if (r.length > 0) {
  3933. for (var o = [], i = t, n = t.name, l = r.length - 1; l >= 0; l--) {
  3934. var s = {
  3935. v: !1
  3936. };
  3937. try {
  3938. var c = Object.assign({
  3939. kind: "class",
  3940. name: n,
  3941. addInitializer: old_createAddInitializerMethod(o, s)
  3942. }, old_createMetadataMethodsForProperty(a, 0, n, s)),
  3943. d = r[l](i, c);
  3944. } finally {
  3945. s.v = !0;
  3946. }
  3947. void 0 !== d && (old_assertValidReturnValue(10, d), i = d);
  3948. }
  3949. e.push(i, function () {
  3950. for (var e = 0; e < o.length; e++) o[e].call(i);
  3951. });
  3952. }
  3953. }
  3954. function _applyDecs(e, t, a) {
  3955. var r = [],
  3956. o = {},
  3957. i = {};
  3958. return old_applyMemberDecs(r, e, i, o, t), old_convertMetadataMapToFinal(e.prototype, i), old_applyClassDecs(r, e, o, a), old_convertMetadataMapToFinal(e, o), r;
  3959. }
  3960. function applyDecs2203Factory() {
  3961. function createAddInitializerMethod(e, t) {
  3962. return function (r) {
  3963. !function (e, t) {
  3964. if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
  3965. }(t, "addInitializer"), assertCallable(r, "An initializer"), e.push(r);
  3966. };
  3967. }
  3968. function memberDec(e, t, r, a, n, i, s, o) {
  3969. var c;
  3970. switch (n) {
  3971. case 1:
  3972. c = "accessor";
  3973. break;
  3974. case 2:
  3975. c = "method";
  3976. break;
  3977. case 3:
  3978. c = "getter";
  3979. break;
  3980. case 4:
  3981. c = "setter";
  3982. break;
  3983. default:
  3984. c = "field";
  3985. }
  3986. var l,
  3987. u,
  3988. f = {
  3989. kind: c,
  3990. name: s ? "#" + t : t,
  3991. static: i,
  3992. private: s
  3993. },
  3994. p = {
  3995. v: !1
  3996. };
  3997. 0 !== n && (f.addInitializer = createAddInitializerMethod(a, p)), 0 === n ? s ? (l = r.get, u = r.set) : (l = function () {
  3998. return this[t];
  3999. }, u = function (e) {
  4000. this[t] = e;
  4001. }) : 2 === n ? l = function () {
  4002. return r.value;
  4003. } : (1 !== n && 3 !== n || (l = function () {
  4004. return r.get.call(this);
  4005. }), 1 !== n && 4 !== n || (u = function (e) {
  4006. r.set.call(this, e);
  4007. })), f.access = l && u ? {
  4008. get: l,
  4009. set: u
  4010. } : l ? {
  4011. get: l
  4012. } : {
  4013. set: u
  4014. };
  4015. try {
  4016. return e(o, f);
  4017. } finally {
  4018. p.v = !0;
  4019. }
  4020. }
  4021. function assertCallable(e, t) {
  4022. if ("function" != typeof e) throw new TypeError(t + " must be a function");
  4023. }
  4024. function assertValidReturnValue(e, t) {
  4025. var r = typeof t;
  4026. if (1 === e) {
  4027. if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
  4028. 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");
  4029. } else if ("function" !== r) {
  4030. var a;
  4031. throw a = 0 === e ? "field" : 10 === e ? "class" : "method", new TypeError(a + " decorators must return a function or void 0");
  4032. }
  4033. }
  4034. function applyMemberDec(e, t, r, a, n, i, s, o) {
  4035. var c,
  4036. l,
  4037. u,
  4038. f,
  4039. p,
  4040. d,
  4041. h = r[0];
  4042. if (s ? c = 0 === n || 1 === n ? {
  4043. get: r[3],
  4044. set: r[4]
  4045. } : 3 === n ? {
  4046. get: r[3]
  4047. } : 4 === n ? {
  4048. set: r[3]
  4049. } : {
  4050. value: r[3]
  4051. } : 0 !== n && (c = Object.getOwnPropertyDescriptor(t, a)), 1 === n ? u = {
  4052. get: c.get,
  4053. set: c.set
  4054. } : 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 = {
  4055. get: p,
  4056. set: d
  4057. }) : u = f);else for (var v = h.length - 1; v >= 0; v--) {
  4058. var g;
  4059. if (void 0 !== (f = memberDec(h[v], a, c, o, n, i, s, u))) assertValidReturnValue(n, f), 0 === n ? g = f : 1 === n ? (g = f.init, p = f.get || u.get, d = f.set || u.set, u = {
  4060. get: p,
  4061. set: d
  4062. }) : u = f, void 0 !== g && (void 0 === l ? l = g : "function" == typeof l ? l = [l, g] : l.push(g));
  4063. }
  4064. if (0 === n || 1 === n) {
  4065. if (void 0 === l) l = function (e, t) {
  4066. return t;
  4067. };else if ("function" != typeof l) {
  4068. var y = l;
  4069. l = function (e, t) {
  4070. for (var r = t, a = 0; a < y.length; a++) r = y[a].call(e, r);
  4071. return r;
  4072. };
  4073. } else {
  4074. var m = l;
  4075. l = function (e, t) {
  4076. return m.call(e, t);
  4077. };
  4078. }
  4079. e.push(l);
  4080. }
  4081. 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) {
  4082. return u.get.call(e, t);
  4083. }), e.push(function (e, t) {
  4084. return u.set.call(e, t);
  4085. })) : 2 === n ? e.push(u) : e.push(function (e, t) {
  4086. return u.call(e, t);
  4087. }) : Object.defineProperty(t, a, c));
  4088. }
  4089. function pushInitializers(e, t) {
  4090. t && e.push(function (e) {
  4091. for (var r = 0; r < t.length; r++) t[r].call(e);
  4092. return e;
  4093. });
  4094. }
  4095. return function (e, t, r) {
  4096. var a = [];
  4097. return function (e, t, r) {
  4098. for (var a, n, i = new Map(), s = new Map(), o = 0; o < r.length; o++) {
  4099. var c = r[o];
  4100. if (Array.isArray(c)) {
  4101. var l,
  4102. u,
  4103. f = c[1],
  4104. p = c[2],
  4105. d = c.length > 3,
  4106. h = f >= 5;
  4107. if (h ? (l = t, 0 != (f -= 5) && (u = n = n || [])) : (l = t.prototype, 0 !== f && (u = a = a || [])), 0 !== f && !d) {
  4108. var v = h ? s : i,
  4109. g = v.get(p) || 0;
  4110. 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);
  4111. !g && f > 2 ? v.set(p, f) : v.set(p, !0);
  4112. }
  4113. applyMemberDec(e, l, c, p, f, h, d, u);
  4114. }
  4115. }
  4116. pushInitializers(e, a), pushInitializers(e, n);
  4117. }(a, e, t), function (e, t, r) {
  4118. if (r.length > 0) {
  4119. for (var a = [], n = t, i = t.name, s = r.length - 1; s >= 0; s--) {
  4120. var o = {
  4121. v: !1
  4122. };
  4123. try {
  4124. var c = r[s](n, {
  4125. kind: "class",
  4126. name: i,
  4127. addInitializer: createAddInitializerMethod(a, o)
  4128. });
  4129. } finally {
  4130. o.v = !0;
  4131. }
  4132. void 0 !== c && (assertValidReturnValue(10, c), n = c);
  4133. }
  4134. e.push(n, function () {
  4135. for (var e = 0; e < a.length; e++) a[e].call(n);
  4136. });
  4137. }
  4138. }(a, e, r), a;
  4139. };
  4140. }
  4141. var applyDecs2203Impl;
  4142. function _applyDecs2203(e, t, r) {
  4143. return (applyDecs2203Impl = applyDecs2203Impl || applyDecs2203Factory())(e, t, r);
  4144. }
  4145. function applyDecs2203RFactory() {
  4146. function createAddInitializerMethod(e, t) {
  4147. return function (r) {
  4148. !function (e, t) {
  4149. if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
  4150. }(t, "addInitializer"), assertCallable(r, "An initializer"), e.push(r);
  4151. };
  4152. }
  4153. function memberDec(e, t, r, n, a, i, s, o) {
  4154. var c;
  4155. switch (a) {
  4156. case 1:
  4157. c = "accessor";
  4158. break;
  4159. case 2:
  4160. c = "method";
  4161. break;
  4162. case 3:
  4163. c = "getter";
  4164. break;
  4165. case 4:
  4166. c = "setter";
  4167. break;
  4168. default:
  4169. c = "field";
  4170. }
  4171. var l,
  4172. u,
  4173. f = {
  4174. kind: c,
  4175. name: s ? "#" + t : t,
  4176. static: i,
  4177. private: s
  4178. },
  4179. p = {
  4180. v: !1
  4181. };
  4182. 0 !== a && (f.addInitializer = createAddInitializerMethod(n, p)), 0 === a ? s ? (l = r.get, u = r.set) : (l = function () {
  4183. return this[t];
  4184. }, u = function (e) {
  4185. this[t] = e;
  4186. }) : 2 === a ? l = function () {
  4187. return r.value;
  4188. } : (1 !== a && 3 !== a || (l = function () {
  4189. return r.get.call(this);
  4190. }), 1 !== a && 4 !== a || (u = function (e) {
  4191. r.set.call(this, e);
  4192. })), f.access = l && u ? {
  4193. get: l,
  4194. set: u
  4195. } : l ? {
  4196. get: l
  4197. } : {
  4198. set: u
  4199. };
  4200. try {
  4201. return e(o, f);
  4202. } finally {
  4203. p.v = !0;
  4204. }
  4205. }
  4206. function assertCallable(e, t) {
  4207. if ("function" != typeof e) throw new TypeError(t + " must be a function");
  4208. }
  4209. function assertValidReturnValue(e, t) {
  4210. var r = typeof t;
  4211. if (1 === e) {
  4212. if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
  4213. 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");
  4214. } else if ("function" !== r) {
  4215. var n;
  4216. throw n = 0 === e ? "field" : 10 === e ? "class" : "method", new TypeError(n + " decorators must return a function or void 0");
  4217. }
  4218. }
  4219. function applyMemberDec(e, t, r, n, a, i, s, o) {
  4220. var c,
  4221. l,
  4222. u,
  4223. f,
  4224. p,
  4225. d,
  4226. h = r[0];
  4227. if (s ? c = 0 === a || 1 === a ? {
  4228. get: r[3],
  4229. set: r[4]
  4230. } : 3 === a ? {
  4231. get: r[3]
  4232. } : 4 === a ? {
  4233. set: r[3]
  4234. } : {
  4235. value: r[3]
  4236. } : 0 !== a && (c = Object.getOwnPropertyDescriptor(t, n)), 1 === a ? u = {
  4237. get: c.get,
  4238. set: c.set
  4239. } : 2 === a ? u = c.value : 3 === a ? u = c.get : 4 === a && (u = c.set), "function" == typeof h) void 0 !== (f = memberDec(h, n, c, o, a, i, s, u)) && (assertValidReturnValue(a, f), 0 === a ? l = f : 1 === a ? (l = f.init, p = f.get || u.get, d = f.set || u.set, u = {
  4240. get: p,
  4241. set: d
  4242. }) : u = f);else for (var v = h.length - 1; v >= 0; v--) {
  4243. var g;
  4244. if (void 0 !== (f = memberDec(h[v], n, c, o, a, i, s, u))) assertValidReturnValue(a, f), 0 === a ? g = f : 1 === a ? (g = f.init, p = f.get || u.get, d = f.set || u.set, u = {
  4245. get: p,
  4246. set: d
  4247. }) : u = f, void 0 !== g && (void 0 === l ? l = g : "function" == typeof l ? l = [l, g] : l.push(g));
  4248. }
  4249. if (0 === a || 1 === a) {
  4250. if (void 0 === l) l = function (e, t) {
  4251. return t;
  4252. };else if ("function" != typeof l) {
  4253. var y = l;
  4254. l = function (e, t) {
  4255. for (var r = t, n = 0; n < y.length; n++) r = y[n].call(e, r);
  4256. return r;
  4257. };
  4258. } else {
  4259. var m = l;
  4260. l = function (e, t) {
  4261. return m.call(e, t);
  4262. };
  4263. }
  4264. e.push(l);
  4265. }
  4266. 0 !== a && (1 === a ? (c.get = u.get, c.set = u.set) : 2 === a ? c.value = u : 3 === a ? c.get = u : 4 === a && (c.set = u), s ? 1 === a ? (e.push(function (e, t) {
  4267. return u.get.call(e, t);
  4268. }), e.push(function (e, t) {
  4269. return u.set.call(e, t);
  4270. })) : 2 === a ? e.push(u) : e.push(function (e, t) {
  4271. return u.call(e, t);
  4272. }) : Object.defineProperty(t, n, c));
  4273. }
  4274. function applyMemberDecs(e, t) {
  4275. for (var r, n, a = [], i = new Map(), s = new Map(), o = 0; o < t.length; o++) {
  4276. var c = t[o];
  4277. if (Array.isArray(c)) {
  4278. var l,
  4279. u,
  4280. f = c[1],
  4281. p = c[2],
  4282. d = c.length > 3,
  4283. h = f >= 5;
  4284. if (h ? (l = e, 0 !== (f -= 5) && (u = n = n || [])) : (l = e.prototype, 0 !== f && (u = r = r || [])), 0 !== f && !d) {
  4285. var v = h ? s : i,
  4286. g = v.get(p) || 0;
  4287. 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);
  4288. !g && f > 2 ? v.set(p, f) : v.set(p, !0);
  4289. }
  4290. applyMemberDec(a, l, c, p, f, h, d, u);
  4291. }
  4292. }
  4293. return pushInitializers(a, r), pushInitializers(a, n), a;
  4294. }
  4295. function pushInitializers(e, t) {
  4296. t && e.push(function (e) {
  4297. for (var r = 0; r < t.length; r++) t[r].call(e);
  4298. return e;
  4299. });
  4300. }
  4301. return function (e, t, r) {
  4302. return {
  4303. e: applyMemberDecs(e, t),
  4304. get c() {
  4305. return function (e, t) {
  4306. if (t.length > 0) {
  4307. for (var r = [], n = e, a = e.name, i = t.length - 1; i >= 0; i--) {
  4308. var s = {
  4309. v: !1
  4310. };
  4311. try {
  4312. var o = t[i](n, {
  4313. kind: "class",
  4314. name: a,
  4315. addInitializer: createAddInitializerMethod(r, s)
  4316. });
  4317. } finally {
  4318. s.v = !0;
  4319. }
  4320. void 0 !== o && (assertValidReturnValue(10, o), n = o);
  4321. }
  4322. return [n, function () {
  4323. for (var e = 0; e < r.length; e++) r[e].call(n);
  4324. }];
  4325. }
  4326. }(e, r);
  4327. }
  4328. };
  4329. };
  4330. }
  4331. function _applyDecs2203R(e, t, r) {
  4332. return (_applyDecs2203R = applyDecs2203RFactory())(e, t, r);
  4333. }
  4334. function applyDecs2301Factory() {
  4335. function createAddInitializerMethod(e, t) {
  4336. return function (r) {
  4337. !function (e, t) {
  4338. if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
  4339. }(t, "addInitializer"), assertCallable(r, "An initializer"), e.push(r);
  4340. };
  4341. }
  4342. function assertInstanceIfPrivate(e, t) {
  4343. if (!e(t)) throw new TypeError("Attempted to access private element on non-instance");
  4344. }
  4345. function memberDec(e, t, r, n, a, i, s, o, c) {
  4346. var u;
  4347. switch (a) {
  4348. case 1:
  4349. u = "accessor";
  4350. break;
  4351. case 2:
  4352. u = "method";
  4353. break;
  4354. case 3:
  4355. u = "getter";
  4356. break;
  4357. case 4:
  4358. u = "setter";
  4359. break;
  4360. default:
  4361. u = "field";
  4362. }
  4363. var l,
  4364. f,
  4365. p = {
  4366. kind: u,
  4367. name: s ? "#" + t : t,
  4368. static: i,
  4369. private: s
  4370. },
  4371. d = {
  4372. v: !1
  4373. };
  4374. if (0 !== a && (p.addInitializer = createAddInitializerMethod(n, d)), s || 0 !== a && 2 !== a) {
  4375. if (2 === a) l = function (e) {
  4376. return assertInstanceIfPrivate(c, e), r.value;
  4377. };else {
  4378. var h = 0 === a || 1 === a;
  4379. (h || 3 === a) && (l = s ? function (e) {
  4380. return assertInstanceIfPrivate(c, e), r.get.call(e);
  4381. } : function (e) {
  4382. return r.get.call(e);
  4383. }), (h || 4 === a) && (f = s ? function (e, t) {
  4384. assertInstanceIfPrivate(c, e), r.set.call(e, t);
  4385. } : function (e, t) {
  4386. r.set.call(e, t);
  4387. });
  4388. }
  4389. } else l = function (e) {
  4390. return e[t];
  4391. }, 0 === a && (f = function (e, r) {
  4392. e[t] = r;
  4393. });
  4394. var v = s ? c.bind() : function (e) {
  4395. return t in e;
  4396. };
  4397. p.access = l && f ? {
  4398. get: l,
  4399. set: f,
  4400. has: v
  4401. } : l ? {
  4402. get: l,
  4403. has: v
  4404. } : {
  4405. set: f,
  4406. has: v
  4407. };
  4408. try {
  4409. return e(o, p);
  4410. } finally {
  4411. d.v = !0;
  4412. }
  4413. }
  4414. function assertCallable(e, t) {
  4415. if ("function" != typeof e) throw new TypeError(t + " must be a function");
  4416. }
  4417. function assertValidReturnValue(e, t) {
  4418. var r = typeof t;
  4419. if (1 === e) {
  4420. if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
  4421. 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");
  4422. } else if ("function" !== r) {
  4423. var n;
  4424. throw n = 0 === e ? "field" : 10 === e ? "class" : "method", new TypeError(n + " decorators must return a function or void 0");
  4425. }
  4426. }
  4427. function curryThis2(e) {
  4428. return function (t) {
  4429. e(this, t);
  4430. };
  4431. }
  4432. function applyMemberDec(e, t, r, n, a, i, s, o, c) {
  4433. var u,
  4434. l,
  4435. f,
  4436. p,
  4437. d,
  4438. h,
  4439. v,
  4440. g = r[0];
  4441. if (s ? u = 0 === a || 1 === a ? {
  4442. get: (p = r[3], function () {
  4443. return p(this);
  4444. }),
  4445. set: curryThis2(r[4])
  4446. } : 3 === a ? {
  4447. get: r[3]
  4448. } : 4 === a ? {
  4449. set: r[3]
  4450. } : {
  4451. value: r[3]
  4452. } : 0 !== a && (u = Object.getOwnPropertyDescriptor(t, n)), 1 === a ? f = {
  4453. get: u.get,
  4454. set: u.set
  4455. } : 2 === a ? f = u.value : 3 === a ? f = u.get : 4 === a && (f = u.set), "function" == typeof g) void 0 !== (d = memberDec(g, n, u, o, a, i, s, f, c)) && (assertValidReturnValue(a, d), 0 === a ? l = d : 1 === a ? (l = d.init, h = d.get || f.get, v = d.set || f.set, f = {
  4456. get: h,
  4457. set: v
  4458. }) : f = d);else for (var y = g.length - 1; y >= 0; y--) {
  4459. var m;
  4460. if (void 0 !== (d = memberDec(g[y], n, u, o, a, i, s, f, c))) assertValidReturnValue(a, d), 0 === a ? m = d : 1 === a ? (m = d.init, h = d.get || f.get, v = d.set || f.set, f = {
  4461. get: h,
  4462. set: v
  4463. }) : f = d, void 0 !== m && (void 0 === l ? l = m : "function" == typeof l ? l = [l, m] : l.push(m));
  4464. }
  4465. if (0 === a || 1 === a) {
  4466. if (void 0 === l) l = function (e, t) {
  4467. return t;
  4468. };else if ("function" != typeof l) {
  4469. var b = l;
  4470. l = function (e, t) {
  4471. for (var r = t, n = 0; n < b.length; n++) r = b[n].call(e, r);
  4472. return r;
  4473. };
  4474. } else {
  4475. var I = l;
  4476. l = function (e, t) {
  4477. return I.call(e, t);
  4478. };
  4479. }
  4480. e.push(l);
  4481. }
  4482. 0 !== a && (1 === a ? (u.get = f.get, u.set = f.set) : 2 === a ? u.value = f : 3 === a ? u.get = f : 4 === a && (u.set = f), s ? 1 === a ? (e.push(function (e, t) {
  4483. return f.get.call(e, t);
  4484. }), e.push(function (e, t) {
  4485. return f.set.call(e, t);
  4486. })) : 2 === a ? e.push(f) : e.push(function (e, t) {
  4487. return f.call(e, t);
  4488. }) : Object.defineProperty(t, n, u));
  4489. }
  4490. function applyMemberDecs(e, t, r) {
  4491. for (var n, a, i, s = [], o = new Map(), c = new Map(), u = 0; u < t.length; u++) {
  4492. var l = t[u];
  4493. if (Array.isArray(l)) {
  4494. var f,
  4495. p,
  4496. d = l[1],
  4497. h = l[2],
  4498. v = l.length > 3,
  4499. g = d >= 5,
  4500. y = r;
  4501. if (g ? (f = e, 0 !== (d -= 5) && (p = a = a || []), v && !i && (i = function (t) {
  4502. return _checkInRHS(t) === e;
  4503. }), y = i) : (f = e.prototype, 0 !== d && (p = n = n || [])), 0 !== d && !v) {
  4504. var m = g ? c : o,
  4505. b = m.get(h) || 0;
  4506. 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);
  4507. !b && d > 2 ? m.set(h, d) : m.set(h, !0);
  4508. }
  4509. applyMemberDec(s, f, l, h, d, g, v, p, y);
  4510. }
  4511. }
  4512. return pushInitializers(s, n), pushInitializers(s, a), s;
  4513. }
  4514. function pushInitializers(e, t) {
  4515. t && e.push(function (e) {
  4516. for (var r = 0; r < t.length; r++) t[r].call(e);
  4517. return e;
  4518. });
  4519. }
  4520. return function (e, t, r, n) {
  4521. return {
  4522. e: applyMemberDecs(e, t, n),
  4523. get c() {
  4524. return function (e, t) {
  4525. if (t.length > 0) {
  4526. for (var r = [], n = e, a = e.name, i = t.length - 1; i >= 0; i--) {
  4527. var s = {
  4528. v: !1
  4529. };
  4530. try {
  4531. var o = t[i](n, {
  4532. kind: "class",
  4533. name: a,
  4534. addInitializer: createAddInitializerMethod(r, s)
  4535. });
  4536. } finally {
  4537. s.v = !0;
  4538. }
  4539. void 0 !== o && (assertValidReturnValue(10, o), n = o);
  4540. }
  4541. return [n, function () {
  4542. for (var e = 0; e < r.length; e++) r[e].call(n);
  4543. }];
  4544. }
  4545. }(e, r);
  4546. }
  4547. };
  4548. };
  4549. }
  4550. function _applyDecs2301(e, t, r, n) {
  4551. return (_applyDecs2301 = applyDecs2301Factory())(e, t, r, n);
  4552. }
  4553. function createAddInitializerMethod(e, t) {
  4554. return function (r) {
  4555. assertNotFinished(t, "addInitializer"), assertCallable(r, "An initializer"), e.push(r);
  4556. };
  4557. }
  4558. function assertInstanceIfPrivate(e, t) {
  4559. if (!e(t)) throw new TypeError("Attempted to access private element on non-instance");
  4560. }
  4561. function memberDec(e, t, r, a, n, i, s, o, c, l, u) {
  4562. var f;
  4563. switch (i) {
  4564. case 1:
  4565. f = "accessor";
  4566. break;
  4567. case 2:
  4568. f = "method";
  4569. break;
  4570. case 3:
  4571. f = "getter";
  4572. break;
  4573. case 4:
  4574. f = "setter";
  4575. break;
  4576. default:
  4577. f = "field";
  4578. }
  4579. var d,
  4580. p,
  4581. h = {
  4582. kind: f,
  4583. name: o ? "#" + r : r,
  4584. static: s,
  4585. private: o,
  4586. metadata: u
  4587. },
  4588. v = {
  4589. v: !1
  4590. };
  4591. if (0 !== i && (h.addInitializer = createAddInitializerMethod(n, v)), o || 0 !== i && 2 !== i) {
  4592. if (2 === i) d = function (e) {
  4593. return assertInstanceIfPrivate(l, e), a.value;
  4594. };else {
  4595. var y = 0 === i || 1 === i;
  4596. (y || 3 === i) && (d = o ? function (e) {
  4597. return assertInstanceIfPrivate(l, e), a.get.call(e);
  4598. } : function (e) {
  4599. return a.get.call(e);
  4600. }), (y || 4 === i) && (p = o ? function (e, t) {
  4601. assertInstanceIfPrivate(l, e), a.set.call(e, t);
  4602. } : function (e, t) {
  4603. a.set.call(e, t);
  4604. });
  4605. }
  4606. } else d = function (e) {
  4607. return e[r];
  4608. }, 0 === i && (p = function (e, t) {
  4609. e[r] = t;
  4610. });
  4611. var m = o ? l.bind() : function (e) {
  4612. return r in e;
  4613. };
  4614. h.access = d && p ? {
  4615. get: d,
  4616. set: p,
  4617. has: m
  4618. } : d ? {
  4619. get: d,
  4620. has: m
  4621. } : {
  4622. set: p,
  4623. has: m
  4624. };
  4625. try {
  4626. return e.call(t, c, h);
  4627. } finally {
  4628. v.v = !0;
  4629. }
  4630. }
  4631. function assertNotFinished(e, t) {
  4632. if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
  4633. }
  4634. function assertCallable(e, t) {
  4635. if ("function" != typeof e) throw new TypeError(t + " must be a function");
  4636. }
  4637. function assertValidReturnValue(e, t) {
  4638. var r = typeof t;
  4639. if (1 === e) {
  4640. if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
  4641. 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");
  4642. } else if ("function" !== r) {
  4643. var a;
  4644. throw a = 0 === e ? "field" : 5 === e ? "class" : "method", new TypeError(a + " decorators must return a function or void 0");
  4645. }
  4646. }
  4647. function curryThis1(e) {
  4648. return function () {
  4649. return e(this);
  4650. };
  4651. }
  4652. function curryThis2(e) {
  4653. return function (t) {
  4654. e(this, t);
  4655. };
  4656. }
  4657. function applyMemberDec(e, t, r, a, n, i, s, o, c, l, u) {
  4658. var f,
  4659. d,
  4660. p,
  4661. h,
  4662. v,
  4663. y,
  4664. m = r[0];
  4665. a || Array.isArray(m) || (m = [m]), o ? f = 0 === i || 1 === i ? {
  4666. get: curryThis1(r[3]),
  4667. set: curryThis2(r[4])
  4668. } : 3 === i ? {
  4669. get: r[3]
  4670. } : 4 === i ? {
  4671. set: r[3]
  4672. } : {
  4673. value: r[3]
  4674. } : 0 !== i && (f = Object.getOwnPropertyDescriptor(t, n)), 1 === i ? p = {
  4675. get: f.get,
  4676. set: f.set
  4677. } : 2 === i ? p = f.value : 3 === i ? p = f.get : 4 === i && (p = f.set);
  4678. for (var g = a ? 2 : 1, b = m.length - 1; b >= 0; b -= g) {
  4679. var I;
  4680. if (void 0 !== (h = memberDec(m[b], a ? m[b - 1] : void 0, n, f, c, i, s, o, p, l, u))) assertValidReturnValue(i, h), 0 === i ? I = h : 1 === i ? (I = h.init, v = h.get || p.get, y = h.set || p.set, p = {
  4681. get: v,
  4682. set: y
  4683. }) : p = h, void 0 !== I && (void 0 === d ? d = I : "function" == typeof d ? d = [d, I] : d.push(I));
  4684. }
  4685. if (0 === i || 1 === i) {
  4686. if (void 0 === d) d = function (e, t) {
  4687. return t;
  4688. };else if ("function" != typeof d) {
  4689. var w = d;
  4690. d = function (e, t) {
  4691. for (var r = t, a = w.length - 1; a >= 0; a--) r = w[a].call(e, r);
  4692. return r;
  4693. };
  4694. } else {
  4695. var M = d;
  4696. d = function (e, t) {
  4697. return M.call(e, t);
  4698. };
  4699. }
  4700. e.push(d);
  4701. }
  4702. 0 !== i && (1 === i ? (f.get = p.get, f.set = p.set) : 2 === i ? f.value = p : 3 === i ? f.get = p : 4 === i && (f.set = p), o ? 1 === i ? (e.push(function (e, t) {
  4703. return p.get.call(e, t);
  4704. }), e.push(function (e, t) {
  4705. return p.set.call(e, t);
  4706. })) : 2 === i ? e.push(p) : e.push(function (e, t) {
  4707. return p.call(e, t);
  4708. }) : Object.defineProperty(t, n, f));
  4709. }
  4710. function applyMemberDecs(e, t, r, a) {
  4711. for (var n, i, s, o = [], c = new Map(), l = new Map(), u = 0; u < t.length; u++) {
  4712. var f = t[u];
  4713. if (Array.isArray(f)) {
  4714. var d,
  4715. p,
  4716. h = f[1],
  4717. v = f[2],
  4718. y = f.length > 3,
  4719. m = 16 & h,
  4720. g = !!(8 & h),
  4721. b = r;
  4722. if (h &= 7, g ? (d = e, 0 !== h && (p = i = i || []), y && !s && (s = function (t) {
  4723. return _checkInRHS(t) === e;
  4724. }), b = s) : (d = e.prototype, 0 !== h && (p = n = n || [])), 0 !== h && !y) {
  4725. var I = g ? l : c,
  4726. w = I.get(v) || 0;
  4727. if (!0 === w || 3 === w && 4 !== h || 4 === w && 3 !== h) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + v);
  4728. I.set(v, !(!w && h > 2) || h);
  4729. }
  4730. applyMemberDec(o, d, f, m, v, h, g, y, p, b, a);
  4731. }
  4732. }
  4733. return pushInitializers(o, n), pushInitializers(o, i), o;
  4734. }
  4735. function pushInitializers(e, t) {
  4736. t && e.push(function (e) {
  4737. for (var r = 0; r < t.length; r++) t[r].call(e);
  4738. return e;
  4739. });
  4740. }
  4741. function applyClassDecs(e, t, r, a) {
  4742. if (t.length) {
  4743. for (var n = [], i = e, s = e.name, o = r ? 2 : 1, c = t.length - 1; c >= 0; c -= o) {
  4744. var l = {
  4745. v: !1
  4746. };
  4747. try {
  4748. var u = t[c].call(r ? t[c - 1] : void 0, i, {
  4749. kind: "class",
  4750. name: s,
  4751. addInitializer: createAddInitializerMethod(n, l),
  4752. metadata: a
  4753. });
  4754. } finally {
  4755. l.v = !0;
  4756. }
  4757. void 0 !== u && (assertValidReturnValue(5, u), i = u);
  4758. }
  4759. return [defineMetadata(i, a), function () {
  4760. for (var e = 0; e < n.length; e++) n[e].call(i);
  4761. }];
  4762. }
  4763. }
  4764. function defineMetadata(e, t) {
  4765. return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), {
  4766. configurable: !0,
  4767. enumerable: !0,
  4768. value: t
  4769. });
  4770. }
  4771. function _applyDecs2305(e, t, r, a, n, i) {
  4772. if (arguments.length >= 6) var s = i[Symbol.metadata || Symbol.for("Symbol.metadata")];
  4773. var o = Object.create(void 0 === s ? null : s),
  4774. c = applyMemberDecs(e, t, n, o);
  4775. return r.length || defineMetadata(e, o), {
  4776. e: c,
  4777. get c() {
  4778. return applyClassDecs(e, r, a, o);
  4779. }
  4780. };
  4781. }
  4782. function _asyncGeneratorDelegate(t) {
  4783. var e = {},
  4784. n = !1;
  4785. function pump(e, r) {
  4786. return n = !0, r = new Promise(function (n) {
  4787. n(t[e](r));
  4788. }), {
  4789. done: !1,
  4790. value: new _OverloadYield(r, 1)
  4791. };
  4792. }
  4793. return e["undefined" != typeof Symbol && Symbol.iterator || "@@iterator"] = function () {
  4794. return this;
  4795. }, e.next = function (t) {
  4796. return n ? (n = !1, t) : pump("next", t);
  4797. }, "function" == typeof t.throw && (e.throw = function (t) {
  4798. if (n) throw n = !1, t;
  4799. return pump("throw", t);
  4800. }), "function" == typeof t.return && (e.return = function (t) {
  4801. return n ? (n = !1, t) : pump("return", t);
  4802. }), e;
  4803. }
  4804. function _asyncIterator(r) {
  4805. var n,
  4806. t,
  4807. o,
  4808. e = 2;
  4809. for ("undefined" != typeof Symbol && (t = Symbol.asyncIterator, o = Symbol.iterator); e--;) {
  4810. if (t && null != (n = r[t])) return n.call(r);
  4811. if (o && null != (n = r[o])) return new AsyncFromSyncIterator(n.call(r));
  4812. t = "@@asyncIterator", o = "@@iterator";
  4813. }
  4814. throw new TypeError("Object is not async iterable");
  4815. }
  4816. function AsyncFromSyncIterator(r) {
  4817. function AsyncFromSyncIteratorContinuation(r) {
  4818. if (Object(r) !== r) return Promise.reject(new TypeError(r + " is not an object."));
  4819. var n = r.done;
  4820. return Promise.resolve(r.value).then(function (r) {
  4821. return {
  4822. value: r,
  4823. done: n
  4824. };
  4825. });
  4826. }
  4827. return AsyncFromSyncIterator = function (r) {
  4828. this.s = r, this.n = r.next;
  4829. }, AsyncFromSyncIterator.prototype = {
  4830. s: null,
  4831. n: null,
  4832. next: function () {
  4833. return AsyncFromSyncIteratorContinuation(this.n.apply(this.s, arguments));
  4834. },
  4835. return: function (r) {
  4836. var n = this.s.return;
  4837. return void 0 === n ? Promise.resolve({
  4838. value: r,
  4839. done: !0
  4840. }) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments));
  4841. },
  4842. throw: function (r) {
  4843. var n = this.s.return;
  4844. return void 0 === n ? Promise.reject(r) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments));
  4845. }
  4846. }, new AsyncFromSyncIterator(r);
  4847. }
  4848. function _awaitAsyncGenerator(e) {
  4849. return new _OverloadYield(e, 0);
  4850. }
  4851. function _checkInRHS(e) {
  4852. if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null"));
  4853. return e;
  4854. }
  4855. function _defineAccessor(e, r, n, t) {
  4856. var c = {
  4857. configurable: !0,
  4858. enumerable: !0
  4859. };
  4860. return c[e] = t, Object.defineProperty(r, n, c);
  4861. }
  4862. function dispose_SuppressedError(r, e) {
  4863. return "undefined" != typeof SuppressedError ? dispose_SuppressedError = SuppressedError : (dispose_SuppressedError = function (r, e) {
  4864. this.suppressed = r, this.error = e, this.stack = new Error().stack;
  4865. }, dispose_SuppressedError.prototype = Object.create(Error.prototype, {
  4866. constructor: {
  4867. value: dispose_SuppressedError,
  4868. writable: !0,
  4869. configurable: !0
  4870. }
  4871. })), new dispose_SuppressedError(r, e);
  4872. }
  4873. function _dispose(r, e, s) {
  4874. function next() {
  4875. for (; r.length > 0;) try {
  4876. var o = r.pop(),
  4877. p = o.d.call(o.v);
  4878. if (o.a) return Promise.resolve(p).then(next, err);
  4879. } catch (r) {
  4880. return err(r);
  4881. }
  4882. if (s) throw e;
  4883. }
  4884. function err(r) {
  4885. return e = s ? new dispose_SuppressedError(r, e) : r, s = !0, next();
  4886. }
  4887. return next();
  4888. }
  4889. function _importDeferProxy(e) {
  4890. var t = null,
  4891. constValue = function (e) {
  4892. return function () {
  4893. return e;
  4894. };
  4895. },
  4896. proxy = function (r) {
  4897. return function (n, o, f) {
  4898. return null === t && (t = e()), r(t, o, f);
  4899. };
  4900. };
  4901. return new Proxy({}, {
  4902. defineProperty: constValue(!1),
  4903. deleteProperty: constValue(!1),
  4904. get: proxy(Reflect.get),
  4905. getOwnPropertyDescriptor: proxy(Reflect.getOwnPropertyDescriptor),
  4906. getPrototypeOf: constValue(null),
  4907. isExtensible: constValue(!1),
  4908. has: proxy(Reflect.has),
  4909. ownKeys: proxy(Reflect.ownKeys),
  4910. preventExtensions: constValue(!0),
  4911. set: constValue(!1),
  4912. setPrototypeOf: constValue(!1)
  4913. });
  4914. }
  4915. function _iterableToArrayLimit(r, l) {
  4916. var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
  4917. if (null != t) {
  4918. var e,
  4919. n,
  4920. i,
  4921. u,
  4922. a = [],
  4923. f = !0,
  4924. o = !1;
  4925. try {
  4926. if (i = (t = t.call(r)).next, 0 === l) {
  4927. if (Object(t) !== t) return;
  4928. f = !1;
  4929. } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
  4930. } catch (r) {
  4931. o = !0, n = r;
  4932. } finally {
  4933. try {
  4934. if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
  4935. } finally {
  4936. if (o) throw n;
  4937. }
  4938. }
  4939. return a;
  4940. }
  4941. }
  4942. function _iterableToArrayLimitLoose(e, r) {
  4943. var t = e && ("undefined" != typeof Symbol && e[Symbol.iterator] || e["@@iterator"]);
  4944. if (null != t) {
  4945. var o,
  4946. l = [];
  4947. for (t = t.call(e); e.length < r && !(o = t.next()).done;) l.push(o.value);
  4948. return l;
  4949. }
  4950. }
  4951. var REACT_ELEMENT_TYPE;
  4952. function _jsx(e, r, E, l) {
  4953. REACT_ELEMENT_TYPE || (REACT_ELEMENT_TYPE = "function" == typeof Symbol && Symbol.for && Symbol.for("react.element") || 60103);
  4954. var o = e && e.defaultProps,
  4955. n = arguments.length - 3;
  4956. if (r || 0 === n || (r = {
  4957. children: void 0
  4958. }), 1 === n) r.children = l;else if (n > 1) {
  4959. for (var t = new Array(n), f = 0; f < n; f++) t[f] = arguments[f + 3];
  4960. r.children = t;
  4961. }
  4962. if (r && o) for (var i in o) void 0 === r[i] && (r[i] = o[i]);else r || (r = o || {});
  4963. return {
  4964. $$typeof: REACT_ELEMENT_TYPE,
  4965. type: e,
  4966. key: void 0 === E ? null : "" + E,
  4967. ref: null,
  4968. props: r,
  4969. _owner: null
  4970. };
  4971. }
  4972. function ownKeys(e, r) {
  4973. var t = Object.keys(e);
  4974. if (Object.getOwnPropertySymbols) {
  4975. var o = Object.getOwnPropertySymbols(e);
  4976. r && (o = o.filter(function (r) {
  4977. return Object.getOwnPropertyDescriptor(e, r).enumerable;
  4978. })), t.push.apply(t, o);
  4979. }
  4980. return t;
  4981. }
  4982. function _objectSpread2(e) {
  4983. for (var r = 1; r < arguments.length; r++) {
  4984. var t = null != arguments[r] ? arguments[r] : {};
  4985. r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
  4986. _defineProperty(e, r, t[r]);
  4987. }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
  4988. Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
  4989. });
  4990. }
  4991. return e;
  4992. }
  4993. function _regeneratorRuntime() {
  4994. "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
  4995. _regeneratorRuntime = function () {
  4996. return e;
  4997. };
  4998. var t,
  4999. e = {},
  5000. r = Object.prototype,
  5001. n = r.hasOwnProperty,
  5002. o = Object.defineProperty || function (t, e, r) {
  5003. t[e] = r.value;
  5004. },
  5005. i = "function" == typeof Symbol ? Symbol : {},
  5006. a = i.iterator || "@@iterator",
  5007. c = i.asyncIterator || "@@asyncIterator",
  5008. u = i.toStringTag || "@@toStringTag";
  5009. function define(t, e, r) {
  5010. return Object.defineProperty(t, e, {
  5011. value: r,
  5012. enumerable: !0,
  5013. configurable: !0,
  5014. writable: !0
  5015. }), t[e];
  5016. }
  5017. try {
  5018. define({}, "");
  5019. } catch (t) {
  5020. define = function (t, e, r) {
  5021. return t[e] = r;
  5022. };
  5023. }
  5024. function wrap(t, e, r, n) {
  5025. var i = e && e.prototype instanceof Generator ? e : Generator,
  5026. a = Object.create(i.prototype),
  5027. c = new Context(n || []);
  5028. return o(a, "_invoke", {
  5029. value: makeInvokeMethod(t, r, c)
  5030. }), a;
  5031. }
  5032. function tryCatch(t, e, r) {
  5033. try {
  5034. return {
  5035. type: "normal",
  5036. arg: t.call(e, r)
  5037. };
  5038. } catch (t) {
  5039. return {
  5040. type: "throw",
  5041. arg: t
  5042. };
  5043. }
  5044. }
  5045. e.wrap = wrap;
  5046. var h = "suspendedStart",
  5047. l = "suspendedYield",
  5048. f = "executing",
  5049. s = "completed",
  5050. y = {};
  5051. function Generator() {}
  5052. function GeneratorFunction() {}
  5053. function GeneratorFunctionPrototype() {}
  5054. var p = {};
  5055. define(p, a, function () {
  5056. return this;
  5057. });
  5058. var d = Object.getPrototypeOf,
  5059. v = d && d(d(values([])));
  5060. v && v !== r && n.call(v, a) && (p = v);
  5061. var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p);
  5062. function defineIteratorMethods(t) {
  5063. ["next", "throw", "return"].forEach(function (e) {
  5064. define(t, e, function (t) {
  5065. return this._invoke(e, t);
  5066. });
  5067. });
  5068. }
  5069. function AsyncIterator(t, e) {
  5070. function invoke(r, o, i, a) {
  5071. var c = tryCatch(t[r], t, o);
  5072. if ("throw" !== c.type) {
  5073. var u = c.arg,
  5074. h = u.value;
  5075. return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) {
  5076. invoke("next", t, i, a);
  5077. }, function (t) {
  5078. invoke("throw", t, i, a);
  5079. }) : e.resolve(h).then(function (t) {
  5080. u.value = t, i(u);
  5081. }, function (t) {
  5082. return invoke("throw", t, i, a);
  5083. });
  5084. }
  5085. a(c.arg);
  5086. }
  5087. var r;
  5088. o(this, "_invoke", {
  5089. value: function (t, n) {
  5090. function callInvokeWithMethodAndArg() {
  5091. return new e(function (e, r) {
  5092. invoke(t, n, e, r);
  5093. });
  5094. }
  5095. return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
  5096. }
  5097. });
  5098. }
  5099. function makeInvokeMethod(e, r, n) {
  5100. var o = h;
  5101. return function (i, a) {
  5102. if (o === f) throw new Error("Generator is already running");
  5103. if (o === s) {
  5104. if ("throw" === i) throw a;
  5105. return {
  5106. value: t,
  5107. done: !0
  5108. };
  5109. }
  5110. for (n.method = i, n.arg = a;;) {
  5111. var c = n.delegate;
  5112. if (c) {
  5113. var u = maybeInvokeDelegate(c, n);
  5114. if (u) {
  5115. if (u === y) continue;
  5116. return u;
  5117. }
  5118. }
  5119. if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) {
  5120. if (o === h) throw o = s, n.arg;
  5121. n.dispatchException(n.arg);
  5122. } else "return" === n.method && n.abrupt("return", n.arg);
  5123. o = f;
  5124. var p = tryCatch(e, r, n);
  5125. if ("normal" === p.type) {
  5126. if (o = n.done ? s : l, p.arg === y) continue;
  5127. return {
  5128. value: p.arg,
  5129. done: n.done
  5130. };
  5131. }
  5132. "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg);
  5133. }
  5134. };
  5135. }
  5136. function maybeInvokeDelegate(e, r) {
  5137. var n = r.method,
  5138. o = e.iterator[n];
  5139. 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;
  5140. var i = tryCatch(o, e.iterator, r.arg);
  5141. if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y;
  5142. var a = i.arg;
  5143. 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);
  5144. }
  5145. function pushTryEntry(t) {
  5146. var e = {
  5147. tryLoc: t[0]
  5148. };
  5149. 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e);
  5150. }
  5151. function resetTryEntry(t) {
  5152. var e = t.completion || {};
  5153. e.type = "normal", delete e.arg, t.completion = e;
  5154. }
  5155. function Context(t) {
  5156. this.tryEntries = [{
  5157. tryLoc: "root"
  5158. }], t.forEach(pushTryEntry, this), this.reset(!0);
  5159. }
  5160. function values(e) {
  5161. if (e || "" === e) {
  5162. var r = e[a];
  5163. if (r) return r.call(e);
  5164. if ("function" == typeof e.next) return e;
  5165. if (!isNaN(e.length)) {
  5166. var o = -1,
  5167. i = function next() {
  5168. for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next;
  5169. return next.value = t, next.done = !0, next;
  5170. };
  5171. return i.next = i;
  5172. }
  5173. }
  5174. throw new TypeError(typeof e + " is not iterable");
  5175. }
  5176. return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", {
  5177. value: GeneratorFunctionPrototype,
  5178. configurable: !0
  5179. }), o(GeneratorFunctionPrototype, "constructor", {
  5180. value: GeneratorFunction,
  5181. configurable: !0
  5182. }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) {
  5183. var e = "function" == typeof t && t.constructor;
  5184. return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name));
  5185. }, e.mark = function (t) {
  5186. return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t;
  5187. }, e.awrap = function (t) {
  5188. return {
  5189. __await: t
  5190. };
  5191. }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () {
  5192. return this;
  5193. }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) {
  5194. void 0 === i && (i = Promise);
  5195. var a = new AsyncIterator(wrap(t, r, n, o), i);
  5196. return e.isGeneratorFunction(r) ? a : a.next().then(function (t) {
  5197. return t.done ? t.value : a.next();
  5198. });
  5199. }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () {
  5200. return this;
  5201. }), define(g, "toString", function () {
  5202. return "[object Generator]";
  5203. }), e.keys = function (t) {
  5204. var e = Object(t),
  5205. r = [];
  5206. for (var n in e) r.push(n);
  5207. return r.reverse(), function next() {
  5208. for (; r.length;) {
  5209. var t = r.pop();
  5210. if (t in e) return next.value = t, next.done = !1, next;
  5211. }
  5212. return next.done = !0, next;
  5213. };
  5214. }, e.values = values, Context.prototype = {
  5215. constructor: Context,
  5216. reset: function (e) {
  5217. 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);
  5218. },
  5219. stop: function () {
  5220. this.done = !0;
  5221. var t = this.tryEntries[0].completion;
  5222. if ("throw" === t.type) throw t.arg;
  5223. return this.rval;
  5224. },
  5225. dispatchException: function (e) {
  5226. if (this.done) throw e;
  5227. var r = this;
  5228. function handle(n, o) {
  5229. return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o;
  5230. }
  5231. for (var o = this.tryEntries.length - 1; o >= 0; --o) {
  5232. var i = this.tryEntries[o],
  5233. a = i.completion;
  5234. if ("root" === i.tryLoc) return handle("end");
  5235. if (i.tryLoc <= this.prev) {
  5236. var c = n.call(i, "catchLoc"),
  5237. u = n.call(i, "finallyLoc");
  5238. if (c && u) {
  5239. if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
  5240. if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
  5241. } else if (c) {
  5242. if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
  5243. } else {
  5244. if (!u) throw new Error("try statement without catch or finally");
  5245. if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
  5246. }
  5247. }
  5248. }
  5249. },
  5250. abrupt: function (t, e) {
  5251. for (var r = this.tryEntries.length - 1; r >= 0; --r) {
  5252. var o = this.tryEntries[r];
  5253. if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
  5254. var i = o;
  5255. break;
  5256. }
  5257. }
  5258. i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
  5259. var a = i ? i.completion : {};
  5260. return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a);
  5261. },
  5262. complete: function (t, e) {
  5263. if ("throw" === t.type) throw t.arg;
  5264. 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;
  5265. },
  5266. finish: function (t) {
  5267. for (var e = this.tryEntries.length - 1; e >= 0; --e) {
  5268. var r = this.tryEntries[e];
  5269. if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y;
  5270. }
  5271. },
  5272. catch: function (t) {
  5273. for (var e = this.tryEntries.length - 1; e >= 0; --e) {
  5274. var r = this.tryEntries[e];
  5275. if (r.tryLoc === t) {
  5276. var n = r.completion;
  5277. if ("throw" === n.type) {
  5278. var o = n.arg;
  5279. resetTryEntry(r);
  5280. }
  5281. return o;
  5282. }
  5283. }
  5284. throw new Error("illegal catch attempt");
  5285. },
  5286. delegateYield: function (e, r, n) {
  5287. return this.delegate = {
  5288. iterator: values(e),
  5289. resultName: r,
  5290. nextLoc: n
  5291. }, "next" === this.method && (this.arg = t), y;
  5292. }
  5293. }, e;
  5294. }
  5295. function _typeof(o) {
  5296. "@babel/helpers - typeof";
  5297. return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
  5298. return typeof o;
  5299. } : function (o) {
  5300. return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
  5301. }, _typeof(o);
  5302. }
  5303. function _using(o, e, n) {
  5304. if (null == e) return e;
  5305. if ("object" != typeof e) throw new TypeError("using declarations can only be used with objects, null, or undefined.");
  5306. if (n) var r = e[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
  5307. if (null == r && (r = e[Symbol.dispose || Symbol.for("Symbol.dispose")]), "function" != typeof r) throw new TypeError("Property [Symbol.dispose] is not a function.");
  5308. return o.push({
  5309. v: e,
  5310. d: r,
  5311. a: n
  5312. }), e;
  5313. }
  5314. function _wrapRegExp() {
  5315. _wrapRegExp = function (e, r) {
  5316. return new BabelRegExp(e, void 0, r);
  5317. };
  5318. var e = RegExp.prototype,
  5319. r = new WeakMap();
  5320. function BabelRegExp(e, t, p) {
  5321. var o = new RegExp(e, t);
  5322. return r.set(o, p || r.get(e)), _setPrototypeOf(o, BabelRegExp.prototype);
  5323. }
  5324. function buildGroups(e, t) {
  5325. var p = r.get(t);
  5326. return Object.keys(p).reduce(function (r, t) {
  5327. var o = p[t];
  5328. if ("number" == typeof o) r[t] = e[o];else {
  5329. for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++;
  5330. r[t] = e[o[i]];
  5331. }
  5332. return r;
  5333. }, Object.create(null));
  5334. }
  5335. return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) {
  5336. var t = e.exec.call(this, r);
  5337. if (t) {
  5338. t.groups = buildGroups(t, this);
  5339. var p = t.indices;
  5340. p && (p.groups = buildGroups(p, this));
  5341. }
  5342. return t;
  5343. }, BabelRegExp.prototype[Symbol.replace] = function (t, p) {
  5344. if ("string" == typeof p) {
  5345. var o = r.get(this);
  5346. return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)>/g, function (e, r) {
  5347. var t = o[r];
  5348. return "$" + (Array.isArray(t) ? t.join("$") : t);
  5349. }));
  5350. }
  5351. if ("function" == typeof p) {
  5352. var i = this;
  5353. return e[Symbol.replace].call(this, t, function () {
  5354. var e = arguments;
  5355. return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e);
  5356. });
  5357. }
  5358. return e[Symbol.replace].call(this, t, p);
  5359. }, _wrapRegExp.apply(this, arguments);
  5360. }
  5361. function _AwaitValue(value) {
  5362. this.wrapped = value;
  5363. }
  5364. function _wrapAsyncGenerator(fn) {
  5365. return function () {
  5366. return new _AsyncGenerator(fn.apply(this, arguments));
  5367. };
  5368. }
  5369. function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  5370. try {
  5371. var info = gen[key](arg);
  5372. var value = info.value;
  5373. } catch (error) {
  5374. reject(error);
  5375. return;
  5376. }
  5377. if (info.done) {
  5378. resolve(value);
  5379. } else {
  5380. Promise.resolve(value).then(_next, _throw);
  5381. }
  5382. }
  5383. function _asyncToGenerator(fn) {
  5384. return function () {
  5385. var self = this,
  5386. args = arguments;
  5387. return new Promise(function (resolve, reject) {
  5388. var gen = fn.apply(self, args);
  5389. function _next(value) {
  5390. asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
  5391. }
  5392. function _throw(err) {
  5393. asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
  5394. }
  5395. _next(undefined);
  5396. });
  5397. };
  5398. }
  5399. function _classCallCheck(instance, Constructor) {
  5400. if (!(instance instanceof Constructor)) {
  5401. throw new TypeError("Cannot call a class as a function");
  5402. }
  5403. }
  5404. function _defineProperties(target, props) {
  5405. for (var i = 0; i < props.length; i++) {
  5406. var descriptor = props[i];
  5407. descriptor.enumerable = descriptor.enumerable || false;
  5408. descriptor.configurable = true;
  5409. if ("value" in descriptor) descriptor.writable = true;
  5410. Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
  5411. }
  5412. }
  5413. function _createClass(Constructor, protoProps, staticProps) {
  5414. if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  5415. if (staticProps) _defineProperties(Constructor, staticProps);
  5416. Object.defineProperty(Constructor, "prototype", {
  5417. writable: false
  5418. });
  5419. return Constructor;
  5420. }
  5421. function _defineEnumerableProperties(obj, descs) {
  5422. for (var key in descs) {
  5423. var desc = descs[key];
  5424. desc.configurable = desc.enumerable = true;
  5425. if ("value" in desc) desc.writable = true;
  5426. Object.defineProperty(obj, key, desc);
  5427. }
  5428. if (Object.getOwnPropertySymbols) {
  5429. var objectSymbols = Object.getOwnPropertySymbols(descs);
  5430. for (var i = 0; i < objectSymbols.length; i++) {
  5431. var sym = objectSymbols[i];
  5432. var desc = descs[sym];
  5433. desc.configurable = desc.enumerable = true;
  5434. if ("value" in desc) desc.writable = true;
  5435. Object.defineProperty(obj, sym, desc);
  5436. }
  5437. }
  5438. return obj;
  5439. }
  5440. function _defaults(obj, defaults) {
  5441. var keys = Object.getOwnPropertyNames(defaults);
  5442. for (var i = 0; i < keys.length; i++) {
  5443. var key = keys[i];
  5444. var value = Object.getOwnPropertyDescriptor(defaults, key);
  5445. if (value && value.configurable && obj[key] === undefined) {
  5446. Object.defineProperty(obj, key, value);
  5447. }
  5448. }
  5449. return obj;
  5450. }
  5451. function _defineProperty(obj, key, value) {
  5452. key = _toPropertyKey(key);
  5453. if (key in obj) {
  5454. Object.defineProperty(obj, key, {
  5455. value: value,
  5456. enumerable: true,
  5457. configurable: true,
  5458. writable: true
  5459. });
  5460. } else {
  5461. obj[key] = value;
  5462. }
  5463. return obj;
  5464. }
  5465. function _extends() {
  5466. _extends = Object.assign ? Object.assign.bind() : function (target) {
  5467. for (var i = 1; i < arguments.length; i++) {
  5468. var source = arguments[i];
  5469. for (var key in source) {
  5470. if (Object.prototype.hasOwnProperty.call(source, key)) {
  5471. target[key] = source[key];
  5472. }
  5473. }
  5474. }
  5475. return target;
  5476. };
  5477. return _extends.apply(this, arguments);
  5478. }
  5479. function _objectSpread(target) {
  5480. for (var i = 1; i < arguments.length; i++) {
  5481. var source = arguments[i] != null ? Object(arguments[i]) : {};
  5482. var ownKeys = Object.keys(source);
  5483. if (typeof Object.getOwnPropertySymbols === 'function') {
  5484. ownKeys.push.apply(ownKeys, Object.getOwnPropertySymbols(source).filter(function (sym) {
  5485. return Object.getOwnPropertyDescriptor(source, sym).enumerable;
  5486. }));
  5487. }
  5488. ownKeys.forEach(function (key) {
  5489. _defineProperty(target, key, source[key]);
  5490. });
  5491. }
  5492. return target;
  5493. }
  5494. function _inherits(subClass, superClass) {
  5495. if (typeof superClass !== "function" && superClass !== null) {
  5496. throw new TypeError("Super expression must either be null or a function");
  5497. }
  5498. subClass.prototype = Object.create(superClass && superClass.prototype, {
  5499. constructor: {
  5500. value: subClass,
  5501. writable: true,
  5502. configurable: true
  5503. }
  5504. });
  5505. Object.defineProperty(subClass, "prototype", {
  5506. writable: false
  5507. });
  5508. if (superClass) _setPrototypeOf(subClass, superClass);
  5509. }
  5510. function _inheritsLoose(subClass, superClass) {
  5511. subClass.prototype = Object.create(superClass.prototype);
  5512. subClass.prototype.constructor = subClass;
  5513. _setPrototypeOf(subClass, superClass);
  5514. }
  5515. function _getPrototypeOf(o) {
  5516. _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
  5517. return o.__proto__ || Object.getPrototypeOf(o);
  5518. };
  5519. return _getPrototypeOf(o);
  5520. }
  5521. function _setPrototypeOf(o, p) {
  5522. _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
  5523. o.__proto__ = p;
  5524. return o;
  5525. };
  5526. return _setPrototypeOf(o, p);
  5527. }
  5528. function _isNativeReflectConstruct() {
  5529. if (typeof Reflect === "undefined" || !Reflect.construct) return false;
  5530. if (Reflect.construct.sham) return false;
  5531. if (typeof Proxy === "function") return true;
  5532. try {
  5533. Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
  5534. return true;
  5535. } catch (e) {
  5536. return false;
  5537. }
  5538. }
  5539. function _construct(Parent, args, Class) {
  5540. if (_isNativeReflectConstruct()) {
  5541. _construct = Reflect.construct.bind();
  5542. } else {
  5543. _construct = function _construct(Parent, args, Class) {
  5544. var a = [null];
  5545. a.push.apply(a, args);
  5546. var Constructor = Function.bind.apply(Parent, a);
  5547. var instance = new Constructor();
  5548. if (Class) _setPrototypeOf(instance, Class.prototype);
  5549. return instance;
  5550. };
  5551. }
  5552. return _construct.apply(null, arguments);
  5553. }
  5554. function _isNativeFunction(fn) {
  5555. return Function.toString.call(fn).indexOf("[native code]") !== -1;
  5556. }
  5557. function _wrapNativeSuper(Class) {
  5558. var _cache = typeof Map === "function" ? new Map() : undefined;
  5559. _wrapNativeSuper = function _wrapNativeSuper(Class) {
  5560. if (Class === null || !_isNativeFunction(Class)) return Class;
  5561. if (typeof Class !== "function") {
  5562. throw new TypeError("Super expression must either be null or a function");
  5563. }
  5564. if (typeof _cache !== "undefined") {
  5565. if (_cache.has(Class)) return _cache.get(Class);
  5566. _cache.set(Class, Wrapper);
  5567. }
  5568. function Wrapper() {
  5569. return _construct(Class, arguments, _getPrototypeOf(this).constructor);
  5570. }
  5571. Wrapper.prototype = Object.create(Class.prototype, {
  5572. constructor: {
  5573. value: Wrapper,
  5574. enumerable: false,
  5575. writable: true,
  5576. configurable: true
  5577. }
  5578. });
  5579. return _setPrototypeOf(Wrapper, Class);
  5580. };
  5581. return _wrapNativeSuper(Class);
  5582. }
  5583. function _instanceof(left, right) {
  5584. if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
  5585. return !!right[Symbol.hasInstance](left);
  5586. } else {
  5587. return left instanceof right;
  5588. }
  5589. }
  5590. function _interopRequireDefault(obj) {
  5591. return obj && obj.__esModule ? obj : {
  5592. default: obj
  5593. };
  5594. }
  5595. function _getRequireWildcardCache(nodeInterop) {
  5596. if (typeof WeakMap !== "function") return null;
  5597. var cacheBabelInterop = new WeakMap();
  5598. var cacheNodeInterop = new WeakMap();
  5599. return (_getRequireWildcardCache = function (nodeInterop) {
  5600. return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
  5601. })(nodeInterop);
  5602. }
  5603. function _interopRequireWildcard(obj, nodeInterop) {
  5604. if (!nodeInterop && obj && obj.__esModule) {
  5605. return obj;
  5606. }
  5607. if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
  5608. return {
  5609. default: obj
  5610. };
  5611. }
  5612. var cache = _getRequireWildcardCache(nodeInterop);
  5613. if (cache && cache.has(obj)) {
  5614. return cache.get(obj);
  5615. }
  5616. var newObj = {};
  5617. var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
  5618. for (var key in obj) {
  5619. if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
  5620. var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
  5621. if (desc && (desc.get || desc.set)) {
  5622. Object.defineProperty(newObj, key, desc);
  5623. } else {
  5624. newObj[key] = obj[key];
  5625. }
  5626. }
  5627. }
  5628. newObj.default = obj;
  5629. if (cache) {
  5630. cache.set(obj, newObj);
  5631. }
  5632. return newObj;
  5633. }
  5634. function _newArrowCheck(innerThis, boundThis) {
  5635. if (innerThis !== boundThis) {
  5636. throw new TypeError("Cannot instantiate an arrow function");
  5637. }
  5638. }
  5639. function _objectDestructuringEmpty(obj) {
  5640. if (obj == null) throw new TypeError("Cannot destructure " + obj);
  5641. }
  5642. function _objectWithoutPropertiesLoose(source, excluded) {
  5643. if (source == null) return {};
  5644. var target = {};
  5645. var sourceKeys = Object.keys(source);
  5646. var key, i;
  5647. for (i = 0; i < sourceKeys.length; i++) {
  5648. key = sourceKeys[i];
  5649. if (excluded.indexOf(key) >= 0) continue;
  5650. target[key] = source[key];
  5651. }
  5652. return target;
  5653. }
  5654. function _objectWithoutProperties(source, excluded) {
  5655. if (source == null) return {};
  5656. var target = _objectWithoutPropertiesLoose(source, excluded);
  5657. var key, i;
  5658. if (Object.getOwnPropertySymbols) {
  5659. var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
  5660. for (i = 0; i < sourceSymbolKeys.length; i++) {
  5661. key = sourceSymbolKeys[i];
  5662. if (excluded.indexOf(key) >= 0) continue;
  5663. if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
  5664. target[key] = source[key];
  5665. }
  5666. }
  5667. return target;
  5668. }
  5669. function _assertThisInitialized(self) {
  5670. if (self === void 0) {
  5671. throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  5672. }
  5673. return self;
  5674. }
  5675. function _possibleConstructorReturn(self, call) {
  5676. if (call && (typeof call === "object" || typeof call === "function")) {
  5677. return call;
  5678. } else if (call !== void 0) {
  5679. throw new TypeError("Derived constructors may only return object or undefined");
  5680. }
  5681. return _assertThisInitialized(self);
  5682. }
  5683. function _createSuper(Derived) {
  5684. var hasNativeReflectConstruct = _isNativeReflectConstruct();
  5685. return function _createSuperInternal() {
  5686. var Super = _getPrototypeOf(Derived),
  5687. result;
  5688. if (hasNativeReflectConstruct) {
  5689. var NewTarget = _getPrototypeOf(this).constructor;
  5690. result = Reflect.construct(Super, arguments, NewTarget);
  5691. } else {
  5692. result = Super.apply(this, arguments);
  5693. }
  5694. return _possibleConstructorReturn(this, result);
  5695. };
  5696. }
  5697. function _superPropBase(object, property) {
  5698. while (!Object.prototype.hasOwnProperty.call(object, property)) {
  5699. object = _getPrototypeOf(object);
  5700. if (object === null) break;
  5701. }
  5702. return object;
  5703. }
  5704. function _get() {
  5705. if (typeof Reflect !== "undefined" && Reflect.get) {
  5706. _get = Reflect.get.bind();
  5707. } else {
  5708. _get = function _get(target, property, receiver) {
  5709. var base = _superPropBase(target, property);
  5710. if (!base) return;
  5711. var desc = Object.getOwnPropertyDescriptor(base, property);
  5712. if (desc.get) {
  5713. return desc.get.call(arguments.length < 3 ? target : receiver);
  5714. }
  5715. return desc.value;
  5716. };
  5717. }
  5718. return _get.apply(this, arguments);
  5719. }
  5720. function set(target, property, value, receiver) {
  5721. if (typeof Reflect !== "undefined" && Reflect.set) {
  5722. set = Reflect.set;
  5723. } else {
  5724. set = function set(target, property, value, receiver) {
  5725. var base = _superPropBase(target, property);
  5726. var desc;
  5727. if (base) {
  5728. desc = Object.getOwnPropertyDescriptor(base, property);
  5729. if (desc.set) {
  5730. desc.set.call(receiver, value);
  5731. return true;
  5732. } else if (!desc.writable) {
  5733. return false;
  5734. }
  5735. }
  5736. desc = Object.getOwnPropertyDescriptor(receiver, property);
  5737. if (desc) {
  5738. if (!desc.writable) {
  5739. return false;
  5740. }
  5741. desc.value = value;
  5742. Object.defineProperty(receiver, property, desc);
  5743. } else {
  5744. _defineProperty(receiver, property, value);
  5745. }
  5746. return true;
  5747. };
  5748. }
  5749. return set(target, property, value, receiver);
  5750. }
  5751. function _set(target, property, value, receiver, isStrict) {
  5752. var s = set(target, property, value, receiver || target);
  5753. if (!s && isStrict) {
  5754. throw new TypeError('failed to set property');
  5755. }
  5756. return value;
  5757. }
  5758. function _taggedTemplateLiteral(strings, raw) {
  5759. if (!raw) {
  5760. raw = strings.slice(0);
  5761. }
  5762. return Object.freeze(Object.defineProperties(strings, {
  5763. raw: {
  5764. value: Object.freeze(raw)
  5765. }
  5766. }));
  5767. }
  5768. function _taggedTemplateLiteralLoose(strings, raw) {
  5769. if (!raw) {
  5770. raw = strings.slice(0);
  5771. }
  5772. strings.raw = raw;
  5773. return strings;
  5774. }
  5775. function _readOnlyError(name) {
  5776. throw new TypeError("\"" + name + "\" is read-only");
  5777. }
  5778. function _writeOnlyError(name) {
  5779. throw new TypeError("\"" + name + "\" is write-only");
  5780. }
  5781. function _classNameTDZError(name) {
  5782. throw new ReferenceError("Class \"" + name + "\" cannot be referenced in computed property keys.");
  5783. }
  5784. function _temporalUndefined() {}
  5785. function _tdz(name) {
  5786. throw new ReferenceError(name + " is not defined - temporal dead zone");
  5787. }
  5788. function _temporalRef(val, name) {
  5789. return val === _temporalUndefined ? _tdz(name) : val;
  5790. }
  5791. function _slicedToArray(arr, i) {
  5792. return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
  5793. }
  5794. function _slicedToArrayLoose(arr, i) {
  5795. return _arrayWithHoles(arr) || _iterableToArrayLimitLoose(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
  5796. }
  5797. function _toArray(arr) {
  5798. return _arrayWithHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableRest();
  5799. }
  5800. function _toConsumableArray(arr) {
  5801. return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
  5802. }
  5803. function _arrayWithoutHoles(arr) {
  5804. if (Array.isArray(arr)) return _arrayLikeToArray(arr);
  5805. }
  5806. function _arrayWithHoles(arr) {
  5807. if (Array.isArray(arr)) return arr;
  5808. }
  5809. function _maybeArrayLike(next, arr, i) {
  5810. if (arr && !Array.isArray(arr) && typeof arr.length === "number") {
  5811. var len = arr.length;
  5812. return _arrayLikeToArray(arr, i !== void 0 && i < len ? i : len);
  5813. }
  5814. return next(arr, i);
  5815. }
  5816. function _iterableToArray(iter) {
  5817. if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
  5818. }
  5819. function _unsupportedIterableToArray(o, minLen) {
  5820. if (!o) return;
  5821. if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  5822. var n = Object.prototype.toString.call(o).slice(8, -1);
  5823. if (n === "Object" && o.constructor) n = o.constructor.name;
  5824. if (n === "Map" || n === "Set") return Array.from(o);
  5825. if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  5826. }
  5827. function _arrayLikeToArray(arr, len) {
  5828. if (len == null || len > arr.length) len = arr.length;
  5829. for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
  5830. return arr2;
  5831. }
  5832. function _nonIterableSpread() {
  5833. throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  5834. }
  5835. function _nonIterableRest() {
  5836. throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  5837. }
  5838. function _createForOfIteratorHelper(o, allowArrayLike) {
  5839. var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
  5840. if (!it) {
  5841. if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
  5842. if (it) o = it;
  5843. var i = 0;
  5844. var F = function () {};
  5845. return {
  5846. s: F,
  5847. n: function () {
  5848. if (i >= o.length) return {
  5849. done: true
  5850. };
  5851. return {
  5852. done: false,
  5853. value: o[i++]
  5854. };
  5855. },
  5856. e: function (e) {
  5857. throw e;
  5858. },
  5859. f: F
  5860. };
  5861. }
  5862. throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  5863. }
  5864. var normalCompletion = true,
  5865. didErr = false,
  5866. err;
  5867. return {
  5868. s: function () {
  5869. it = it.call(o);
  5870. },
  5871. n: function () {
  5872. var step = it.next();
  5873. normalCompletion = step.done;
  5874. return step;
  5875. },
  5876. e: function (e) {
  5877. didErr = true;
  5878. err = e;
  5879. },
  5880. f: function () {
  5881. try {
  5882. if (!normalCompletion && it.return != null) it.return();
  5883. } finally {
  5884. if (didErr) throw err;
  5885. }
  5886. }
  5887. };
  5888. }
  5889. function _createForOfIteratorHelperLoose(o, allowArrayLike) {
  5890. var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
  5891. if (it) return (it = it.call(o)).next.bind(it);
  5892. if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
  5893. if (it) o = it;
  5894. var i = 0;
  5895. return function () {
  5896. if (i >= o.length) return {
  5897. done: true
  5898. };
  5899. return {
  5900. done: false,
  5901. value: o[i++]
  5902. };
  5903. };
  5904. }
  5905. throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  5906. }
  5907. function _skipFirstGeneratorNext(fn) {
  5908. return function () {
  5909. var it = fn.apply(this, arguments);
  5910. it.next();
  5911. return it;
  5912. };
  5913. }
  5914. function _toPrimitive(input, hint) {
  5915. if (typeof input !== "object" || input === null) return input;
  5916. var prim = input[Symbol.toPrimitive];
  5917. if (prim !== undefined) {
  5918. var res = prim.call(input, hint || "default");
  5919. if (typeof res !== "object") return res;
  5920. throw new TypeError("@@toPrimitive must return a primitive value.");
  5921. }
  5922. return (hint === "string" ? String : Number)(input);
  5923. }
  5924. function _toPropertyKey(arg) {
  5925. var key = _toPrimitive(arg, "string");
  5926. return typeof key === "symbol" ? key : String(key);
  5927. }
  5928. function _initializerWarningHelper(descriptor, context) {
  5929. throw new Error('Decorating class property failed. Please ensure that ' + 'transform-class-properties is enabled and runs after the decorators transform.');
  5930. }
  5931. function _initializerDefineProperty(target, property, descriptor, context) {
  5932. if (!descriptor) return;
  5933. Object.defineProperty(target, property, {
  5934. enumerable: descriptor.enumerable,
  5935. configurable: descriptor.configurable,
  5936. writable: descriptor.writable,
  5937. value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
  5938. });
  5939. }
  5940. function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
  5941. var desc = {};
  5942. Object.keys(descriptor).forEach(function (key) {
  5943. desc[key] = descriptor[key];
  5944. });
  5945. desc.enumerable = !!desc.enumerable;
  5946. desc.configurable = !!desc.configurable;
  5947. if ('value' in desc || desc.initializer) {
  5948. desc.writable = true;
  5949. }
  5950. desc = decorators.slice().reverse().reduce(function (desc, decorator) {
  5951. return decorator(target, property, desc) || desc;
  5952. }, desc);
  5953. if (context && desc.initializer !== void 0) {
  5954. desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
  5955. desc.initializer = undefined;
  5956. }
  5957. if (desc.initializer === void 0) {
  5958. Object.defineProperty(target, property, desc);
  5959. desc = null;
  5960. }
  5961. return desc;
  5962. }
  5963. var id$1 = 0;
  5964. function _classPrivateFieldLooseKey(name) {
  5965. return "__private_" + id$1++ + "_" + name;
  5966. }
  5967. function _classPrivateFieldLooseBase(receiver, privateKey) {
  5968. if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
  5969. throw new TypeError("attempted to use private field on non-instance");
  5970. }
  5971. return receiver;
  5972. }
  5973. function _classPrivateFieldGet(receiver, privateMap) {
  5974. var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get");
  5975. return _classApplyDescriptorGet(receiver, descriptor);
  5976. }
  5977. function _classPrivateFieldSet(receiver, privateMap, value) {
  5978. var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set");
  5979. _classApplyDescriptorSet(receiver, descriptor, value);
  5980. return value;
  5981. }
  5982. function _classPrivateFieldDestructureSet(receiver, privateMap) {
  5983. var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set");
  5984. return _classApplyDescriptorDestructureSet(receiver, descriptor);
  5985. }
  5986. function _classExtractFieldDescriptor(receiver, privateMap, action) {
  5987. if (!privateMap.has(receiver)) {
  5988. throw new TypeError("attempted to " + action + " private field on non-instance");
  5989. }
  5990. return privateMap.get(receiver);
  5991. }
  5992. function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) {
  5993. _classCheckPrivateStaticAccess(receiver, classConstructor);
  5994. _classCheckPrivateStaticFieldDescriptor(descriptor, "get");
  5995. return _classApplyDescriptorGet(receiver, descriptor);
  5996. }
  5997. function _classStaticPrivateFieldSpecSet(receiver, classConstructor, descriptor, value) {
  5998. _classCheckPrivateStaticAccess(receiver, classConstructor);
  5999. _classCheckPrivateStaticFieldDescriptor(descriptor, "set");
  6000. _classApplyDescriptorSet(receiver, descriptor, value);
  6001. return value;
  6002. }
  6003. function _classStaticPrivateMethodGet(receiver, classConstructor, method) {
  6004. _classCheckPrivateStaticAccess(receiver, classConstructor);
  6005. return method;
  6006. }
  6007. function _classStaticPrivateMethodSet() {
  6008. throw new TypeError("attempted to set read only static private field");
  6009. }
  6010. function _classApplyDescriptorGet(receiver, descriptor) {
  6011. if (descriptor.get) {
  6012. return descriptor.get.call(receiver);
  6013. }
  6014. return descriptor.value;
  6015. }
  6016. function _classApplyDescriptorSet(receiver, descriptor, value) {
  6017. if (descriptor.set) {
  6018. descriptor.set.call(receiver, value);
  6019. } else {
  6020. if (!descriptor.writable) {
  6021. throw new TypeError("attempted to set read only private field");
  6022. }
  6023. descriptor.value = value;
  6024. }
  6025. }
  6026. function _classApplyDescriptorDestructureSet(receiver, descriptor) {
  6027. if (descriptor.set) {
  6028. if (!("__destrObj" in descriptor)) {
  6029. descriptor.__destrObj = {
  6030. set value(v) {
  6031. descriptor.set.call(receiver, v);
  6032. }
  6033. };
  6034. }
  6035. return descriptor.__destrObj;
  6036. } else {
  6037. if (!descriptor.writable) {
  6038. throw new TypeError("attempted to set read only private field");
  6039. }
  6040. return descriptor;
  6041. }
  6042. }
  6043. function _classStaticPrivateFieldDestructureSet(receiver, classConstructor, descriptor) {
  6044. _classCheckPrivateStaticAccess(receiver, classConstructor);
  6045. _classCheckPrivateStaticFieldDescriptor(descriptor, "set");
  6046. return _classApplyDescriptorDestructureSet(receiver, descriptor);
  6047. }
  6048. function _classCheckPrivateStaticAccess(receiver, classConstructor) {
  6049. if (receiver !== classConstructor) {
  6050. throw new TypeError("Private static access of wrong provenance");
  6051. }
  6052. }
  6053. function _classCheckPrivateStaticFieldDescriptor(descriptor, action) {
  6054. if (descriptor === undefined) {
  6055. throw new TypeError("attempted to " + action + " private static field before its declaration");
  6056. }
  6057. }
  6058. function _decorate(decorators, factory, superClass, mixins) {
  6059. var api = _getDecoratorsApi();
  6060. if (mixins) {
  6061. for (var i = 0; i < mixins.length; i++) {
  6062. api = mixins[i](api);
  6063. }
  6064. }
  6065. var r = factory(function initialize(O) {
  6066. api.initializeInstanceElements(O, decorated.elements);
  6067. }, superClass);
  6068. var decorated = api.decorateClass(_coalesceClassElements(r.d.map(_createElementDescriptor)), decorators);
  6069. api.initializeClassElements(r.F, decorated.elements);
  6070. return api.runClassFinishers(r.F, decorated.finishers);
  6071. }
  6072. function _getDecoratorsApi() {
  6073. _getDecoratorsApi = function () {
  6074. return api;
  6075. };
  6076. var api = {
  6077. elementsDefinitionOrder: [["method"], ["field"]],
  6078. initializeInstanceElements: function (O, elements) {
  6079. ["method", "field"].forEach(function (kind) {
  6080. elements.forEach(function (element) {
  6081. if (element.kind === kind && element.placement === "own") {
  6082. this.defineClassElement(O, element);
  6083. }
  6084. }, this);
  6085. }, this);
  6086. },
  6087. initializeClassElements: function (F, elements) {
  6088. var proto = F.prototype;
  6089. ["method", "field"].forEach(function (kind) {
  6090. elements.forEach(function (element) {
  6091. var placement = element.placement;
  6092. if (element.kind === kind && (placement === "static" || placement === "prototype")) {
  6093. var receiver = placement === "static" ? F : proto;
  6094. this.defineClassElement(receiver, element);
  6095. }
  6096. }, this);
  6097. }, this);
  6098. },
  6099. defineClassElement: function (receiver, element) {
  6100. var descriptor = element.descriptor;
  6101. if (element.kind === "field") {
  6102. var initializer = element.initializer;
  6103. descriptor = {
  6104. enumerable: descriptor.enumerable,
  6105. writable: descriptor.writable,
  6106. configurable: descriptor.configurable,
  6107. value: initializer === void 0 ? void 0 : initializer.call(receiver)
  6108. };
  6109. }
  6110. Object.defineProperty(receiver, element.key, descriptor);
  6111. },
  6112. decorateClass: function (elements, decorators) {
  6113. var newElements = [];
  6114. var finishers = [];
  6115. var placements = {
  6116. static: [],
  6117. prototype: [],
  6118. own: []
  6119. };
  6120. elements.forEach(function (element) {
  6121. this.addElementPlacement(element, placements);
  6122. }, this);
  6123. elements.forEach(function (element) {
  6124. if (!_hasDecorators(element)) return newElements.push(element);
  6125. var elementFinishersExtras = this.decorateElement(element, placements);
  6126. newElements.push(elementFinishersExtras.element);
  6127. newElements.push.apply(newElements, elementFinishersExtras.extras);
  6128. finishers.push.apply(finishers, elementFinishersExtras.finishers);
  6129. }, this);
  6130. if (!decorators) {
  6131. return {
  6132. elements: newElements,
  6133. finishers: finishers
  6134. };
  6135. }
  6136. var result = this.decorateConstructor(newElements, decorators);
  6137. finishers.push.apply(finishers, result.finishers);
  6138. result.finishers = finishers;
  6139. return result;
  6140. },
  6141. addElementPlacement: function (element, placements, silent) {
  6142. var keys = placements[element.placement];
  6143. if (!silent && keys.indexOf(element.key) !== -1) {
  6144. throw new TypeError("Duplicated element (" + element.key + ")");
  6145. }
  6146. keys.push(element.key);
  6147. },
  6148. decorateElement: function (element, placements) {
  6149. var extras = [];
  6150. var finishers = [];
  6151. for (var decorators = element.decorators, i = decorators.length - 1; i >= 0; i--) {
  6152. var keys = placements[element.placement];
  6153. keys.splice(keys.indexOf(element.key), 1);
  6154. var elementObject = this.fromElementDescriptor(element);
  6155. var elementFinisherExtras = this.toElementFinisherExtras((0, decorators[i])(elementObject) || elementObject);
  6156. element = elementFinisherExtras.element;
  6157. this.addElementPlacement(element, placements);
  6158. if (elementFinisherExtras.finisher) {
  6159. finishers.push(elementFinisherExtras.finisher);
  6160. }
  6161. var newExtras = elementFinisherExtras.extras;
  6162. if (newExtras) {
  6163. for (var j = 0; j < newExtras.length; j++) {
  6164. this.addElementPlacement(newExtras[j], placements);
  6165. }
  6166. extras.push.apply(extras, newExtras);
  6167. }
  6168. }
  6169. return {
  6170. element: element,
  6171. finishers: finishers,
  6172. extras: extras
  6173. };
  6174. },
  6175. decorateConstructor: function (elements, decorators) {
  6176. var finishers = [];
  6177. for (var i = decorators.length - 1; i >= 0; i--) {
  6178. var obj = this.fromClassDescriptor(elements);
  6179. var elementsAndFinisher = this.toClassDescriptor((0, decorators[i])(obj) || obj);
  6180. if (elementsAndFinisher.finisher !== undefined) {
  6181. finishers.push(elementsAndFinisher.finisher);
  6182. }
  6183. if (elementsAndFinisher.elements !== undefined) {
  6184. elements = elementsAndFinisher.elements;
  6185. for (var j = 0; j < elements.length - 1; j++) {
  6186. for (var k = j + 1; k < elements.length; k++) {
  6187. if (elements[j].key === elements[k].key && elements[j].placement === elements[k].placement) {
  6188. throw new TypeError("Duplicated element (" + elements[j].key + ")");
  6189. }
  6190. }
  6191. }
  6192. }
  6193. }
  6194. return {
  6195. elements: elements,
  6196. finishers: finishers
  6197. };
  6198. },
  6199. fromElementDescriptor: function (element) {
  6200. var obj = {
  6201. kind: element.kind,
  6202. key: element.key,
  6203. placement: element.placement,
  6204. descriptor: element.descriptor
  6205. };
  6206. var desc = {
  6207. value: "Descriptor",
  6208. configurable: true
  6209. };
  6210. Object.defineProperty(obj, Symbol.toStringTag, desc);
  6211. if (element.kind === "field") obj.initializer = element.initializer;
  6212. return obj;
  6213. },
  6214. toElementDescriptors: function (elementObjects) {
  6215. if (elementObjects === undefined) return;
  6216. return _toArray(elementObjects).map(function (elementObject) {
  6217. var element = this.toElementDescriptor(elementObject);
  6218. this.disallowProperty(elementObject, "finisher", "An element descriptor");
  6219. this.disallowProperty(elementObject, "extras", "An element descriptor");
  6220. return element;
  6221. }, this);
  6222. },
  6223. toElementDescriptor: function (elementObject) {
  6224. var kind = String(elementObject.kind);
  6225. if (kind !== "method" && kind !== "field") {
  6226. 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 + '"');
  6227. }
  6228. var key = _toPropertyKey(elementObject.key);
  6229. var placement = String(elementObject.placement);
  6230. if (placement !== "static" && placement !== "prototype" && placement !== "own") {
  6231. 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 + '"');
  6232. }
  6233. var descriptor = elementObject.descriptor;
  6234. this.disallowProperty(elementObject, "elements", "An element descriptor");
  6235. var element = {
  6236. kind: kind,
  6237. key: key,
  6238. placement: placement,
  6239. descriptor: Object.assign({}, descriptor)
  6240. };
  6241. if (kind !== "field") {
  6242. this.disallowProperty(elementObject, "initializer", "A method descriptor");
  6243. } else {
  6244. this.disallowProperty(descriptor, "get", "The property descriptor of a field descriptor");
  6245. this.disallowProperty(descriptor, "set", "The property descriptor of a field descriptor");
  6246. this.disallowProperty(descriptor, "value", "The property descriptor of a field descriptor");
  6247. element.initializer = elementObject.initializer;
  6248. }
  6249. return element;
  6250. },
  6251. toElementFinisherExtras: function (elementObject) {
  6252. var element = this.toElementDescriptor(elementObject);
  6253. var finisher = _optionalCallableProperty(elementObject, "finisher");
  6254. var extras = this.toElementDescriptors(elementObject.extras);
  6255. return {
  6256. element: element,
  6257. finisher: finisher,
  6258. extras: extras
  6259. };
  6260. },
  6261. fromClassDescriptor: function (elements) {
  6262. var obj = {
  6263. kind: "class",
  6264. elements: elements.map(this.fromElementDescriptor, this)
  6265. };
  6266. var desc = {
  6267. value: "Descriptor",
  6268. configurable: true
  6269. };
  6270. Object.defineProperty(obj, Symbol.toStringTag, desc);
  6271. return obj;
  6272. },
  6273. toClassDescriptor: function (obj) {
  6274. var kind = String(obj.kind);
  6275. if (kind !== "class") {
  6276. throw new TypeError('A class descriptor\'s .kind property must be "class", but a decorator' + ' created a class descriptor with .kind "' + kind + '"');
  6277. }
  6278. this.disallowProperty(obj, "key", "A class descriptor");
  6279. this.disallowProperty(obj, "placement", "A class descriptor");
  6280. this.disallowProperty(obj, "descriptor", "A class descriptor");
  6281. this.disallowProperty(obj, "initializer", "A class descriptor");
  6282. this.disallowProperty(obj, "extras", "A class descriptor");
  6283. var finisher = _optionalCallableProperty(obj, "finisher");
  6284. var elements = this.toElementDescriptors(obj.elements);
  6285. return {
  6286. elements: elements,
  6287. finisher: finisher
  6288. };
  6289. },
  6290. runClassFinishers: function (constructor, finishers) {
  6291. for (var i = 0; i < finishers.length; i++) {
  6292. var newConstructor = (0, finishers[i])(constructor);
  6293. if (newConstructor !== undefined) {
  6294. if (typeof newConstructor !== "function") {
  6295. throw new TypeError("Finishers must return a constructor.");
  6296. }
  6297. constructor = newConstructor;
  6298. }
  6299. }
  6300. return constructor;
  6301. },
  6302. disallowProperty: function (obj, name, objectType) {
  6303. if (obj[name] !== undefined) {
  6304. throw new TypeError(objectType + " can't have a ." + name + " property.");
  6305. }
  6306. }
  6307. };
  6308. return api;
  6309. }
  6310. function _createElementDescriptor(def) {
  6311. var key = _toPropertyKey(def.key);
  6312. var descriptor;
  6313. if (def.kind === "method") {
  6314. descriptor = {
  6315. value: def.value,
  6316. writable: true,
  6317. configurable: true,
  6318. enumerable: false
  6319. };
  6320. } else if (def.kind === "get") {
  6321. descriptor = {
  6322. get: def.value,
  6323. configurable: true,
  6324. enumerable: false
  6325. };
  6326. } else if (def.kind === "set") {
  6327. descriptor = {
  6328. set: def.value,
  6329. configurable: true,
  6330. enumerable: false
  6331. };
  6332. } else if (def.kind === "field") {
  6333. descriptor = {
  6334. configurable: true,
  6335. writable: true,
  6336. enumerable: true
  6337. };
  6338. }
  6339. var element = {
  6340. kind: def.kind === "field" ? "field" : "method",
  6341. key: key,
  6342. placement: def.static ? "static" : def.kind === "field" ? "own" : "prototype",
  6343. descriptor: descriptor
  6344. };
  6345. if (def.decorators) element.decorators = def.decorators;
  6346. if (def.kind === "field") element.initializer = def.value;
  6347. return element;
  6348. }
  6349. function _coalesceGetterSetter(element, other) {
  6350. if (element.descriptor.get !== undefined) {
  6351. other.descriptor.get = element.descriptor.get;
  6352. } else {
  6353. other.descriptor.set = element.descriptor.set;
  6354. }
  6355. }
  6356. function _coalesceClassElements(elements) {
  6357. var newElements = [];
  6358. var isSameElement = function (other) {
  6359. return other.kind === "method" && other.key === element.key && other.placement === element.placement;
  6360. };
  6361. for (var i = 0; i < elements.length; i++) {
  6362. var element = elements[i];
  6363. var other;
  6364. if (element.kind === "method" && (other = newElements.find(isSameElement))) {
  6365. if (_isDataDescriptor(element.descriptor) || _isDataDescriptor(other.descriptor)) {
  6366. if (_hasDecorators(element) || _hasDecorators(other)) {
  6367. throw new ReferenceError("Duplicated methods (" + element.key + ") can't be decorated.");
  6368. }
  6369. other.descriptor = element.descriptor;
  6370. } else {
  6371. if (_hasDecorators(element)) {
  6372. if (_hasDecorators(other)) {
  6373. throw new ReferenceError("Decorators can't be placed on different accessors with for " + "the same property (" + element.key + ").");
  6374. }
  6375. other.decorators = element.decorators;
  6376. }
  6377. _coalesceGetterSetter(element, other);
  6378. }
  6379. } else {
  6380. newElements.push(element);
  6381. }
  6382. }
  6383. return newElements;
  6384. }
  6385. function _hasDecorators(element) {
  6386. return element.decorators && element.decorators.length;
  6387. }
  6388. function _isDataDescriptor(desc) {
  6389. return desc !== undefined && !(desc.value === undefined && desc.writable === undefined);
  6390. }
  6391. function _optionalCallableProperty(obj, name) {
  6392. var value = obj[name];
  6393. if (value !== undefined && typeof value !== "function") {
  6394. throw new TypeError("Expected '" + name + "' to be a function");
  6395. }
  6396. return value;
  6397. }
  6398. function _classPrivateMethodGet(receiver, privateSet, fn) {
  6399. if (!privateSet.has(receiver)) {
  6400. throw new TypeError("attempted to get private field on non-instance");
  6401. }
  6402. return fn;
  6403. }
  6404. function _checkPrivateRedeclaration(obj, privateCollection) {
  6405. if (privateCollection.has(obj)) {
  6406. throw new TypeError("Cannot initialize the same private elements twice on an object");
  6407. }
  6408. }
  6409. function _classPrivateFieldInitSpec(obj, privateMap, value) {
  6410. _checkPrivateRedeclaration(obj, privateMap);
  6411. privateMap.set(obj, value);
  6412. }
  6413. function _classPrivateMethodInitSpec(obj, privateSet) {
  6414. _checkPrivateRedeclaration(obj, privateSet);
  6415. privateSet.add(obj);
  6416. }
  6417. function _classPrivateMethodSet() {
  6418. throw new TypeError("attempted to reassign private method");
  6419. }
  6420. function _identity(x) {
  6421. return x;
  6422. }
  6423. function _nullishReceiverError(r) {
  6424. throw new TypeError("Cannot set property of null or undefined.");
  6425. }
  6426. class Piece extends TrixObject {
  6427. static registerType(type, constructor) {
  6428. constructor.type = type;
  6429. this.types[type] = constructor;
  6430. }
  6431. static fromJSON(pieceJSON) {
  6432. const constructor = this.types[pieceJSON.type];
  6433. if (constructor) {
  6434. return constructor.fromJSON(pieceJSON);
  6435. }
  6436. }
  6437. constructor(value) {
  6438. let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  6439. super(...arguments);
  6440. this.attributes = Hash.box(attributes);
  6441. }
  6442. copyWithAttributes(attributes) {
  6443. return new this.constructor(this.getValue(), attributes);
  6444. }
  6445. copyWithAdditionalAttributes(attributes) {
  6446. return this.copyWithAttributes(this.attributes.merge(attributes));
  6447. }
  6448. copyWithoutAttribute(attribute) {
  6449. return this.copyWithAttributes(this.attributes.remove(attribute));
  6450. }
  6451. copy() {
  6452. return this.copyWithAttributes(this.attributes);
  6453. }
  6454. getAttribute(attribute) {
  6455. return this.attributes.get(attribute);
  6456. }
  6457. getAttributesHash() {
  6458. return this.attributes;
  6459. }
  6460. getAttributes() {
  6461. return this.attributes.toObject();
  6462. }
  6463. hasAttribute(attribute) {
  6464. return this.attributes.has(attribute);
  6465. }
  6466. hasSameStringValueAsPiece(piece) {
  6467. return piece && this.toString() === piece.toString();
  6468. }
  6469. hasSameAttributesAsPiece(piece) {
  6470. return piece && (this.attributes === piece.attributes || this.attributes.isEqualTo(piece.attributes));
  6471. }
  6472. isBlockBreak() {
  6473. return false;
  6474. }
  6475. isEqualTo(piece) {
  6476. return super.isEqualTo(...arguments) || this.hasSameConstructorAs(piece) && this.hasSameStringValueAsPiece(piece) && this.hasSameAttributesAsPiece(piece);
  6477. }
  6478. isEmpty() {
  6479. return this.length === 0;
  6480. }
  6481. isSerializable() {
  6482. return true;
  6483. }
  6484. toJSON() {
  6485. return {
  6486. type: this.constructor.type,
  6487. attributes: this.getAttributes()
  6488. };
  6489. }
  6490. contentsForInspection() {
  6491. return {
  6492. type: this.constructor.type,
  6493. attributes: this.attributes.inspect()
  6494. };
  6495. }
  6496. // Grouping
  6497. canBeGrouped() {
  6498. return this.hasAttribute("href");
  6499. }
  6500. canBeGroupedWith(piece) {
  6501. return this.getAttribute("href") === piece.getAttribute("href");
  6502. }
  6503. // Splittable
  6504. getLength() {
  6505. return this.length;
  6506. }
  6507. canBeConsolidatedWith(piece) {
  6508. return false;
  6509. }
  6510. }
  6511. _defineProperty(Piece, "types", {});
  6512. class ImagePreloadOperation extends Operation {
  6513. constructor(url) {
  6514. super(...arguments);
  6515. this.url = url;
  6516. }
  6517. perform(callback) {
  6518. const image = new Image();
  6519. image.onload = () => {
  6520. image.width = this.width = image.naturalWidth;
  6521. image.height = this.height = image.naturalHeight;
  6522. return callback(true, image);
  6523. };
  6524. image.onerror = () => callback(false);
  6525. image.src = this.url;
  6526. }
  6527. }
  6528. class Attachment extends TrixObject {
  6529. static attachmentForFile(file) {
  6530. const attributes = this.attributesForFile(file);
  6531. const attachment = new this(attributes);
  6532. attachment.setFile(file);
  6533. return attachment;
  6534. }
  6535. static attributesForFile(file) {
  6536. return new Hash({
  6537. filename: file.name,
  6538. filesize: file.size,
  6539. contentType: file.type
  6540. });
  6541. }
  6542. static fromJSON(attachmentJSON) {
  6543. return new this(attachmentJSON);
  6544. }
  6545. constructor() {
  6546. let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  6547. super(attributes);
  6548. this.releaseFile = this.releaseFile.bind(this);
  6549. this.attributes = Hash.box(attributes);
  6550. this.didChangeAttributes();
  6551. }
  6552. getAttribute(attribute) {
  6553. return this.attributes.get(attribute);
  6554. }
  6555. hasAttribute(attribute) {
  6556. return this.attributes.has(attribute);
  6557. }
  6558. getAttributes() {
  6559. return this.attributes.toObject();
  6560. }
  6561. setAttributes() {
  6562. let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  6563. const newAttributes = this.attributes.merge(attributes);
  6564. if (!this.attributes.isEqualTo(newAttributes)) {
  6565. var _this$previewDelegate, _this$previewDelegate2, _this$delegate, _this$delegate$attach;
  6566. this.attributes = newAttributes;
  6567. this.didChangeAttributes();
  6568. (_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);
  6569. 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);
  6570. }
  6571. }
  6572. didChangeAttributes() {
  6573. if (this.isPreviewable()) {
  6574. return this.preloadURL();
  6575. }
  6576. }
  6577. isPending() {
  6578. return this.file != null && !(this.getURL() || this.getHref());
  6579. }
  6580. isPreviewable() {
  6581. if (this.attributes.has("previewable")) {
  6582. return this.attributes.get("previewable");
  6583. } else {
  6584. return Attachment.previewablePattern.test(this.getContentType());
  6585. }
  6586. }
  6587. getType() {
  6588. if (this.hasContent()) {
  6589. return "content";
  6590. } else if (this.isPreviewable()) {
  6591. return "preview";
  6592. } else {
  6593. return "file";
  6594. }
  6595. }
  6596. getURL() {
  6597. return this.attributes.get("url");
  6598. }
  6599. getHref() {
  6600. return this.attributes.get("href");
  6601. }
  6602. getFilename() {
  6603. return this.attributes.get("filename") || "";
  6604. }
  6605. getFilesize() {
  6606. return this.attributes.get("filesize");
  6607. }
  6608. getFormattedFilesize() {
  6609. const filesize = this.attributes.get("filesize");
  6610. if (typeof filesize === "number") {
  6611. return file_size_formatting.formatter(filesize);
  6612. } else {
  6613. return "";
  6614. }
  6615. }
  6616. getExtension() {
  6617. var _this$getFilename$mat;
  6618. return (_this$getFilename$mat = this.getFilename().match(/\.(\w+)$/)) === null || _this$getFilename$mat === void 0 ? void 0 : _this$getFilename$mat[1].toLowerCase();
  6619. }
  6620. getContentType() {
  6621. return this.attributes.get("contentType");
  6622. }
  6623. hasContent() {
  6624. return this.attributes.has("content");
  6625. }
  6626. getContent() {
  6627. return this.attributes.get("content");
  6628. }
  6629. getWidth() {
  6630. return this.attributes.get("width");
  6631. }
  6632. getHeight() {
  6633. return this.attributes.get("height");
  6634. }
  6635. getFile() {
  6636. return this.file;
  6637. }
  6638. setFile(file) {
  6639. this.file = file;
  6640. if (this.isPreviewable()) {
  6641. return this.preloadFile();
  6642. }
  6643. }
  6644. releaseFile() {
  6645. this.releasePreloadedFile();
  6646. this.file = null;
  6647. }
  6648. getUploadProgress() {
  6649. return this.uploadProgress != null ? this.uploadProgress : 0;
  6650. }
  6651. setUploadProgress(value) {
  6652. if (this.uploadProgress !== value) {
  6653. var _this$uploadProgressD, _this$uploadProgressD2;
  6654. this.uploadProgress = value;
  6655. 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);
  6656. }
  6657. }
  6658. toJSON() {
  6659. return this.getAttributes();
  6660. }
  6661. getCacheKey() {
  6662. return [super.getCacheKey(...arguments), this.attributes.getCacheKey(), this.getPreviewURL()].join("/");
  6663. }
  6664. // Previewable
  6665. getPreviewURL() {
  6666. return this.previewURL || this.preloadingURL;
  6667. }
  6668. setPreviewURL(url) {
  6669. if (url !== this.getPreviewURL()) {
  6670. var _this$previewDelegate3, _this$previewDelegate4, _this$delegate2, _this$delegate2$attac;
  6671. this.previewURL = url;
  6672. (_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);
  6673. 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);
  6674. }
  6675. }
  6676. preloadURL() {
  6677. return this.preload(this.getURL(), this.releaseFile);
  6678. }
  6679. preloadFile() {
  6680. if (this.file) {
  6681. this.fileObjectURL = URL.createObjectURL(this.file);
  6682. return this.preload(this.fileObjectURL);
  6683. }
  6684. }
  6685. releasePreloadedFile() {
  6686. if (this.fileObjectURL) {
  6687. URL.revokeObjectURL(this.fileObjectURL);
  6688. this.fileObjectURL = null;
  6689. }
  6690. }
  6691. preload(url, callback) {
  6692. if (url && url !== this.getPreviewURL()) {
  6693. this.preloadingURL = url;
  6694. const operation = new ImagePreloadOperation(url);
  6695. return operation.then(_ref => {
  6696. let {
  6697. width,
  6698. height
  6699. } = _ref;
  6700. if (!this.getWidth() || !this.getHeight()) {
  6701. this.setAttributes({
  6702. width,
  6703. height
  6704. });
  6705. }
  6706. this.preloadingURL = null;
  6707. this.setPreviewURL(url);
  6708. return callback === null || callback === void 0 ? void 0 : callback();
  6709. }).catch(() => {
  6710. this.preloadingURL = null;
  6711. return callback === null || callback === void 0 ? void 0 : callback();
  6712. });
  6713. }
  6714. }
  6715. }
  6716. _defineProperty(Attachment, "previewablePattern", /^image(\/(gif|png|webp|jpe?g)|$)/);
  6717. class AttachmentPiece extends Piece {
  6718. static fromJSON(pieceJSON) {
  6719. return new this(Attachment.fromJSON(pieceJSON.attachment), pieceJSON.attributes);
  6720. }
  6721. constructor(attachment) {
  6722. super(...arguments);
  6723. this.attachment = attachment;
  6724. this.length = 1;
  6725. this.ensureAttachmentExclusivelyHasAttribute("href");
  6726. if (!this.attachment.hasContent()) {
  6727. this.removeProhibitedAttributes();
  6728. }
  6729. }
  6730. ensureAttachmentExclusivelyHasAttribute(attribute) {
  6731. if (this.hasAttribute(attribute)) {
  6732. if (!this.attachment.hasAttribute(attribute)) {
  6733. this.attachment.setAttributes(this.attributes.slice([attribute]));
  6734. }
  6735. this.attributes = this.attributes.remove(attribute);
  6736. }
  6737. }
  6738. removeProhibitedAttributes() {
  6739. const attributes = this.attributes.slice(AttachmentPiece.permittedAttributes);
  6740. if (!attributes.isEqualTo(this.attributes)) {
  6741. this.attributes = attributes;
  6742. }
  6743. }
  6744. getValue() {
  6745. return this.attachment;
  6746. }
  6747. isSerializable() {
  6748. return !this.attachment.isPending();
  6749. }
  6750. getCaption() {
  6751. return this.attributes.get("caption") || "";
  6752. }
  6753. isEqualTo(piece) {
  6754. var _piece$attachment;
  6755. 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);
  6756. }
  6757. toString() {
  6758. return OBJECT_REPLACEMENT_CHARACTER;
  6759. }
  6760. toJSON() {
  6761. const json = super.toJSON(...arguments);
  6762. json.attachment = this.attachment;
  6763. return json;
  6764. }
  6765. getCacheKey() {
  6766. return [super.getCacheKey(...arguments), this.attachment.getCacheKey()].join("/");
  6767. }
  6768. toConsole() {
  6769. return JSON.stringify(this.toString());
  6770. }
  6771. }
  6772. _defineProperty(AttachmentPiece, "permittedAttributes", ["caption", "presentation"]);
  6773. Piece.registerType("attachment", AttachmentPiece);
  6774. class StringPiece extends Piece {
  6775. static fromJSON(pieceJSON) {
  6776. return new this(pieceJSON.string, pieceJSON.attributes);
  6777. }
  6778. constructor(string) {
  6779. super(...arguments);
  6780. this.string = normalizeNewlines(string);
  6781. this.length = this.string.length;
  6782. }
  6783. getValue() {
  6784. return this.string;
  6785. }
  6786. toString() {
  6787. return this.string.toString();
  6788. }
  6789. isBlockBreak() {
  6790. return this.toString() === "\n" && this.getAttribute("blockBreak") === true;
  6791. }
  6792. toJSON() {
  6793. const result = super.toJSON(...arguments);
  6794. result.string = this.string;
  6795. return result;
  6796. }
  6797. // Splittable
  6798. canBeConsolidatedWith(piece) {
  6799. return piece && this.hasSameConstructorAs(piece) && this.hasSameAttributesAsPiece(piece);
  6800. }
  6801. consolidateWith(piece) {
  6802. return new this.constructor(this.toString() + piece.toString(), this.attributes);
  6803. }
  6804. splitAtOffset(offset) {
  6805. let left, right;
  6806. if (offset === 0) {
  6807. left = null;
  6808. right = this;
  6809. } else if (offset === this.length) {
  6810. left = this;
  6811. right = null;
  6812. } else {
  6813. left = new this.constructor(this.string.slice(0, offset), this.attributes);
  6814. right = new this.constructor(this.string.slice(offset), this.attributes);
  6815. }
  6816. return [left, right];
  6817. }
  6818. toConsole() {
  6819. let {
  6820. string
  6821. } = this;
  6822. if (string.length > 15) {
  6823. string = string.slice(0, 14) + "…";
  6824. }
  6825. return JSON.stringify(string.toString());
  6826. }
  6827. }
  6828. Piece.registerType("string", StringPiece);
  6829. /* eslint-disable
  6830. prefer-const,
  6831. */
  6832. class SplittableList extends TrixObject {
  6833. static box(objects) {
  6834. if (objects instanceof this) {
  6835. return objects;
  6836. } else {
  6837. return new this(objects);
  6838. }
  6839. }
  6840. constructor() {
  6841. let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  6842. super(...arguments);
  6843. this.objects = objects.slice(0);
  6844. this.length = this.objects.length;
  6845. }
  6846. indexOf(object) {
  6847. return this.objects.indexOf(object);
  6848. }
  6849. splice() {
  6850. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  6851. args[_key] = arguments[_key];
  6852. }
  6853. return new this.constructor(spliceArray(this.objects, ...args));
  6854. }
  6855. eachObject(callback) {
  6856. return this.objects.map((object, index) => callback(object, index));
  6857. }
  6858. insertObjectAtIndex(object, index) {
  6859. return this.splice(index, 0, object);
  6860. }
  6861. insertSplittableListAtIndex(splittableList, index) {
  6862. return this.splice(index, 0, ...splittableList.objects);
  6863. }
  6864. insertSplittableListAtPosition(splittableList, position) {
  6865. const [objects, index] = this.splitObjectAtPosition(position);
  6866. return new this.constructor(objects).insertSplittableListAtIndex(splittableList, index);
  6867. }
  6868. editObjectAtIndex(index, callback) {
  6869. return this.replaceObjectAtIndex(callback(this.objects[index]), index);
  6870. }
  6871. replaceObjectAtIndex(object, index) {
  6872. return this.splice(index, 1, object);
  6873. }
  6874. removeObjectAtIndex(index) {
  6875. return this.splice(index, 1);
  6876. }
  6877. getObjectAtIndex(index) {
  6878. return this.objects[index];
  6879. }
  6880. getSplittableListInRange(range) {
  6881. const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range);
  6882. return new this.constructor(objects.slice(leftIndex, rightIndex + 1));
  6883. }
  6884. selectSplittableList(test) {
  6885. const objects = this.objects.filter(object => test(object));
  6886. return new this.constructor(objects);
  6887. }
  6888. removeObjectsInRange(range) {
  6889. const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range);
  6890. return new this.constructor(objects).splice(leftIndex, rightIndex - leftIndex + 1);
  6891. }
  6892. transformObjectsInRange(range, transform) {
  6893. const [objects, leftIndex, rightIndex] = this.splitObjectsAtRange(range);
  6894. const transformedObjects = objects.map((object, index) => leftIndex <= index && index <= rightIndex ? transform(object) : object);
  6895. return new this.constructor(transformedObjects);
  6896. }
  6897. splitObjectsAtRange(range) {
  6898. let rightOuterIndex;
  6899. let [objects, leftInnerIndex, offset] = this.splitObjectAtPosition(startOfRange(range));
  6900. [objects, rightOuterIndex] = new this.constructor(objects).splitObjectAtPosition(endOfRange(range) + offset);
  6901. return [objects, leftInnerIndex, rightOuterIndex - 1];
  6902. }
  6903. getObjectAtPosition(position) {
  6904. const {
  6905. index
  6906. } = this.findIndexAndOffsetAtPosition(position);
  6907. return this.objects[index];
  6908. }
  6909. splitObjectAtPosition(position) {
  6910. let splitIndex, splitOffset;
  6911. const {
  6912. index,
  6913. offset
  6914. } = this.findIndexAndOffsetAtPosition(position);
  6915. const objects = this.objects.slice(0);
  6916. if (index != null) {
  6917. if (offset === 0) {
  6918. splitIndex = index;
  6919. splitOffset = 0;
  6920. } else {
  6921. const object = this.getObjectAtIndex(index);
  6922. const [leftObject, rightObject] = object.splitAtOffset(offset);
  6923. objects.splice(index, 1, leftObject, rightObject);
  6924. splitIndex = index + 1;
  6925. splitOffset = leftObject.getLength() - offset;
  6926. }
  6927. } else {
  6928. splitIndex = objects.length;
  6929. splitOffset = 0;
  6930. }
  6931. return [objects, splitIndex, splitOffset];
  6932. }
  6933. consolidate() {
  6934. const objects = [];
  6935. let pendingObject = this.objects[0];
  6936. this.objects.slice(1).forEach(object => {
  6937. var _pendingObject$canBeC, _pendingObject;
  6938. if ((_pendingObject$canBeC = (_pendingObject = pendingObject).canBeConsolidatedWith) !== null && _pendingObject$canBeC !== void 0 && _pendingObject$canBeC.call(_pendingObject, object)) {
  6939. pendingObject = pendingObject.consolidateWith(object);
  6940. } else {
  6941. objects.push(pendingObject);
  6942. pendingObject = object;
  6943. }
  6944. });
  6945. if (pendingObject) {
  6946. objects.push(pendingObject);
  6947. }
  6948. return new this.constructor(objects);
  6949. }
  6950. consolidateFromIndexToIndex(startIndex, endIndex) {
  6951. const objects = this.objects.slice(0);
  6952. const objectsInRange = objects.slice(startIndex, endIndex + 1);
  6953. const consolidatedInRange = new this.constructor(objectsInRange).consolidate().toArray();
  6954. return this.splice(startIndex, objectsInRange.length, ...consolidatedInRange);
  6955. }
  6956. findIndexAndOffsetAtPosition(position) {
  6957. let index;
  6958. let currentPosition = 0;
  6959. for (index = 0; index < this.objects.length; index++) {
  6960. const object = this.objects[index];
  6961. const nextPosition = currentPosition + object.getLength();
  6962. if (currentPosition <= position && position < nextPosition) {
  6963. return {
  6964. index,
  6965. offset: position - currentPosition
  6966. };
  6967. }
  6968. currentPosition = nextPosition;
  6969. }
  6970. return {
  6971. index: null,
  6972. offset: null
  6973. };
  6974. }
  6975. findPositionAtIndexAndOffset(index, offset) {
  6976. let position = 0;
  6977. for (let currentIndex = 0; currentIndex < this.objects.length; currentIndex++) {
  6978. const object = this.objects[currentIndex];
  6979. if (currentIndex < index) {
  6980. position += object.getLength();
  6981. } else if (currentIndex === index) {
  6982. position += offset;
  6983. break;
  6984. }
  6985. }
  6986. return position;
  6987. }
  6988. getEndPosition() {
  6989. if (this.endPosition == null) {
  6990. this.endPosition = 0;
  6991. this.objects.forEach(object => this.endPosition += object.getLength());
  6992. }
  6993. return this.endPosition;
  6994. }
  6995. toString() {
  6996. return this.objects.join("");
  6997. }
  6998. toArray() {
  6999. return this.objects.slice(0);
  7000. }
  7001. toJSON() {
  7002. return this.toArray();
  7003. }
  7004. isEqualTo(splittableList) {
  7005. return super.isEqualTo(...arguments) || objectArraysAreEqual(this.objects, splittableList === null || splittableList === void 0 ? void 0 : splittableList.objects);
  7006. }
  7007. contentsForInspection() {
  7008. return {
  7009. objects: "[".concat(this.objects.map(object => object.inspect()).join(", "), "]")
  7010. };
  7011. }
  7012. }
  7013. const objectArraysAreEqual = function (left) {
  7014. let right = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  7015. if (left.length !== right.length) {
  7016. return false;
  7017. }
  7018. let result = true;
  7019. for (let index = 0; index < left.length; index++) {
  7020. const object = left[index];
  7021. if (result && !object.isEqualTo(right[index])) {
  7022. result = false;
  7023. }
  7024. }
  7025. return result;
  7026. };
  7027. const startOfRange = range => range[0];
  7028. const endOfRange = range => range[1];
  7029. class Text extends TrixObject {
  7030. static textForAttachmentWithAttributes(attachment, attributes) {
  7031. const piece = new AttachmentPiece(attachment, attributes);
  7032. return new this([piece]);
  7033. }
  7034. static textForStringWithAttributes(string, attributes) {
  7035. const piece = new StringPiece(string, attributes);
  7036. return new this([piece]);
  7037. }
  7038. static fromJSON(textJSON) {
  7039. const pieces = Array.from(textJSON).map(pieceJSON => Piece.fromJSON(pieceJSON));
  7040. return new this(pieces);
  7041. }
  7042. constructor() {
  7043. let pieces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  7044. super(...arguments);
  7045. const notEmpty = pieces.filter(piece => !piece.isEmpty());
  7046. this.pieceList = new SplittableList(notEmpty);
  7047. }
  7048. copy() {
  7049. return this.copyWithPieceList(this.pieceList);
  7050. }
  7051. copyWithPieceList(pieceList) {
  7052. return new this.constructor(pieceList.consolidate().toArray());
  7053. }
  7054. copyUsingObjectMap(objectMap) {
  7055. const pieces = this.getPieces().map(piece => objectMap.find(piece) || piece);
  7056. return new this.constructor(pieces);
  7057. }
  7058. appendText(text) {
  7059. return this.insertTextAtPosition(text, this.getLength());
  7060. }
  7061. insertTextAtPosition(text, position) {
  7062. return this.copyWithPieceList(this.pieceList.insertSplittableListAtPosition(text.pieceList, position));
  7063. }
  7064. removeTextAtRange(range) {
  7065. return this.copyWithPieceList(this.pieceList.removeObjectsInRange(range));
  7066. }
  7067. replaceTextAtRange(text, range) {
  7068. return this.removeTextAtRange(range).insertTextAtPosition(text, range[0]);
  7069. }
  7070. moveTextFromRangeToPosition(range, position) {
  7071. if (range[0] <= position && position <= range[1]) return;
  7072. const text = this.getTextAtRange(range);
  7073. const length = text.getLength();
  7074. if (range[0] < position) {
  7075. position -= length;
  7076. }
  7077. return this.removeTextAtRange(range).insertTextAtPosition(text, position);
  7078. }
  7079. addAttributeAtRange(attribute, value, range) {
  7080. const attributes = {};
  7081. attributes[attribute] = value;
  7082. return this.addAttributesAtRange(attributes, range);
  7083. }
  7084. addAttributesAtRange(attributes, range) {
  7085. return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithAdditionalAttributes(attributes)));
  7086. }
  7087. removeAttributeAtRange(attribute, range) {
  7088. return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithoutAttribute(attribute)));
  7089. }
  7090. setAttributesAtRange(attributes, range) {
  7091. return this.copyWithPieceList(this.pieceList.transformObjectsInRange(range, piece => piece.copyWithAttributes(attributes)));
  7092. }
  7093. getAttributesAtPosition(position) {
  7094. var _this$pieceList$getOb;
  7095. return ((_this$pieceList$getOb = this.pieceList.getObjectAtPosition(position)) === null || _this$pieceList$getOb === void 0 ? void 0 : _this$pieceList$getOb.getAttributes()) || {};
  7096. }
  7097. getCommonAttributes() {
  7098. const objects = Array.from(this.pieceList.toArray()).map(piece => piece.getAttributes());
  7099. return Hash.fromCommonAttributesOfObjects(objects).toObject();
  7100. }
  7101. getCommonAttributesAtRange(range) {
  7102. return this.getTextAtRange(range).getCommonAttributes() || {};
  7103. }
  7104. getExpandedRangeForAttributeAtOffset(attributeName, offset) {
  7105. let right;
  7106. let left = right = offset;
  7107. const length = this.getLength();
  7108. while (left > 0 && this.getCommonAttributesAtRange([left - 1, right])[attributeName]) {
  7109. left--;
  7110. }
  7111. while (right < length && this.getCommonAttributesAtRange([offset, right + 1])[attributeName]) {
  7112. right++;
  7113. }
  7114. return [left, right];
  7115. }
  7116. getTextAtRange(range) {
  7117. return this.copyWithPieceList(this.pieceList.getSplittableListInRange(range));
  7118. }
  7119. getStringAtRange(range) {
  7120. return this.pieceList.getSplittableListInRange(range).toString();
  7121. }
  7122. getStringAtPosition(position) {
  7123. return this.getStringAtRange([position, position + 1]);
  7124. }
  7125. startsWithString(string) {
  7126. return this.getStringAtRange([0, string.length]) === string;
  7127. }
  7128. endsWithString(string) {
  7129. const length = this.getLength();
  7130. return this.getStringAtRange([length - string.length, length]) === string;
  7131. }
  7132. getAttachmentPieces() {
  7133. return this.pieceList.toArray().filter(piece => !!piece.attachment);
  7134. }
  7135. getAttachments() {
  7136. return this.getAttachmentPieces().map(piece => piece.attachment);
  7137. }
  7138. getAttachmentAndPositionById(attachmentId) {
  7139. let position = 0;
  7140. for (const piece of this.pieceList.toArray()) {
  7141. var _piece$attachment;
  7142. if (((_piece$attachment = piece.attachment) === null || _piece$attachment === void 0 ? void 0 : _piece$attachment.id) === attachmentId) {
  7143. return {
  7144. attachment: piece.attachment,
  7145. position
  7146. };
  7147. }
  7148. position += piece.length;
  7149. }
  7150. return {
  7151. attachment: null,
  7152. position: null
  7153. };
  7154. }
  7155. getAttachmentById(attachmentId) {
  7156. const {
  7157. attachment
  7158. } = this.getAttachmentAndPositionById(attachmentId);
  7159. return attachment;
  7160. }
  7161. getRangeOfAttachment(attachment) {
  7162. const attachmentAndPosition = this.getAttachmentAndPositionById(attachment.id);
  7163. const position = attachmentAndPosition.position;
  7164. attachment = attachmentAndPosition.attachment;
  7165. if (attachment) {
  7166. return [position, position + 1];
  7167. }
  7168. }
  7169. updateAttributesForAttachment(attributes, attachment) {
  7170. const range = this.getRangeOfAttachment(attachment);
  7171. if (range) {
  7172. return this.addAttributesAtRange(attributes, range);
  7173. } else {
  7174. return this;
  7175. }
  7176. }
  7177. getLength() {
  7178. return this.pieceList.getEndPosition();
  7179. }
  7180. isEmpty() {
  7181. return this.getLength() === 0;
  7182. }
  7183. isEqualTo(text) {
  7184. var _text$pieceList;
  7185. 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));
  7186. }
  7187. isBlockBreak() {
  7188. return this.getLength() === 1 && this.pieceList.getObjectAtIndex(0).isBlockBreak();
  7189. }
  7190. eachPiece(callback) {
  7191. return this.pieceList.eachObject(callback);
  7192. }
  7193. getPieces() {
  7194. return this.pieceList.toArray();
  7195. }
  7196. getPieceAtPosition(position) {
  7197. return this.pieceList.getObjectAtPosition(position);
  7198. }
  7199. contentsForInspection() {
  7200. return {
  7201. pieceList: this.pieceList.inspect()
  7202. };
  7203. }
  7204. toSerializableText() {
  7205. const pieceList = this.pieceList.selectSplittableList(piece => piece.isSerializable());
  7206. return this.copyWithPieceList(pieceList);
  7207. }
  7208. toString() {
  7209. return this.pieceList.toString();
  7210. }
  7211. toJSON() {
  7212. return this.pieceList.toJSON();
  7213. }
  7214. toConsole() {
  7215. return JSON.stringify(this.pieceList.toArray().map(piece => JSON.parse(piece.toConsole())));
  7216. }
  7217. // BIDI
  7218. getDirection() {
  7219. return getDirection(this.toString());
  7220. }
  7221. isRTL() {
  7222. return this.getDirection() === "rtl";
  7223. }
  7224. }
  7225. class Block extends TrixObject {
  7226. static fromJSON(blockJSON) {
  7227. const text = Text.fromJSON(blockJSON.text);
  7228. return new this(text, blockJSON.attributes, blockJSON.htmlAttributes);
  7229. }
  7230. constructor(text, attributes, htmlAttributes) {
  7231. super(...arguments);
  7232. this.text = applyBlockBreakToText(text || new Text());
  7233. this.attributes = attributes || [];
  7234. this.htmlAttributes = htmlAttributes || {};
  7235. }
  7236. isEmpty() {
  7237. return this.text.isBlockBreak();
  7238. }
  7239. isEqualTo(block) {
  7240. if (super.isEqualTo(block)) return true;
  7241. 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);
  7242. }
  7243. copyWithText(text) {
  7244. return new Block(text, this.attributes, this.htmlAttributes);
  7245. }
  7246. copyWithoutText() {
  7247. return this.copyWithText(null);
  7248. }
  7249. copyWithAttributes(attributes) {
  7250. return new Block(this.text, attributes, this.htmlAttributes);
  7251. }
  7252. copyWithoutAttributes() {
  7253. return this.copyWithAttributes(null);
  7254. }
  7255. copyUsingObjectMap(objectMap) {
  7256. const mappedText = objectMap.find(this.text);
  7257. if (mappedText) {
  7258. return this.copyWithText(mappedText);
  7259. } else {
  7260. return this.copyWithText(this.text.copyUsingObjectMap(objectMap));
  7261. }
  7262. }
  7263. addAttribute(attribute) {
  7264. const attributes = this.attributes.concat(expandAttribute(attribute));
  7265. return this.copyWithAttributes(attributes);
  7266. }
  7267. addHTMLAttribute(attribute, value) {
  7268. const htmlAttributes = Object.assign({}, this.htmlAttributes, {
  7269. [attribute]: value
  7270. });
  7271. return new Block(this.text, this.attributes, htmlAttributes);
  7272. }
  7273. removeAttribute(attribute) {
  7274. const {
  7275. listAttribute
  7276. } = getBlockConfig(attribute);
  7277. const attributes = removeLastValue(removeLastValue(this.attributes, attribute), listAttribute);
  7278. return this.copyWithAttributes(attributes);
  7279. }
  7280. removeLastAttribute() {
  7281. return this.removeAttribute(this.getLastAttribute());
  7282. }
  7283. getLastAttribute() {
  7284. return getLastElement(this.attributes);
  7285. }
  7286. getAttributes() {
  7287. return this.attributes.slice(0);
  7288. }
  7289. getAttributeLevel() {
  7290. return this.attributes.length;
  7291. }
  7292. getAttributeAtLevel(level) {
  7293. return this.attributes[level - 1];
  7294. }
  7295. hasAttribute(attributeName) {
  7296. return this.attributes.includes(attributeName);
  7297. }
  7298. hasAttributes() {
  7299. return this.getAttributeLevel() > 0;
  7300. }
  7301. getLastNestableAttribute() {
  7302. return getLastElement(this.getNestableAttributes());
  7303. }
  7304. getNestableAttributes() {
  7305. return this.attributes.filter(attribute => getBlockConfig(attribute).nestable);
  7306. }
  7307. getNestingLevel() {
  7308. return this.getNestableAttributes().length;
  7309. }
  7310. decreaseNestingLevel() {
  7311. const attribute = this.getLastNestableAttribute();
  7312. if (attribute) {
  7313. return this.removeAttribute(attribute);
  7314. } else {
  7315. return this;
  7316. }
  7317. }
  7318. increaseNestingLevel() {
  7319. const attribute = this.getLastNestableAttribute();
  7320. if (attribute) {
  7321. const index = this.attributes.lastIndexOf(attribute);
  7322. const attributes = spliceArray(this.attributes, index + 1, 0, ...expandAttribute(attribute));
  7323. return this.copyWithAttributes(attributes);
  7324. } else {
  7325. return this;
  7326. }
  7327. }
  7328. getListItemAttributes() {
  7329. return this.attributes.filter(attribute => getBlockConfig(attribute).listAttribute);
  7330. }
  7331. isListItem() {
  7332. var _getBlockConfig;
  7333. return (_getBlockConfig = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.listAttribute;
  7334. }
  7335. isTerminalBlock() {
  7336. var _getBlockConfig2;
  7337. return (_getBlockConfig2 = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig2 === void 0 ? void 0 : _getBlockConfig2.terminal;
  7338. }
  7339. breaksOnReturn() {
  7340. var _getBlockConfig3;
  7341. return (_getBlockConfig3 = getBlockConfig(this.getLastAttribute())) === null || _getBlockConfig3 === void 0 ? void 0 : _getBlockConfig3.breakOnReturn;
  7342. }
  7343. findLineBreakInDirectionFromPosition(direction, position) {
  7344. const string = this.toString();
  7345. let result;
  7346. switch (direction) {
  7347. case "forward":
  7348. result = string.indexOf("\n", position);
  7349. break;
  7350. case "backward":
  7351. result = string.slice(0, position).lastIndexOf("\n");
  7352. }
  7353. if (result !== -1) {
  7354. return result;
  7355. }
  7356. }
  7357. contentsForInspection() {
  7358. return {
  7359. text: this.text.inspect(),
  7360. attributes: this.attributes
  7361. };
  7362. }
  7363. toString() {
  7364. return this.text.toString();
  7365. }
  7366. toJSON() {
  7367. return {
  7368. text: this.text,
  7369. attributes: this.attributes,
  7370. htmlAttributes: this.htmlAttributes
  7371. };
  7372. }
  7373. // BIDI
  7374. getDirection() {
  7375. return this.text.getDirection();
  7376. }
  7377. isRTL() {
  7378. return this.text.isRTL();
  7379. }
  7380. // Splittable
  7381. getLength() {
  7382. return this.text.getLength();
  7383. }
  7384. canBeConsolidatedWith(block) {
  7385. return !this.hasAttributes() && !block.hasAttributes() && this.getDirection() === block.getDirection();
  7386. }
  7387. consolidateWith(block) {
  7388. const newlineText = Text.textForStringWithAttributes("\n");
  7389. const text = this.getTextWithoutBlockBreak().appendText(newlineText);
  7390. return this.copyWithText(text.appendText(block.text));
  7391. }
  7392. splitAtOffset(offset) {
  7393. let left, right;
  7394. if (offset === 0) {
  7395. left = null;
  7396. right = this;
  7397. } else if (offset === this.getLength()) {
  7398. left = this;
  7399. right = null;
  7400. } else {
  7401. left = this.copyWithText(this.text.getTextAtRange([0, offset]));
  7402. right = this.copyWithText(this.text.getTextAtRange([offset, this.getLength()]));
  7403. }
  7404. return [left, right];
  7405. }
  7406. getBlockBreakPosition() {
  7407. return this.text.getLength() - 1;
  7408. }
  7409. getTextWithoutBlockBreak() {
  7410. if (textEndsInBlockBreak(this.text)) {
  7411. return this.text.getTextAtRange([0, this.getBlockBreakPosition()]);
  7412. } else {
  7413. return this.text.copy();
  7414. }
  7415. }
  7416. // Grouping
  7417. canBeGrouped(depth) {
  7418. return this.attributes[depth];
  7419. }
  7420. canBeGroupedWith(otherBlock, depth) {
  7421. const otherAttributes = otherBlock.getAttributes();
  7422. const otherAttribute = otherAttributes[depth];
  7423. const attribute = this.attributes[depth];
  7424. return attribute === otherAttribute && !(getBlockConfig(attribute).group === false && !getListAttributeNames().includes(otherAttributes[depth + 1])) && (this.getDirection() === otherBlock.getDirection() || otherBlock.isEmpty());
  7425. }
  7426. }
  7427. // Block breaks
  7428. const applyBlockBreakToText = function (text) {
  7429. text = unmarkExistingInnerBlockBreaksInText(text);
  7430. text = addBlockBreakToText(text);
  7431. return text;
  7432. };
  7433. const unmarkExistingInnerBlockBreaksInText = function (text) {
  7434. let modified = false;
  7435. const pieces = text.getPieces();
  7436. let innerPieces = pieces.slice(0, pieces.length - 1);
  7437. const lastPiece = pieces[pieces.length - 1];
  7438. if (!lastPiece) return text;
  7439. innerPieces = innerPieces.map(piece => {
  7440. if (piece.isBlockBreak()) {
  7441. modified = true;
  7442. return unmarkBlockBreakPiece(piece);
  7443. } else {
  7444. return piece;
  7445. }
  7446. });
  7447. if (modified) {
  7448. return new Text([...innerPieces, lastPiece]);
  7449. } else {
  7450. return text;
  7451. }
  7452. };
  7453. const blockBreakText = Text.textForStringWithAttributes("\n", {
  7454. blockBreak: true
  7455. });
  7456. const addBlockBreakToText = function (text) {
  7457. if (textEndsInBlockBreak(text)) {
  7458. return text;
  7459. } else {
  7460. return text.appendText(blockBreakText);
  7461. }
  7462. };
  7463. const textEndsInBlockBreak = function (text) {
  7464. const length = text.getLength();
  7465. if (length === 0) {
  7466. return false;
  7467. }
  7468. const endText = text.getTextAtRange([length - 1, length]);
  7469. return endText.isBlockBreak();
  7470. };
  7471. const unmarkBlockBreakPiece = piece => piece.copyWithoutAttribute("blockBreak");
  7472. // Attributes
  7473. const expandAttribute = function (attribute) {
  7474. const {
  7475. listAttribute
  7476. } = getBlockConfig(attribute);
  7477. if (listAttribute) {
  7478. return [listAttribute, attribute];
  7479. } else {
  7480. return [attribute];
  7481. }
  7482. };
  7483. // Array helpers
  7484. const getLastElement = array => array.slice(-1)[0];
  7485. const removeLastValue = function (array, value) {
  7486. const index = array.lastIndexOf(value);
  7487. if (index === -1) {
  7488. return array;
  7489. } else {
  7490. return spliceArray(array, index, 1);
  7491. }
  7492. };
  7493. class Document extends TrixObject {
  7494. static fromJSON(documentJSON) {
  7495. const blocks = Array.from(documentJSON).map(blockJSON => Block.fromJSON(blockJSON));
  7496. return new this(blocks);
  7497. }
  7498. static fromString(string, textAttributes) {
  7499. const text = Text.textForStringWithAttributes(string, textAttributes);
  7500. return new this([new Block(text)]);
  7501. }
  7502. constructor() {
  7503. let blocks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  7504. super(...arguments);
  7505. if (blocks.length === 0) {
  7506. blocks = [new Block()];
  7507. }
  7508. this.blockList = SplittableList.box(blocks);
  7509. }
  7510. isEmpty() {
  7511. const block = this.getBlockAtIndex(0);
  7512. return this.blockList.length === 1 && block.isEmpty() && !block.hasAttributes();
  7513. }
  7514. copy() {
  7515. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  7516. const blocks = options.consolidateBlocks ? this.blockList.consolidate().toArray() : this.blockList.toArray();
  7517. return new this.constructor(blocks);
  7518. }
  7519. copyUsingObjectsFromDocument(sourceDocument) {
  7520. const objectMap = new ObjectMap(sourceDocument.getObjects());
  7521. return this.copyUsingObjectMap(objectMap);
  7522. }
  7523. copyUsingObjectMap(objectMap) {
  7524. const blocks = this.getBlocks().map(block => {
  7525. const mappedBlock = objectMap.find(block);
  7526. return mappedBlock || block.copyUsingObjectMap(objectMap);
  7527. });
  7528. return new this.constructor(blocks);
  7529. }
  7530. copyWithBaseBlockAttributes() {
  7531. let blockAttributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  7532. const blocks = this.getBlocks().map(block => {
  7533. const attributes = blockAttributes.concat(block.getAttributes());
  7534. return block.copyWithAttributes(attributes);
  7535. });
  7536. return new this.constructor(blocks);
  7537. }
  7538. replaceBlock(oldBlock, newBlock) {
  7539. const index = this.blockList.indexOf(oldBlock);
  7540. if (index === -1) {
  7541. return this;
  7542. }
  7543. return new this.constructor(this.blockList.replaceObjectAtIndex(newBlock, index));
  7544. }
  7545. insertDocumentAtRange(document, range) {
  7546. const {
  7547. blockList
  7548. } = document;
  7549. range = normalizeRange(range);
  7550. let [position] = range;
  7551. const {
  7552. index,
  7553. offset
  7554. } = this.locationFromPosition(position);
  7555. let result = this;
  7556. const block = this.getBlockAtPosition(position);
  7557. if (rangeIsCollapsed(range) && block.isEmpty() && !block.hasAttributes()) {
  7558. result = new this.constructor(result.blockList.removeObjectAtIndex(index));
  7559. } else if (block.getBlockBreakPosition() === offset) {
  7560. position++;
  7561. }
  7562. result = result.removeTextAtRange(range);
  7563. return new this.constructor(result.blockList.insertSplittableListAtPosition(blockList, position));
  7564. }
  7565. mergeDocumentAtRange(document, range) {
  7566. let formattedDocument, result;
  7567. range = normalizeRange(range);
  7568. const [startPosition] = range;
  7569. const startLocation = this.locationFromPosition(startPosition);
  7570. const blockAttributes = this.getBlockAtIndex(startLocation.index).getAttributes();
  7571. const baseBlockAttributes = document.getBaseBlockAttributes();
  7572. const trailingBlockAttributes = blockAttributes.slice(-baseBlockAttributes.length);
  7573. if (arraysAreEqual(baseBlockAttributes, trailingBlockAttributes)) {
  7574. const leadingBlockAttributes = blockAttributes.slice(0, -baseBlockAttributes.length);
  7575. formattedDocument = document.copyWithBaseBlockAttributes(leadingBlockAttributes);
  7576. } else {
  7577. formattedDocument = document.copy({
  7578. consolidateBlocks: true
  7579. }).copyWithBaseBlockAttributes(blockAttributes);
  7580. }
  7581. const blockCount = formattedDocument.getBlockCount();
  7582. const firstBlock = formattedDocument.getBlockAtIndex(0);
  7583. if (arraysAreEqual(blockAttributes, firstBlock.getAttributes())) {
  7584. const firstText = firstBlock.getTextWithoutBlockBreak();
  7585. result = this.insertTextAtRange(firstText, range);
  7586. if (blockCount > 1) {
  7587. formattedDocument = new this.constructor(formattedDocument.getBlocks().slice(1));
  7588. const position = startPosition + firstText.getLength();
  7589. result = result.insertDocumentAtRange(formattedDocument, position);
  7590. }
  7591. } else {
  7592. result = this.insertDocumentAtRange(formattedDocument, range);
  7593. }
  7594. return result;
  7595. }
  7596. insertTextAtRange(text, range) {
  7597. range = normalizeRange(range);
  7598. const [startPosition] = range;
  7599. const {
  7600. index,
  7601. offset
  7602. } = this.locationFromPosition(startPosition);
  7603. const document = this.removeTextAtRange(range);
  7604. return new this.constructor(document.blockList.editObjectAtIndex(index, block => block.copyWithText(block.text.insertTextAtPosition(text, offset))));
  7605. }
  7606. removeTextAtRange(range) {
  7607. let blocks;
  7608. range = normalizeRange(range);
  7609. const [leftPosition, rightPosition] = range;
  7610. if (rangeIsCollapsed(range)) {
  7611. return this;
  7612. }
  7613. const [leftLocation, rightLocation] = Array.from(this.locationRangeFromRange(range));
  7614. const leftIndex = leftLocation.index;
  7615. const leftOffset = leftLocation.offset;
  7616. const leftBlock = this.getBlockAtIndex(leftIndex);
  7617. const rightIndex = rightLocation.index;
  7618. const rightOffset = rightLocation.offset;
  7619. const rightBlock = this.getBlockAtIndex(rightIndex);
  7620. const removeRightNewline = rightPosition - leftPosition === 1 && leftBlock.getBlockBreakPosition() === leftOffset && rightBlock.getBlockBreakPosition() !== rightOffset && rightBlock.text.getStringAtPosition(rightOffset) === "\n";
  7621. if (removeRightNewline) {
  7622. blocks = this.blockList.editObjectAtIndex(rightIndex, block => block.copyWithText(block.text.removeTextAtRange([rightOffset, rightOffset + 1])));
  7623. } else {
  7624. let block;
  7625. const leftText = leftBlock.text.getTextAtRange([0, leftOffset]);
  7626. const rightText = rightBlock.text.getTextAtRange([rightOffset, rightBlock.getLength()]);
  7627. const text = leftText.appendText(rightText);
  7628. const removingLeftBlock = leftIndex !== rightIndex && leftOffset === 0;
  7629. const useRightBlock = removingLeftBlock && leftBlock.getAttributeLevel() >= rightBlock.getAttributeLevel();
  7630. if (useRightBlock) {
  7631. block = rightBlock.copyWithText(text);
  7632. } else {
  7633. block = leftBlock.copyWithText(text);
  7634. }
  7635. const affectedBlockCount = rightIndex + 1 - leftIndex;
  7636. blocks = this.blockList.splice(leftIndex, affectedBlockCount, block);
  7637. }
  7638. return new this.constructor(blocks);
  7639. }
  7640. moveTextFromRangeToPosition(range, position) {
  7641. let text;
  7642. range = normalizeRange(range);
  7643. const [startPosition, endPosition] = range;
  7644. if (startPosition <= position && position <= endPosition) {
  7645. return this;
  7646. }
  7647. let document = this.getDocumentAtRange(range);
  7648. let result = this.removeTextAtRange(range);
  7649. const movingRightward = startPosition < position;
  7650. if (movingRightward) {
  7651. position -= document.getLength();
  7652. }
  7653. const [firstBlock, ...blocks] = document.getBlocks();
  7654. if (blocks.length === 0) {
  7655. text = firstBlock.getTextWithoutBlockBreak();
  7656. if (movingRightward) {
  7657. position += 1;
  7658. }
  7659. } else {
  7660. text = firstBlock.text;
  7661. }
  7662. result = result.insertTextAtRange(text, position);
  7663. if (blocks.length === 0) {
  7664. return result;
  7665. }
  7666. document = new this.constructor(blocks);
  7667. position += text.getLength();
  7668. return result.insertDocumentAtRange(document, position);
  7669. }
  7670. addAttributeAtRange(attribute, value, range) {
  7671. let {
  7672. blockList
  7673. } = this;
  7674. this.eachBlockAtRange(range, (block, textRange, index) => blockList = blockList.editObjectAtIndex(index, function () {
  7675. if (getBlockConfig(attribute)) {
  7676. return block.addAttribute(attribute, value);
  7677. } else {
  7678. if (textRange[0] === textRange[1]) {
  7679. return block;
  7680. } else {
  7681. return block.copyWithText(block.text.addAttributeAtRange(attribute, value, textRange));
  7682. }
  7683. }
  7684. }));
  7685. return new this.constructor(blockList);
  7686. }
  7687. addAttribute(attribute, value) {
  7688. let {
  7689. blockList
  7690. } = this;
  7691. this.eachBlock((block, index) => blockList = blockList.editObjectAtIndex(index, () => block.addAttribute(attribute, value)));
  7692. return new this.constructor(blockList);
  7693. }
  7694. removeAttributeAtRange(attribute, range) {
  7695. let {
  7696. blockList
  7697. } = this;
  7698. this.eachBlockAtRange(range, function (block, textRange, index) {
  7699. if (getBlockConfig(attribute)) {
  7700. blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(attribute));
  7701. } else if (textRange[0] !== textRange[1]) {
  7702. blockList = blockList.editObjectAtIndex(index, () => block.copyWithText(block.text.removeAttributeAtRange(attribute, textRange)));
  7703. }
  7704. });
  7705. return new this.constructor(blockList);
  7706. }
  7707. updateAttributesForAttachment(attributes, attachment) {
  7708. const range = this.getRangeOfAttachment(attachment);
  7709. const [startPosition] = Array.from(range);
  7710. const {
  7711. index
  7712. } = this.locationFromPosition(startPosition);
  7713. const text = this.getTextAtIndex(index);
  7714. return new this.constructor(this.blockList.editObjectAtIndex(index, block => block.copyWithText(text.updateAttributesForAttachment(attributes, attachment))));
  7715. }
  7716. removeAttributeForAttachment(attribute, attachment) {
  7717. const range = this.getRangeOfAttachment(attachment);
  7718. return this.removeAttributeAtRange(attribute, range);
  7719. }
  7720. setHTMLAttributeAtPosition(position, name, value) {
  7721. const block = this.getBlockAtPosition(position);
  7722. const updatedBlock = block.addHTMLAttribute(name, value);
  7723. return this.replaceBlock(block, updatedBlock);
  7724. }
  7725. insertBlockBreakAtRange(range) {
  7726. let blocks;
  7727. range = normalizeRange(range);
  7728. const [startPosition] = range;
  7729. const {
  7730. offset
  7731. } = this.locationFromPosition(startPosition);
  7732. const document = this.removeTextAtRange(range);
  7733. if (offset === 0) {
  7734. blocks = [new Block()];
  7735. }
  7736. return new this.constructor(document.blockList.insertSplittableListAtPosition(new SplittableList(blocks), startPosition));
  7737. }
  7738. applyBlockAttributeAtRange(attributeName, value, range) {
  7739. const expanded = this.expandRangeToLineBreaksAndSplitBlocks(range);
  7740. let document = expanded.document;
  7741. range = expanded.range;
  7742. const blockConfig = getBlockConfig(attributeName);
  7743. if (blockConfig.listAttribute) {
  7744. document = document.removeLastListAttributeAtRange(range, {
  7745. exceptAttributeName: attributeName
  7746. });
  7747. const converted = document.convertLineBreaksToBlockBreaksInRange(range);
  7748. document = converted.document;
  7749. range = converted.range;
  7750. } else if (blockConfig.exclusive) {
  7751. document = document.removeBlockAttributesAtRange(range);
  7752. } else if (blockConfig.terminal) {
  7753. document = document.removeLastTerminalAttributeAtRange(range);
  7754. } else {
  7755. document = document.consolidateBlocksAtRange(range);
  7756. }
  7757. return document.addAttributeAtRange(attributeName, value, range);
  7758. }
  7759. removeLastListAttributeAtRange(range) {
  7760. let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  7761. let {
  7762. blockList
  7763. } = this;
  7764. this.eachBlockAtRange(range, function (block, textRange, index) {
  7765. const lastAttributeName = block.getLastAttribute();
  7766. if (!lastAttributeName) {
  7767. return;
  7768. }
  7769. if (!getBlockConfig(lastAttributeName).listAttribute) {
  7770. return;
  7771. }
  7772. if (lastAttributeName === options.exceptAttributeName) {
  7773. return;
  7774. }
  7775. blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(lastAttributeName));
  7776. });
  7777. return new this.constructor(blockList);
  7778. }
  7779. removeLastTerminalAttributeAtRange(range) {
  7780. let {
  7781. blockList
  7782. } = this;
  7783. this.eachBlockAtRange(range, function (block, textRange, index) {
  7784. const lastAttributeName = block.getLastAttribute();
  7785. if (!lastAttributeName) {
  7786. return;
  7787. }
  7788. if (!getBlockConfig(lastAttributeName).terminal) {
  7789. return;
  7790. }
  7791. blockList = blockList.editObjectAtIndex(index, () => block.removeAttribute(lastAttributeName));
  7792. });
  7793. return new this.constructor(blockList);
  7794. }
  7795. removeBlockAttributesAtRange(range) {
  7796. let {
  7797. blockList
  7798. } = this;
  7799. this.eachBlockAtRange(range, function (block, textRange, index) {
  7800. if (block.hasAttributes()) {
  7801. blockList = blockList.editObjectAtIndex(index, () => block.copyWithoutAttributes());
  7802. }
  7803. });
  7804. return new this.constructor(blockList);
  7805. }
  7806. expandRangeToLineBreaksAndSplitBlocks(range) {
  7807. let position;
  7808. range = normalizeRange(range);
  7809. let [startPosition, endPosition] = range;
  7810. const startLocation = this.locationFromPosition(startPosition);
  7811. const endLocation = this.locationFromPosition(endPosition);
  7812. let document = this;
  7813. const startBlock = document.getBlockAtIndex(startLocation.index);
  7814. startLocation.offset = startBlock.findLineBreakInDirectionFromPosition("backward", startLocation.offset);
  7815. if (startLocation.offset != null) {
  7816. position = document.positionFromLocation(startLocation);
  7817. document = document.insertBlockBreakAtRange([position, position + 1]);
  7818. endLocation.index += 1;
  7819. endLocation.offset -= document.getBlockAtIndex(startLocation.index).getLength();
  7820. startLocation.index += 1;
  7821. }
  7822. startLocation.offset = 0;
  7823. if (endLocation.offset === 0 && endLocation.index > startLocation.index) {
  7824. endLocation.index -= 1;
  7825. endLocation.offset = document.getBlockAtIndex(endLocation.index).getBlockBreakPosition();
  7826. } else {
  7827. const endBlock = document.getBlockAtIndex(endLocation.index);
  7828. if (endBlock.text.getStringAtRange([endLocation.offset - 1, endLocation.offset]) === "\n") {
  7829. endLocation.offset -= 1;
  7830. } else {
  7831. endLocation.offset = endBlock.findLineBreakInDirectionFromPosition("forward", endLocation.offset);
  7832. }
  7833. if (endLocation.offset !== endBlock.getBlockBreakPosition()) {
  7834. position = document.positionFromLocation(endLocation);
  7835. document = document.insertBlockBreakAtRange([position, position + 1]);
  7836. }
  7837. }
  7838. startPosition = document.positionFromLocation(startLocation);
  7839. endPosition = document.positionFromLocation(endLocation);
  7840. range = normalizeRange([startPosition, endPosition]);
  7841. return {
  7842. document,
  7843. range
  7844. };
  7845. }
  7846. convertLineBreaksToBlockBreaksInRange(range) {
  7847. range = normalizeRange(range);
  7848. let [position] = range;
  7849. const string = this.getStringAtRange(range).slice(0, -1);
  7850. let document = this;
  7851. string.replace(/.*?\n/g, function (match) {
  7852. position += match.length;
  7853. document = document.insertBlockBreakAtRange([position - 1, position]);
  7854. });
  7855. return {
  7856. document,
  7857. range
  7858. };
  7859. }
  7860. consolidateBlocksAtRange(range) {
  7861. range = normalizeRange(range);
  7862. const [startPosition, endPosition] = range;
  7863. const startIndex = this.locationFromPosition(startPosition).index;
  7864. const endIndex = this.locationFromPosition(endPosition).index;
  7865. return new this.constructor(this.blockList.consolidateFromIndexToIndex(startIndex, endIndex));
  7866. }
  7867. getDocumentAtRange(range) {
  7868. range = normalizeRange(range);
  7869. const blocks = this.blockList.getSplittableListInRange(range).toArray();
  7870. return new this.constructor(blocks);
  7871. }
  7872. getStringAtRange(range) {
  7873. let endIndex;
  7874. const array = range = normalizeRange(range),
  7875. endPosition = array[array.length - 1];
  7876. if (endPosition !== this.getLength()) {
  7877. endIndex = -1;
  7878. }
  7879. return this.getDocumentAtRange(range).toString().slice(0, endIndex);
  7880. }
  7881. getBlockAtIndex(index) {
  7882. return this.blockList.getObjectAtIndex(index);
  7883. }
  7884. getBlockAtPosition(position) {
  7885. const {
  7886. index
  7887. } = this.locationFromPosition(position);
  7888. return this.getBlockAtIndex(index);
  7889. }
  7890. getTextAtIndex(index) {
  7891. var _this$getBlockAtIndex;
  7892. return (_this$getBlockAtIndex = this.getBlockAtIndex(index)) === null || _this$getBlockAtIndex === void 0 ? void 0 : _this$getBlockAtIndex.text;
  7893. }
  7894. getTextAtPosition(position) {
  7895. const {
  7896. index
  7897. } = this.locationFromPosition(position);
  7898. return this.getTextAtIndex(index);
  7899. }
  7900. getPieceAtPosition(position) {
  7901. const {
  7902. index,
  7903. offset
  7904. } = this.locationFromPosition(position);
  7905. return this.getTextAtIndex(index).getPieceAtPosition(offset);
  7906. }
  7907. getCharacterAtPosition(position) {
  7908. const {
  7909. index,
  7910. offset
  7911. } = this.locationFromPosition(position);
  7912. return this.getTextAtIndex(index).getStringAtRange([offset, offset + 1]);
  7913. }
  7914. getLength() {
  7915. return this.blockList.getEndPosition();
  7916. }
  7917. getBlocks() {
  7918. return this.blockList.toArray();
  7919. }
  7920. getBlockCount() {
  7921. return this.blockList.length;
  7922. }
  7923. getEditCount() {
  7924. return this.editCount;
  7925. }
  7926. eachBlock(callback) {
  7927. return this.blockList.eachObject(callback);
  7928. }
  7929. eachBlockAtRange(range, callback) {
  7930. let block, textRange;
  7931. range = normalizeRange(range);
  7932. const [startPosition, endPosition] = range;
  7933. const startLocation = this.locationFromPosition(startPosition);
  7934. const endLocation = this.locationFromPosition(endPosition);
  7935. if (startLocation.index === endLocation.index) {
  7936. block = this.getBlockAtIndex(startLocation.index);
  7937. textRange = [startLocation.offset, endLocation.offset];
  7938. return callback(block, textRange, startLocation.index);
  7939. } else {
  7940. for (let index = startLocation.index; index <= endLocation.index; index++) {
  7941. block = this.getBlockAtIndex(index);
  7942. if (block) {
  7943. switch (index) {
  7944. case startLocation.index:
  7945. textRange = [startLocation.offset, block.text.getLength()];
  7946. break;
  7947. case endLocation.index:
  7948. textRange = [0, endLocation.offset];
  7949. break;
  7950. default:
  7951. textRange = [0, block.text.getLength()];
  7952. }
  7953. callback(block, textRange, index);
  7954. }
  7955. }
  7956. }
  7957. }
  7958. getCommonAttributesAtRange(range) {
  7959. range = normalizeRange(range);
  7960. const [startPosition] = range;
  7961. if (rangeIsCollapsed(range)) {
  7962. return this.getCommonAttributesAtPosition(startPosition);
  7963. } else {
  7964. const textAttributes = [];
  7965. const blockAttributes = [];
  7966. this.eachBlockAtRange(range, function (block, textRange) {
  7967. if (textRange[0] !== textRange[1]) {
  7968. textAttributes.push(block.text.getCommonAttributesAtRange(textRange));
  7969. return blockAttributes.push(attributesForBlock(block));
  7970. }
  7971. });
  7972. return Hash.fromCommonAttributesOfObjects(textAttributes).merge(Hash.fromCommonAttributesOfObjects(blockAttributes)).toObject();
  7973. }
  7974. }
  7975. getCommonAttributesAtPosition(position) {
  7976. let key, value;
  7977. const {
  7978. index,
  7979. offset
  7980. } = this.locationFromPosition(position);
  7981. const block = this.getBlockAtIndex(index);
  7982. if (!block) {
  7983. return {};
  7984. }
  7985. const commonAttributes = attributesForBlock(block);
  7986. const attributes = block.text.getAttributesAtPosition(offset);
  7987. const attributesLeft = block.text.getAttributesAtPosition(offset - 1);
  7988. const inheritableAttributes = Object.keys(text_attributes).filter(key => {
  7989. return text_attributes[key].inheritable;
  7990. });
  7991. for (key in attributesLeft) {
  7992. value = attributesLeft[key];
  7993. if (value === attributes[key] || inheritableAttributes.includes(key)) {
  7994. commonAttributes[key] = value;
  7995. }
  7996. }
  7997. return commonAttributes;
  7998. }
  7999. getRangeOfCommonAttributeAtPosition(attributeName, position) {
  8000. const {
  8001. index,
  8002. offset
  8003. } = this.locationFromPosition(position);
  8004. const text = this.getTextAtIndex(index);
  8005. const [startOffset, endOffset] = Array.from(text.getExpandedRangeForAttributeAtOffset(attributeName, offset));
  8006. const start = this.positionFromLocation({
  8007. index,
  8008. offset: startOffset
  8009. });
  8010. const end = this.positionFromLocation({
  8011. index,
  8012. offset: endOffset
  8013. });
  8014. return normalizeRange([start, end]);
  8015. }
  8016. getBaseBlockAttributes() {
  8017. let baseBlockAttributes = this.getBlockAtIndex(0).getAttributes();
  8018. for (let blockIndex = 1; blockIndex < this.getBlockCount(); blockIndex++) {
  8019. const blockAttributes = this.getBlockAtIndex(blockIndex).getAttributes();
  8020. const lastAttributeIndex = Math.min(baseBlockAttributes.length, blockAttributes.length);
  8021. baseBlockAttributes = (() => {
  8022. const result = [];
  8023. for (let index = 0; index < lastAttributeIndex; index++) {
  8024. if (blockAttributes[index] !== baseBlockAttributes[index]) {
  8025. break;
  8026. }
  8027. result.push(blockAttributes[index]);
  8028. }
  8029. return result;
  8030. })();
  8031. }
  8032. return baseBlockAttributes;
  8033. }
  8034. getAttachmentById(attachmentId) {
  8035. for (const attachment of this.getAttachments()) {
  8036. if (attachment.id === attachmentId) {
  8037. return attachment;
  8038. }
  8039. }
  8040. }
  8041. getAttachmentPieces() {
  8042. let attachmentPieces = [];
  8043. this.blockList.eachObject(_ref => {
  8044. let {
  8045. text
  8046. } = _ref;
  8047. return attachmentPieces = attachmentPieces.concat(text.getAttachmentPieces());
  8048. });
  8049. return attachmentPieces;
  8050. }
  8051. getAttachments() {
  8052. return this.getAttachmentPieces().map(piece => piece.attachment);
  8053. }
  8054. getRangeOfAttachment(attachment) {
  8055. let position = 0;
  8056. const iterable = this.blockList.toArray();
  8057. for (let index = 0; index < iterable.length; index++) {
  8058. const {
  8059. text
  8060. } = iterable[index];
  8061. const textRange = text.getRangeOfAttachment(attachment);
  8062. if (textRange) {
  8063. return normalizeRange([position + textRange[0], position + textRange[1]]);
  8064. }
  8065. position += text.getLength();
  8066. }
  8067. }
  8068. getLocationRangeOfAttachment(attachment) {
  8069. const range = this.getRangeOfAttachment(attachment);
  8070. return this.locationRangeFromRange(range);
  8071. }
  8072. getAttachmentPieceForAttachment(attachment) {
  8073. for (const piece of this.getAttachmentPieces()) {
  8074. if (piece.attachment === attachment) {
  8075. return piece;
  8076. }
  8077. }
  8078. }
  8079. findRangesForBlockAttribute(attributeName) {
  8080. let position = 0;
  8081. const ranges = [];
  8082. this.getBlocks().forEach(block => {
  8083. const length = block.getLength();
  8084. if (block.hasAttribute(attributeName)) {
  8085. ranges.push([position, position + length]);
  8086. }
  8087. position += length;
  8088. });
  8089. return ranges;
  8090. }
  8091. findRangesForTextAttribute(attributeName) {
  8092. let {
  8093. withValue
  8094. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  8095. let position = 0;
  8096. let range = [];
  8097. const ranges = [];
  8098. const match = function (piece) {
  8099. if (withValue) {
  8100. return piece.getAttribute(attributeName) === withValue;
  8101. } else {
  8102. return piece.hasAttribute(attributeName);
  8103. }
  8104. };
  8105. this.getPieces().forEach(piece => {
  8106. const length = piece.getLength();
  8107. if (match(piece)) {
  8108. if (range[1] === position) {
  8109. range[1] = position + length;
  8110. } else {
  8111. ranges.push(range = [position, position + length]);
  8112. }
  8113. }
  8114. position += length;
  8115. });
  8116. return ranges;
  8117. }
  8118. locationFromPosition(position) {
  8119. const location = this.blockList.findIndexAndOffsetAtPosition(Math.max(0, position));
  8120. if (location.index != null) {
  8121. return location;
  8122. } else {
  8123. const blocks = this.getBlocks();
  8124. return {
  8125. index: blocks.length - 1,
  8126. offset: blocks[blocks.length - 1].getLength()
  8127. };
  8128. }
  8129. }
  8130. positionFromLocation(location) {
  8131. return this.blockList.findPositionAtIndexAndOffset(location.index, location.offset);
  8132. }
  8133. locationRangeFromPosition(position) {
  8134. return normalizeRange(this.locationFromPosition(position));
  8135. }
  8136. locationRangeFromRange(range) {
  8137. range = normalizeRange(range);
  8138. if (!range) return;
  8139. const [startPosition, endPosition] = Array.from(range);
  8140. const startLocation = this.locationFromPosition(startPosition);
  8141. const endLocation = this.locationFromPosition(endPosition);
  8142. return normalizeRange([startLocation, endLocation]);
  8143. }
  8144. rangeFromLocationRange(locationRange) {
  8145. let rightPosition;
  8146. locationRange = normalizeRange(locationRange);
  8147. const leftPosition = this.positionFromLocation(locationRange[0]);
  8148. if (!rangeIsCollapsed(locationRange)) {
  8149. rightPosition = this.positionFromLocation(locationRange[1]);
  8150. }
  8151. return normalizeRange([leftPosition, rightPosition]);
  8152. }
  8153. isEqualTo(document) {
  8154. return this.blockList.isEqualTo(document === null || document === void 0 ? void 0 : document.blockList);
  8155. }
  8156. getTexts() {
  8157. return this.getBlocks().map(block => block.text);
  8158. }
  8159. getPieces() {
  8160. const pieces = [];
  8161. Array.from(this.getTexts()).forEach(text => {
  8162. pieces.push(...Array.from(text.getPieces() || []));
  8163. });
  8164. return pieces;
  8165. }
  8166. getObjects() {
  8167. return this.getBlocks().concat(this.getTexts()).concat(this.getPieces());
  8168. }
  8169. toSerializableDocument() {
  8170. const blocks = [];
  8171. this.blockList.eachObject(block => blocks.push(block.copyWithText(block.text.toSerializableText())));
  8172. return new this.constructor(blocks);
  8173. }
  8174. toString() {
  8175. return this.blockList.toString();
  8176. }
  8177. toJSON() {
  8178. return this.blockList.toJSON();
  8179. }
  8180. toConsole() {
  8181. return JSON.stringify(this.blockList.toArray().map(block => JSON.parse(block.text.toConsole())));
  8182. }
  8183. }
  8184. const attributesForBlock = function (block) {
  8185. const attributes = {};
  8186. const attributeName = block.getLastAttribute();
  8187. if (attributeName) {
  8188. attributes[attributeName] = true;
  8189. }
  8190. return attributes;
  8191. };
  8192. /* eslint-disable
  8193. no-case-declarations,
  8194. no-irregular-whitespace,
  8195. */
  8196. const pieceForString = function (string) {
  8197. let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  8198. const type = "string";
  8199. string = normalizeSpaces(string);
  8200. return {
  8201. string,
  8202. attributes,
  8203. type
  8204. };
  8205. };
  8206. const pieceForAttachment = function (attachment) {
  8207. let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  8208. const type = "attachment";
  8209. return {
  8210. attachment,
  8211. attributes,
  8212. type
  8213. };
  8214. };
  8215. const blockForAttributes = function () {
  8216. let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  8217. let htmlAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  8218. const text = [];
  8219. return {
  8220. text,
  8221. attributes,
  8222. htmlAttributes
  8223. };
  8224. };
  8225. const parseTrixDataAttribute = (element, name) => {
  8226. try {
  8227. return JSON.parse(element.getAttribute("data-trix-".concat(name)));
  8228. } catch (error) {
  8229. return {};
  8230. }
  8231. };
  8232. const getImageDimensions = element => {
  8233. const width = element.getAttribute("width");
  8234. const height = element.getAttribute("height");
  8235. const dimensions = {};
  8236. if (width) {
  8237. dimensions.width = parseInt(width, 10);
  8238. }
  8239. if (height) {
  8240. dimensions.height = parseInt(height, 10);
  8241. }
  8242. return dimensions;
  8243. };
  8244. class HTMLParser extends BasicObject {
  8245. static parse(html, options) {
  8246. const parser = new this(html, options);
  8247. parser.parse();
  8248. return parser;
  8249. }
  8250. constructor(html) {
  8251. let {
  8252. referenceElement
  8253. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  8254. super(...arguments);
  8255. this.html = html;
  8256. this.referenceElement = referenceElement;
  8257. this.blocks = [];
  8258. this.blockElements = [];
  8259. this.processedElements = [];
  8260. }
  8261. getDocument() {
  8262. return Document.fromJSON(this.blocks);
  8263. }
  8264. // HTML parsing
  8265. parse() {
  8266. try {
  8267. this.createHiddenContainer();
  8268. HTMLSanitizer.setHTML(this.containerElement, this.html);
  8269. const walker = walkTree(this.containerElement, {
  8270. usingFilter: nodeFilter
  8271. });
  8272. while (walker.nextNode()) {
  8273. this.processNode(walker.currentNode);
  8274. }
  8275. return this.translateBlockElementMarginsToNewlines();
  8276. } finally {
  8277. this.removeHiddenContainer();
  8278. }
  8279. }
  8280. createHiddenContainer() {
  8281. if (this.referenceElement) {
  8282. this.containerElement = this.referenceElement.cloneNode(false);
  8283. this.containerElement.removeAttribute("id");
  8284. this.containerElement.setAttribute("data-trix-internal", "");
  8285. this.containerElement.style.display = "none";
  8286. return this.referenceElement.parentNode.insertBefore(this.containerElement, this.referenceElement.nextSibling);
  8287. } else {
  8288. this.containerElement = makeElement({
  8289. tagName: "div",
  8290. style: {
  8291. display: "none"
  8292. }
  8293. });
  8294. return document.body.appendChild(this.containerElement);
  8295. }
  8296. }
  8297. removeHiddenContainer() {
  8298. return removeNode(this.containerElement);
  8299. }
  8300. processNode(node) {
  8301. switch (node.nodeType) {
  8302. case Node.TEXT_NODE:
  8303. if (!this.isInsignificantTextNode(node)) {
  8304. this.appendBlockForTextNode(node);
  8305. return this.processTextNode(node);
  8306. }
  8307. break;
  8308. case Node.ELEMENT_NODE:
  8309. this.appendBlockForElement(node);
  8310. return this.processElement(node);
  8311. }
  8312. }
  8313. appendBlockForTextNode(node) {
  8314. const element = node.parentNode;
  8315. if (element === this.currentBlockElement && this.isBlockElement(node.previousSibling)) {
  8316. return this.appendStringWithAttributes("\n");
  8317. } else if (element === this.containerElement || this.isBlockElement(element)) {
  8318. var _this$currentBlock;
  8319. const attributes = this.getBlockAttributes(element);
  8320. const htmlAttributes = this.getBlockHTMLAttributes(element);
  8321. if (!arraysAreEqual(attributes, (_this$currentBlock = this.currentBlock) === null || _this$currentBlock === void 0 ? void 0 : _this$currentBlock.attributes)) {
  8322. this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
  8323. this.currentBlockElement = element;
  8324. }
  8325. }
  8326. }
  8327. appendBlockForElement(element) {
  8328. const elementIsBlockElement = this.isBlockElement(element);
  8329. const currentBlockContainsElement = elementContainsNode(this.currentBlockElement, element);
  8330. if (elementIsBlockElement && !this.isBlockElement(element.firstChild)) {
  8331. if (!this.isInsignificantTextNode(element.firstChild) || !this.isBlockElement(element.firstElementChild)) {
  8332. const attributes = this.getBlockAttributes(element);
  8333. const htmlAttributes = this.getBlockHTMLAttributes(element);
  8334. if (element.firstChild) {
  8335. if (!(currentBlockContainsElement && arraysAreEqual(attributes, this.currentBlock.attributes))) {
  8336. this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
  8337. this.currentBlockElement = element;
  8338. } else {
  8339. return this.appendStringWithAttributes("\n");
  8340. }
  8341. }
  8342. }
  8343. } else if (this.currentBlockElement && !currentBlockContainsElement && !elementIsBlockElement) {
  8344. const parentBlockElement = this.findParentBlockElement(element);
  8345. if (parentBlockElement) {
  8346. return this.appendBlockForElement(parentBlockElement);
  8347. } else {
  8348. this.currentBlock = this.appendEmptyBlock();
  8349. this.currentBlockElement = null;
  8350. }
  8351. }
  8352. }
  8353. findParentBlockElement(element) {
  8354. let {
  8355. parentElement
  8356. } = element;
  8357. while (parentElement && parentElement !== this.containerElement) {
  8358. if (this.isBlockElement(parentElement) && this.blockElements.includes(parentElement)) {
  8359. return parentElement;
  8360. } else {
  8361. parentElement = parentElement.parentElement;
  8362. }
  8363. }
  8364. return null;
  8365. }
  8366. processTextNode(node) {
  8367. let string = node.data;
  8368. if (!elementCanDisplayPreformattedText(node.parentNode)) {
  8369. var _node$previousSibling;
  8370. string = squishBreakableWhitespace(string);
  8371. if (stringEndsWithWhitespace((_node$previousSibling = node.previousSibling) === null || _node$previousSibling === void 0 ? void 0 : _node$previousSibling.textContent)) {
  8372. string = leftTrimBreakableWhitespace(string);
  8373. }
  8374. }
  8375. return this.appendStringWithAttributes(string, this.getTextAttributes(node.parentNode));
  8376. }
  8377. processElement(element) {
  8378. let attributes;
  8379. if (nodeIsAttachmentElement(element)) {
  8380. attributes = parseTrixDataAttribute(element, "attachment");
  8381. if (Object.keys(attributes).length) {
  8382. const textAttributes = this.getTextAttributes(element);
  8383. this.appendAttachmentWithAttributes(attributes, textAttributes);
  8384. // We have everything we need so avoid processing inner nodes
  8385. element.innerHTML = "";
  8386. }
  8387. return this.processedElements.push(element);
  8388. } else {
  8389. switch (tagName(element)) {
  8390. case "br":
  8391. if (!this.isExtraBR(element) && !this.isBlockElement(element.nextSibling)) {
  8392. this.appendStringWithAttributes("\n", this.getTextAttributes(element));
  8393. }
  8394. return this.processedElements.push(element);
  8395. case "img":
  8396. attributes = {
  8397. url: element.getAttribute("src"),
  8398. contentType: "image"
  8399. };
  8400. const object = getImageDimensions(element);
  8401. for (const key in object) {
  8402. const value = object[key];
  8403. attributes[key] = value;
  8404. }
  8405. this.appendAttachmentWithAttributes(attributes, this.getTextAttributes(element));
  8406. return this.processedElements.push(element);
  8407. case "tr":
  8408. if (this.needsTableSeparator(element)) {
  8409. return this.appendStringWithAttributes(parser.tableRowSeparator);
  8410. }
  8411. break;
  8412. case "td":
  8413. if (this.needsTableSeparator(element)) {
  8414. return this.appendStringWithAttributes(parser.tableCellSeparator);
  8415. }
  8416. break;
  8417. }
  8418. }
  8419. }
  8420. // Document construction
  8421. appendBlockForAttributesWithElement(attributes, element) {
  8422. let htmlAttributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  8423. this.blockElements.push(element);
  8424. const block = blockForAttributes(attributes, htmlAttributes);
  8425. this.blocks.push(block);
  8426. return block;
  8427. }
  8428. appendEmptyBlock() {
  8429. return this.appendBlockForAttributesWithElement([], null);
  8430. }
  8431. appendStringWithAttributes(string, attributes) {
  8432. return this.appendPiece(pieceForString(string, attributes));
  8433. }
  8434. appendAttachmentWithAttributes(attachment, attributes) {
  8435. return this.appendPiece(pieceForAttachment(attachment, attributes));
  8436. }
  8437. appendPiece(piece) {
  8438. if (this.blocks.length === 0) {
  8439. this.appendEmptyBlock();
  8440. }
  8441. return this.blocks[this.blocks.length - 1].text.push(piece);
  8442. }
  8443. appendStringToTextAtIndex(string, index) {
  8444. const {
  8445. text
  8446. } = this.blocks[index];
  8447. const piece = text[text.length - 1];
  8448. if ((piece === null || piece === void 0 ? void 0 : piece.type) === "string") {
  8449. piece.string += string;
  8450. } else {
  8451. return text.push(pieceForString(string));
  8452. }
  8453. }
  8454. prependStringToTextAtIndex(string, index) {
  8455. const {
  8456. text
  8457. } = this.blocks[index];
  8458. const piece = text[0];
  8459. if ((piece === null || piece === void 0 ? void 0 : piece.type) === "string") {
  8460. piece.string = string + piece.string;
  8461. } else {
  8462. return text.unshift(pieceForString(string));
  8463. }
  8464. }
  8465. // Attribute parsing
  8466. getTextAttributes(element) {
  8467. let value;
  8468. const attributes = {};
  8469. for (const attribute in text_attributes) {
  8470. const configAttr = text_attributes[attribute];
  8471. if (configAttr.tagName && findClosestElementFromNode(element, {
  8472. matchingSelector: configAttr.tagName,
  8473. untilNode: this.containerElement
  8474. })) {
  8475. attributes[attribute] = true;
  8476. } else if (configAttr.parser) {
  8477. value = configAttr.parser(element);
  8478. if (value) {
  8479. let attributeInheritedFromBlock = false;
  8480. for (const blockElement of this.findBlockElementAncestors(element)) {
  8481. if (configAttr.parser(blockElement) === value) {
  8482. attributeInheritedFromBlock = true;
  8483. break;
  8484. }
  8485. }
  8486. if (!attributeInheritedFromBlock) {
  8487. attributes[attribute] = value;
  8488. }
  8489. }
  8490. } else if (configAttr.styleProperty) {
  8491. value = element.style[configAttr.styleProperty];
  8492. if (value) {
  8493. attributes[attribute] = value;
  8494. }
  8495. }
  8496. }
  8497. if (nodeIsAttachmentElement(element)) {
  8498. const object = parseTrixDataAttribute(element, "attributes");
  8499. for (const key in object) {
  8500. value = object[key];
  8501. attributes[key] = value;
  8502. }
  8503. }
  8504. return attributes;
  8505. }
  8506. getBlockAttributes(element) {
  8507. const attributes$1 = [];
  8508. while (element && element !== this.containerElement) {
  8509. for (const attribute in attributes) {
  8510. const attrConfig = attributes[attribute];
  8511. if (attrConfig.parse !== false) {
  8512. if (tagName(element) === attrConfig.tagName) {
  8513. var _attrConfig$test;
  8514. if ((_attrConfig$test = attrConfig.test) !== null && _attrConfig$test !== void 0 && _attrConfig$test.call(attrConfig, element) || !attrConfig.test) {
  8515. attributes$1.push(attribute);
  8516. if (attrConfig.listAttribute) {
  8517. attributes$1.push(attrConfig.listAttribute);
  8518. }
  8519. }
  8520. }
  8521. }
  8522. }
  8523. element = element.parentNode;
  8524. }
  8525. return attributes$1.reverse();
  8526. }
  8527. getBlockHTMLAttributes(element) {
  8528. const attributes$1 = {};
  8529. const blockConfig = Object.values(attributes).find(settings => settings.tagName === tagName(element));
  8530. const allowedAttributes = (blockConfig === null || blockConfig === void 0 ? void 0 : blockConfig.htmlAttributes) || [];
  8531. allowedAttributes.forEach(attribute => {
  8532. if (element.hasAttribute(attribute)) {
  8533. attributes$1[attribute] = element.getAttribute(attribute);
  8534. }
  8535. });
  8536. return attributes$1;
  8537. }
  8538. findBlockElementAncestors(element) {
  8539. const ancestors = [];
  8540. while (element && element !== this.containerElement) {
  8541. const tag = tagName(element);
  8542. if (getBlockTagNames().includes(tag)) {
  8543. ancestors.push(element);
  8544. }
  8545. element = element.parentNode;
  8546. }
  8547. return ancestors;
  8548. }
  8549. // Element inspection
  8550. isBlockElement(element) {
  8551. if ((element === null || element === void 0 ? void 0 : element.nodeType) !== Node.ELEMENT_NODE) return;
  8552. if (nodeIsAttachmentElement(element)) return;
  8553. if (findClosestElementFromNode(element, {
  8554. matchingSelector: "td",
  8555. untilNode: this.containerElement
  8556. })) return;
  8557. return getBlockTagNames().includes(tagName(element)) || window.getComputedStyle(element).display === "block";
  8558. }
  8559. isInsignificantTextNode(node) {
  8560. if ((node === null || node === void 0 ? void 0 : node.nodeType) !== Node.TEXT_NODE) return;
  8561. if (!stringIsAllBreakableWhitespace(node.data)) return;
  8562. const {
  8563. parentNode,
  8564. previousSibling,
  8565. nextSibling
  8566. } = node;
  8567. if (nodeEndsWithNonWhitespace(parentNode.previousSibling) && !this.isBlockElement(parentNode.previousSibling)) return;
  8568. if (elementCanDisplayPreformattedText(parentNode)) return;
  8569. return !previousSibling || this.isBlockElement(previousSibling) || !nextSibling || this.isBlockElement(nextSibling);
  8570. }
  8571. isExtraBR(element) {
  8572. return tagName(element) === "br" && this.isBlockElement(element.parentNode) && element.parentNode.lastChild === element;
  8573. }
  8574. needsTableSeparator(element) {
  8575. if (parser.removeBlankTableCells) {
  8576. var _element$previousSibl;
  8577. const content = (_element$previousSibl = element.previousSibling) === null || _element$previousSibl === void 0 ? void 0 : _element$previousSibl.textContent;
  8578. return content && /\S/.test(content);
  8579. } else {
  8580. return element.previousSibling;
  8581. }
  8582. }
  8583. // Margin translation
  8584. translateBlockElementMarginsToNewlines() {
  8585. const defaultMargin = this.getMarginOfDefaultBlockElement();
  8586. for (let index = 0; index < this.blocks.length; index++) {
  8587. const margin = this.getMarginOfBlockElementAtIndex(index);
  8588. if (margin) {
  8589. if (margin.top > defaultMargin.top * 2) {
  8590. this.prependStringToTextAtIndex("\n", index);
  8591. }
  8592. if (margin.bottom > defaultMargin.bottom * 2) {
  8593. this.appendStringToTextAtIndex("\n", index);
  8594. }
  8595. }
  8596. }
  8597. }
  8598. getMarginOfBlockElementAtIndex(index) {
  8599. const element = this.blockElements[index];
  8600. if (element) {
  8601. if (element.textContent) {
  8602. if (!getBlockTagNames().includes(tagName(element)) && !this.processedElements.includes(element)) {
  8603. return getBlockElementMargin(element);
  8604. }
  8605. }
  8606. }
  8607. }
  8608. getMarginOfDefaultBlockElement() {
  8609. const element = makeElement(attributes.default.tagName);
  8610. this.containerElement.appendChild(element);
  8611. return getBlockElementMargin(element);
  8612. }
  8613. }
  8614. // Helpers
  8615. const elementCanDisplayPreformattedText = function (element) {
  8616. const {
  8617. whiteSpace
  8618. } = window.getComputedStyle(element);
  8619. return ["pre", "pre-wrap", "pre-line"].includes(whiteSpace);
  8620. };
  8621. const nodeEndsWithNonWhitespace = node => node && !stringEndsWithWhitespace(node.textContent);
  8622. const getBlockElementMargin = function (element) {
  8623. const style = window.getComputedStyle(element);
  8624. if (style.display === "block") {
  8625. return {
  8626. top: parseInt(style.marginTop),
  8627. bottom: parseInt(style.marginBottom)
  8628. };
  8629. }
  8630. };
  8631. const nodeFilter = function (node) {
  8632. if (tagName(node) === "style") {
  8633. return NodeFilter.FILTER_REJECT;
  8634. } else {
  8635. return NodeFilter.FILTER_ACCEPT;
  8636. }
  8637. };
  8638. // Whitespace
  8639. const leftTrimBreakableWhitespace = string => string.replace(new RegExp("^".concat(breakableWhitespacePattern.source, "+")), "");
  8640. const stringIsAllBreakableWhitespace = string => new RegExp("^".concat(breakableWhitespacePattern.source, "*$")).test(string);
  8641. const stringEndsWithWhitespace = string => /\s$/.test(string);
  8642. /* eslint-disable
  8643. no-empty,
  8644. */
  8645. const unserializableElementSelector = "[data-trix-serialize=false]";
  8646. const unserializableAttributeNames = ["contenteditable", "data-trix-id", "data-trix-store-key", "data-trix-mutable", "data-trix-placeholder", "tabindex"];
  8647. const serializedAttributesAttribute = "data-trix-serialized-attributes";
  8648. const serializedAttributesSelector = "[".concat(serializedAttributesAttribute, "]");
  8649. const blockCommentPattern = new RegExp("<!--block-->", "g");
  8650. const serializers = {
  8651. "application/json": function (serializable) {
  8652. let document;
  8653. if (serializable instanceof Document) {
  8654. document = serializable;
  8655. } else if (serializable instanceof HTMLElement) {
  8656. document = HTMLParser.parse(serializable.innerHTML).getDocument();
  8657. } else {
  8658. throw new Error("unserializable object");
  8659. }
  8660. return document.toSerializableDocument().toJSONString();
  8661. },
  8662. "text/html": function (serializable) {
  8663. let element;
  8664. if (serializable instanceof Document) {
  8665. element = DocumentView.render(serializable);
  8666. } else if (serializable instanceof HTMLElement) {
  8667. element = serializable.cloneNode(true);
  8668. } else {
  8669. throw new Error("unserializable object");
  8670. }
  8671. // Remove unserializable elements
  8672. Array.from(element.querySelectorAll(unserializableElementSelector)).forEach(el => {
  8673. removeNode(el);
  8674. });
  8675. // Remove unserializable attributes
  8676. unserializableAttributeNames.forEach(attribute => {
  8677. Array.from(element.querySelectorAll("[".concat(attribute, "]"))).forEach(el => {
  8678. el.removeAttribute(attribute);
  8679. });
  8680. });
  8681. // Rewrite elements with serialized attribute overrides
  8682. Array.from(element.querySelectorAll(serializedAttributesSelector)).forEach(el => {
  8683. try {
  8684. const attributes = JSON.parse(el.getAttribute(serializedAttributesAttribute));
  8685. el.removeAttribute(serializedAttributesAttribute);
  8686. for (const name in attributes) {
  8687. const value = attributes[name];
  8688. el.setAttribute(name, value);
  8689. }
  8690. } catch (error) {}
  8691. });
  8692. return element.innerHTML.replace(blockCommentPattern, "");
  8693. }
  8694. };
  8695. const deserializers = {
  8696. "application/json": function (string) {
  8697. return Document.fromJSONString(string);
  8698. },
  8699. "text/html": function (string) {
  8700. return HTMLParser.parse(string).getDocument();
  8701. }
  8702. };
  8703. const serializeToContentType = function (serializable, contentType) {
  8704. const serializer = serializers[contentType];
  8705. if (serializer) {
  8706. return serializer(serializable);
  8707. } else {
  8708. throw new Error("unknown content type: ".concat(contentType));
  8709. }
  8710. };
  8711. const deserializeFromContentType = function (string, contentType) {
  8712. const deserializer = deserializers[contentType];
  8713. if (deserializer) {
  8714. return deserializer(string);
  8715. } else {
  8716. throw new Error("unknown content type: ".concat(contentType));
  8717. }
  8718. };
  8719. var core = /*#__PURE__*/Object.freeze({
  8720. __proto__: null
  8721. });
  8722. class ManagedAttachment extends BasicObject {
  8723. constructor(attachmentManager, attachment) {
  8724. super(...arguments);
  8725. this.attachmentManager = attachmentManager;
  8726. this.attachment = attachment;
  8727. this.id = this.attachment.id;
  8728. this.file = this.attachment.file;
  8729. }
  8730. remove() {
  8731. return this.attachmentManager.requestRemovalOfAttachment(this.attachment);
  8732. }
  8733. }
  8734. ManagedAttachment.proxyMethod("attachment.getAttribute");
  8735. ManagedAttachment.proxyMethod("attachment.hasAttribute");
  8736. ManagedAttachment.proxyMethod("attachment.setAttribute");
  8737. ManagedAttachment.proxyMethod("attachment.getAttributes");
  8738. ManagedAttachment.proxyMethod("attachment.setAttributes");
  8739. ManagedAttachment.proxyMethod("attachment.isPending");
  8740. ManagedAttachment.proxyMethod("attachment.isPreviewable");
  8741. ManagedAttachment.proxyMethod("attachment.getURL");
  8742. ManagedAttachment.proxyMethod("attachment.getHref");
  8743. ManagedAttachment.proxyMethod("attachment.getFilename");
  8744. ManagedAttachment.proxyMethod("attachment.getFilesize");
  8745. ManagedAttachment.proxyMethod("attachment.getFormattedFilesize");
  8746. ManagedAttachment.proxyMethod("attachment.getExtension");
  8747. ManagedAttachment.proxyMethod("attachment.getContentType");
  8748. ManagedAttachment.proxyMethod("attachment.getFile");
  8749. ManagedAttachment.proxyMethod("attachment.setFile");
  8750. ManagedAttachment.proxyMethod("attachment.releaseFile");
  8751. ManagedAttachment.proxyMethod("attachment.getUploadProgress");
  8752. ManagedAttachment.proxyMethod("attachment.setUploadProgress");
  8753. class AttachmentManager extends BasicObject {
  8754. constructor() {
  8755. let attachments = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  8756. super(...arguments);
  8757. this.managedAttachments = {};
  8758. Array.from(attachments).forEach(attachment => {
  8759. this.manageAttachment(attachment);
  8760. });
  8761. }
  8762. getAttachments() {
  8763. const result = [];
  8764. for (const id in this.managedAttachments) {
  8765. const attachment = this.managedAttachments[id];
  8766. result.push(attachment);
  8767. }
  8768. return result;
  8769. }
  8770. manageAttachment(attachment) {
  8771. if (!this.managedAttachments[attachment.id]) {
  8772. this.managedAttachments[attachment.id] = new ManagedAttachment(this, attachment);
  8773. }
  8774. return this.managedAttachments[attachment.id];
  8775. }
  8776. attachmentIsManaged(attachment) {
  8777. return attachment.id in this.managedAttachments;
  8778. }
  8779. requestRemovalOfAttachment(attachment) {
  8780. if (this.attachmentIsManaged(attachment)) {
  8781. var _this$delegate, _this$delegate$attach;
  8782. 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);
  8783. }
  8784. }
  8785. unmanageAttachment(attachment) {
  8786. const managedAttachment = this.managedAttachments[attachment.id];
  8787. delete this.managedAttachments[attachment.id];
  8788. return managedAttachment;
  8789. }
  8790. }
  8791. class LineBreakInsertion {
  8792. constructor(composition) {
  8793. this.composition = composition;
  8794. this.document = this.composition.document;
  8795. const selectedRange = this.composition.getSelectedRange();
  8796. this.startPosition = selectedRange[0];
  8797. this.endPosition = selectedRange[1];
  8798. this.startLocation = this.document.locationFromPosition(this.startPosition);
  8799. this.endLocation = this.document.locationFromPosition(this.endPosition);
  8800. this.block = this.document.getBlockAtIndex(this.endLocation.index);
  8801. this.breaksOnReturn = this.block.breaksOnReturn();
  8802. this.previousCharacter = this.block.text.getStringAtPosition(this.endLocation.offset - 1);
  8803. this.nextCharacter = this.block.text.getStringAtPosition(this.endLocation.offset);
  8804. }
  8805. shouldInsertBlockBreak() {
  8806. if (this.block.hasAttributes() && this.block.isListItem() && !this.block.isEmpty()) {
  8807. return this.startLocation.offset !== 0;
  8808. } else {
  8809. return this.breaksOnReturn && this.nextCharacter !== "\n";
  8810. }
  8811. }
  8812. shouldBreakFormattedBlock() {
  8813. return this.block.hasAttributes() && !this.block.isListItem() && (this.breaksOnReturn && this.nextCharacter === "\n" || this.previousCharacter === "\n");
  8814. }
  8815. shouldDecreaseListLevel() {
  8816. return this.block.hasAttributes() && this.block.isListItem() && this.block.isEmpty();
  8817. }
  8818. shouldPrependListItem() {
  8819. return this.block.isListItem() && this.startLocation.offset === 0 && !this.block.isEmpty();
  8820. }
  8821. shouldRemoveLastBlockAttribute() {
  8822. return this.block.hasAttributes() && !this.block.isListItem() && this.block.isEmpty();
  8823. }
  8824. }
  8825. const PLACEHOLDER = " ";
  8826. class Composition extends BasicObject {
  8827. constructor() {
  8828. super(...arguments);
  8829. this.document = new Document();
  8830. this.attachments = [];
  8831. this.currentAttributes = {};
  8832. this.revision = 0;
  8833. }
  8834. setDocument(document) {
  8835. if (!document.isEqualTo(this.document)) {
  8836. var _this$delegate, _this$delegate$compos;
  8837. this.document = document;
  8838. this.refreshAttachments();
  8839. this.revision++;
  8840. 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);
  8841. }
  8842. }
  8843. // Snapshots
  8844. getSnapshot() {
  8845. return {
  8846. document: this.document,
  8847. selectedRange: this.getSelectedRange()
  8848. };
  8849. }
  8850. loadSnapshot(_ref) {
  8851. var _this$delegate2, _this$delegate2$compo, _this$delegate3, _this$delegate3$compo;
  8852. let {
  8853. document,
  8854. selectedRange
  8855. } = _ref;
  8856. (_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);
  8857. this.setDocument(document != null ? document : new Document());
  8858. this.setSelection(selectedRange != null ? selectedRange : [0, 0]);
  8859. 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);
  8860. }
  8861. // Responder protocol
  8862. insertText(text) {
  8863. let {
  8864. updatePosition
  8865. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
  8866. updatePosition: true
  8867. };
  8868. const selectedRange = this.getSelectedRange();
  8869. this.setDocument(this.document.insertTextAtRange(text, selectedRange));
  8870. const startPosition = selectedRange[0];
  8871. const endPosition = startPosition + text.getLength();
  8872. if (updatePosition) {
  8873. this.setSelection(endPosition);
  8874. }
  8875. return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
  8876. }
  8877. insertBlock() {
  8878. let block = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Block();
  8879. const document = new Document([block]);
  8880. return this.insertDocument(document);
  8881. }
  8882. insertDocument() {
  8883. let document = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Document();
  8884. const selectedRange = this.getSelectedRange();
  8885. this.setDocument(this.document.insertDocumentAtRange(document, selectedRange));
  8886. const startPosition = selectedRange[0];
  8887. const endPosition = startPosition + document.getLength();
  8888. this.setSelection(endPosition);
  8889. return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
  8890. }
  8891. insertString(string, options) {
  8892. const attributes = this.getCurrentTextAttributes();
  8893. const text = Text.textForStringWithAttributes(string, attributes);
  8894. return this.insertText(text, options);
  8895. }
  8896. insertBlockBreak() {
  8897. const selectedRange = this.getSelectedRange();
  8898. this.setDocument(this.document.insertBlockBreakAtRange(selectedRange));
  8899. const startPosition = selectedRange[0];
  8900. const endPosition = startPosition + 1;
  8901. this.setSelection(endPosition);
  8902. return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
  8903. }
  8904. insertLineBreak() {
  8905. const insertion = new LineBreakInsertion(this);
  8906. if (insertion.shouldDecreaseListLevel()) {
  8907. this.decreaseListLevel();
  8908. return this.setSelection(insertion.startPosition);
  8909. } else if (insertion.shouldPrependListItem()) {
  8910. const document = new Document([insertion.block.copyWithoutText()]);
  8911. return this.insertDocument(document);
  8912. } else if (insertion.shouldInsertBlockBreak()) {
  8913. return this.insertBlockBreak();
  8914. } else if (insertion.shouldRemoveLastBlockAttribute()) {
  8915. return this.removeLastBlockAttribute();
  8916. } else if (insertion.shouldBreakFormattedBlock()) {
  8917. return this.breakFormattedBlock(insertion);
  8918. } else {
  8919. return this.insertString("\n");
  8920. }
  8921. }
  8922. insertHTML(html) {
  8923. const document = HTMLParser.parse(html).getDocument();
  8924. const selectedRange = this.getSelectedRange();
  8925. this.setDocument(this.document.mergeDocumentAtRange(document, selectedRange));
  8926. const startPosition = selectedRange[0];
  8927. const endPosition = startPosition + document.getLength() - 1;
  8928. this.setSelection(endPosition);
  8929. return this.notifyDelegateOfInsertionAtRange([startPosition, endPosition]);
  8930. }
  8931. replaceHTML(html) {
  8932. const document = HTMLParser.parse(html).getDocument().copyUsingObjectsFromDocument(this.document);
  8933. const locationRange = this.getLocationRange({
  8934. strict: false
  8935. });
  8936. const selectedRange = this.document.rangeFromLocationRange(locationRange);
  8937. this.setDocument(document);
  8938. return this.setSelection(selectedRange);
  8939. }
  8940. insertFile(file) {
  8941. return this.insertFiles([file]);
  8942. }
  8943. insertFiles(files) {
  8944. const attachments = [];
  8945. Array.from(files).forEach(file => {
  8946. var _this$delegate4;
  8947. if ((_this$delegate4 = this.delegate) !== null && _this$delegate4 !== void 0 && _this$delegate4.compositionShouldAcceptFile(file)) {
  8948. const attachment = Attachment.attachmentForFile(file);
  8949. attachments.push(attachment);
  8950. }
  8951. });
  8952. return this.insertAttachments(attachments);
  8953. }
  8954. insertAttachment(attachment) {
  8955. return this.insertAttachments([attachment]);
  8956. }
  8957. insertAttachments(attachments$1) {
  8958. let text = new Text();
  8959. Array.from(attachments$1).forEach(attachment => {
  8960. var _config$attachments$t;
  8961. const type = attachment.getType();
  8962. const presentation = (_config$attachments$t = attachments[type]) === null || _config$attachments$t === void 0 ? void 0 : _config$attachments$t.presentation;
  8963. const attributes = this.getCurrentTextAttributes();
  8964. if (presentation) {
  8965. attributes.presentation = presentation;
  8966. }
  8967. const attachmentText = Text.textForAttachmentWithAttributes(attachment, attributes);
  8968. text = text.appendText(attachmentText);
  8969. });
  8970. return this.insertText(text);
  8971. }
  8972. shouldManageDeletingInDirection(direction) {
  8973. const locationRange = this.getLocationRange();
  8974. if (rangeIsCollapsed(locationRange)) {
  8975. if (direction === "backward" && locationRange[0].offset === 0) {
  8976. return true;
  8977. }
  8978. if (this.shouldManageMovingCursorInDirection(direction)) {
  8979. return true;
  8980. }
  8981. } else {
  8982. if (locationRange[0].index !== locationRange[1].index) {
  8983. return true;
  8984. }
  8985. }
  8986. return false;
  8987. }
  8988. deleteInDirection(direction) {
  8989. let {
  8990. length
  8991. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  8992. let attachment, deletingIntoPreviousBlock, selectionSpansBlocks;
  8993. const locationRange = this.getLocationRange();
  8994. let range = this.getSelectedRange();
  8995. const selectionIsCollapsed = rangeIsCollapsed(range);
  8996. if (selectionIsCollapsed) {
  8997. deletingIntoPreviousBlock = direction === "backward" && locationRange[0].offset === 0;
  8998. } else {
  8999. selectionSpansBlocks = locationRange[0].index !== locationRange[1].index;
  9000. }
  9001. if (deletingIntoPreviousBlock) {
  9002. if (this.canDecreaseBlockAttributeLevel()) {
  9003. const block = this.getBlock();
  9004. if (block.isListItem()) {
  9005. this.decreaseListLevel();
  9006. } else {
  9007. this.decreaseBlockAttributeLevel();
  9008. }
  9009. this.setSelection(range[0]);
  9010. if (block.isEmpty()) {
  9011. return false;
  9012. }
  9013. }
  9014. }
  9015. if (selectionIsCollapsed) {
  9016. range = this.getExpandedRangeInDirection(direction, {
  9017. length
  9018. });
  9019. if (direction === "backward") {
  9020. attachment = this.getAttachmentAtRange(range);
  9021. }
  9022. }
  9023. if (attachment) {
  9024. this.editAttachment(attachment);
  9025. return false;
  9026. } else {
  9027. this.setDocument(this.document.removeTextAtRange(range));
  9028. this.setSelection(range[0]);
  9029. if (deletingIntoPreviousBlock || selectionSpansBlocks) {
  9030. return false;
  9031. }
  9032. }
  9033. }
  9034. moveTextFromRange(range) {
  9035. const [position] = Array.from(this.getSelectedRange());
  9036. this.setDocument(this.document.moveTextFromRangeToPosition(range, position));
  9037. return this.setSelection(position);
  9038. }
  9039. removeAttachment(attachment) {
  9040. const range = this.document.getRangeOfAttachment(attachment);
  9041. if (range) {
  9042. this.stopEditingAttachment();
  9043. this.setDocument(this.document.removeTextAtRange(range));
  9044. return this.setSelection(range[0]);
  9045. }
  9046. }
  9047. removeLastBlockAttribute() {
  9048. const [startPosition, endPosition] = Array.from(this.getSelectedRange());
  9049. const block = this.document.getBlockAtPosition(endPosition);
  9050. this.removeCurrentAttribute(block.getLastAttribute());
  9051. return this.setSelection(startPosition);
  9052. }
  9053. insertPlaceholder() {
  9054. this.placeholderPosition = this.getPosition();
  9055. return this.insertString(PLACEHOLDER);
  9056. }
  9057. selectPlaceholder() {
  9058. if (this.placeholderPosition != null) {
  9059. this.setSelectedRange([this.placeholderPosition, this.placeholderPosition + PLACEHOLDER.length]);
  9060. return this.getSelectedRange();
  9061. }
  9062. }
  9063. forgetPlaceholder() {
  9064. this.placeholderPosition = null;
  9065. }
  9066. // Current attributes
  9067. hasCurrentAttribute(attributeName) {
  9068. const value = this.currentAttributes[attributeName];
  9069. return value != null && value !== false;
  9070. }
  9071. toggleCurrentAttribute(attributeName) {
  9072. const value = !this.currentAttributes[attributeName];
  9073. if (value) {
  9074. return this.setCurrentAttribute(attributeName, value);
  9075. } else {
  9076. return this.removeCurrentAttribute(attributeName);
  9077. }
  9078. }
  9079. canSetCurrentAttribute(attributeName) {
  9080. if (getBlockConfig(attributeName)) {
  9081. return this.canSetCurrentBlockAttribute(attributeName);
  9082. } else {
  9083. return this.canSetCurrentTextAttribute(attributeName);
  9084. }
  9085. }
  9086. canSetCurrentTextAttribute(attributeName) {
  9087. const document = this.getSelectedDocument();
  9088. if (!document) return;
  9089. for (const attachment of Array.from(document.getAttachments())) {
  9090. if (!attachment.hasContent()) {
  9091. return false;
  9092. }
  9093. }
  9094. return true;
  9095. }
  9096. canSetCurrentBlockAttribute(attributeName) {
  9097. const block = this.getBlock();
  9098. if (!block) return;
  9099. return !block.isTerminalBlock();
  9100. }
  9101. setCurrentAttribute(attributeName, value) {
  9102. if (getBlockConfig(attributeName)) {
  9103. return this.setBlockAttribute(attributeName, value);
  9104. } else {
  9105. this.setTextAttribute(attributeName, value);
  9106. this.currentAttributes[attributeName] = value;
  9107. return this.notifyDelegateOfCurrentAttributesChange();
  9108. }
  9109. }
  9110. setHTMLAtributeAtPosition(position, attributeName, value) {
  9111. var _getBlockConfig;
  9112. const block = this.document.getBlockAtPosition(position);
  9113. const allowedHTMLAttributes = (_getBlockConfig = getBlockConfig(block.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.htmlAttributes;
  9114. if (block && allowedHTMLAttributes !== null && allowedHTMLAttributes !== void 0 && allowedHTMLAttributes.includes(attributeName)) {
  9115. const newDocument = this.document.setHTMLAttributeAtPosition(position, attributeName, value);
  9116. this.setDocument(newDocument);
  9117. }
  9118. }
  9119. setTextAttribute(attributeName, value) {
  9120. const selectedRange = this.getSelectedRange();
  9121. if (!selectedRange) return;
  9122. const [startPosition, endPosition] = Array.from(selectedRange);
  9123. if (startPosition === endPosition) {
  9124. if (attributeName === "href") {
  9125. const text = Text.textForStringWithAttributes(value, {
  9126. href: value
  9127. });
  9128. return this.insertText(text);
  9129. }
  9130. } else {
  9131. return this.setDocument(this.document.addAttributeAtRange(attributeName, value, selectedRange));
  9132. }
  9133. }
  9134. setBlockAttribute(attributeName, value) {
  9135. const selectedRange = this.getSelectedRange();
  9136. if (this.canSetCurrentAttribute(attributeName)) {
  9137. this.setDocument(this.document.applyBlockAttributeAtRange(attributeName, value, selectedRange));
  9138. return this.setSelection(selectedRange);
  9139. }
  9140. }
  9141. removeCurrentAttribute(attributeName) {
  9142. if (getBlockConfig(attributeName)) {
  9143. this.removeBlockAttribute(attributeName);
  9144. return this.updateCurrentAttributes();
  9145. } else {
  9146. this.removeTextAttribute(attributeName);
  9147. delete this.currentAttributes[attributeName];
  9148. return this.notifyDelegateOfCurrentAttributesChange();
  9149. }
  9150. }
  9151. removeTextAttribute(attributeName) {
  9152. const selectedRange = this.getSelectedRange();
  9153. if (!selectedRange) return;
  9154. return this.setDocument(this.document.removeAttributeAtRange(attributeName, selectedRange));
  9155. }
  9156. removeBlockAttribute(attributeName) {
  9157. const selectedRange = this.getSelectedRange();
  9158. if (!selectedRange) return;
  9159. return this.setDocument(this.document.removeAttributeAtRange(attributeName, selectedRange));
  9160. }
  9161. canDecreaseNestingLevel() {
  9162. var _this$getBlock;
  9163. return ((_this$getBlock = this.getBlock()) === null || _this$getBlock === void 0 ? void 0 : _this$getBlock.getNestingLevel()) > 0;
  9164. }
  9165. canIncreaseNestingLevel() {
  9166. var _getBlockConfig2;
  9167. const block = this.getBlock();
  9168. if (!block) return;
  9169. if ((_getBlockConfig2 = getBlockConfig(block.getLastNestableAttribute())) !== null && _getBlockConfig2 !== void 0 && _getBlockConfig2.listAttribute) {
  9170. const previousBlock = this.getPreviousBlock();
  9171. if (previousBlock) {
  9172. return arrayStartsWith(previousBlock.getListItemAttributes(), block.getListItemAttributes());
  9173. }
  9174. } else {
  9175. return block.getNestingLevel() > 0;
  9176. }
  9177. }
  9178. decreaseNestingLevel() {
  9179. const block = this.getBlock();
  9180. if (!block) return;
  9181. return this.setDocument(this.document.replaceBlock(block, block.decreaseNestingLevel()));
  9182. }
  9183. increaseNestingLevel() {
  9184. const block = this.getBlock();
  9185. if (!block) return;
  9186. return this.setDocument(this.document.replaceBlock(block, block.increaseNestingLevel()));
  9187. }
  9188. canDecreaseBlockAttributeLevel() {
  9189. var _this$getBlock2;
  9190. return ((_this$getBlock2 = this.getBlock()) === null || _this$getBlock2 === void 0 ? void 0 : _this$getBlock2.getAttributeLevel()) > 0;
  9191. }
  9192. decreaseBlockAttributeLevel() {
  9193. var _this$getBlock3;
  9194. const attribute = (_this$getBlock3 = this.getBlock()) === null || _this$getBlock3 === void 0 ? void 0 : _this$getBlock3.getLastAttribute();
  9195. if (attribute) {
  9196. return this.removeCurrentAttribute(attribute);
  9197. }
  9198. }
  9199. decreaseListLevel() {
  9200. let [startPosition] = Array.from(this.getSelectedRange());
  9201. const {
  9202. index
  9203. } = this.document.locationFromPosition(startPosition);
  9204. let endIndex = index;
  9205. const attributeLevel = this.getBlock().getAttributeLevel();
  9206. let block = this.document.getBlockAtIndex(endIndex + 1);
  9207. while (block) {
  9208. if (!block.isListItem() || block.getAttributeLevel() <= attributeLevel) {
  9209. break;
  9210. }
  9211. endIndex++;
  9212. block = this.document.getBlockAtIndex(endIndex + 1);
  9213. }
  9214. startPosition = this.document.positionFromLocation({
  9215. index,
  9216. offset: 0
  9217. });
  9218. const endPosition = this.document.positionFromLocation({
  9219. index: endIndex,
  9220. offset: 0
  9221. });
  9222. return this.setDocument(this.document.removeLastListAttributeAtRange([startPosition, endPosition]));
  9223. }
  9224. updateCurrentAttributes() {
  9225. const selectedRange = this.getSelectedRange({
  9226. ignoreLock: true
  9227. });
  9228. if (selectedRange) {
  9229. const currentAttributes = this.document.getCommonAttributesAtRange(selectedRange);
  9230. Array.from(getAllAttributeNames()).forEach(attributeName => {
  9231. if (!currentAttributes[attributeName]) {
  9232. if (!this.canSetCurrentAttribute(attributeName)) {
  9233. currentAttributes[attributeName] = false;
  9234. }
  9235. }
  9236. });
  9237. if (!objectsAreEqual(currentAttributes, this.currentAttributes)) {
  9238. this.currentAttributes = currentAttributes;
  9239. return this.notifyDelegateOfCurrentAttributesChange();
  9240. }
  9241. }
  9242. }
  9243. getCurrentAttributes() {
  9244. return extend.call({}, this.currentAttributes);
  9245. }
  9246. getCurrentTextAttributes() {
  9247. const attributes = {};
  9248. for (const key in this.currentAttributes) {
  9249. const value = this.currentAttributes[key];
  9250. if (value !== false) {
  9251. if (getTextConfig(key)) {
  9252. attributes[key] = value;
  9253. }
  9254. }
  9255. }
  9256. return attributes;
  9257. }
  9258. // Selection freezing
  9259. freezeSelection() {
  9260. return this.setCurrentAttribute("frozen", true);
  9261. }
  9262. thawSelection() {
  9263. return this.removeCurrentAttribute("frozen");
  9264. }
  9265. hasFrozenSelection() {
  9266. return this.hasCurrentAttribute("frozen");
  9267. }
  9268. setSelection(selectedRange) {
  9269. var _this$delegate5;
  9270. const locationRange = this.document.locationRangeFromRange(selectedRange);
  9271. return (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 ? void 0 : _this$delegate5.compositionDidRequestChangingSelectionToLocationRange(locationRange);
  9272. }
  9273. getSelectedRange() {
  9274. const locationRange = this.getLocationRange();
  9275. if (locationRange) {
  9276. return this.document.rangeFromLocationRange(locationRange);
  9277. }
  9278. }
  9279. setSelectedRange(selectedRange) {
  9280. const locationRange = this.document.locationRangeFromRange(selectedRange);
  9281. return this.getSelectionManager().setLocationRange(locationRange);
  9282. }
  9283. getPosition() {
  9284. const locationRange = this.getLocationRange();
  9285. if (locationRange) {
  9286. return this.document.positionFromLocation(locationRange[0]);
  9287. }
  9288. }
  9289. getLocationRange(options) {
  9290. if (this.targetLocationRange) {
  9291. return this.targetLocationRange;
  9292. } else {
  9293. return this.getSelectionManager().getLocationRange(options) || normalizeRange({
  9294. index: 0,
  9295. offset: 0
  9296. });
  9297. }
  9298. }
  9299. withTargetLocationRange(locationRange, fn) {
  9300. let result;
  9301. this.targetLocationRange = locationRange;
  9302. try {
  9303. result = fn();
  9304. } finally {
  9305. this.targetLocationRange = null;
  9306. }
  9307. return result;
  9308. }
  9309. withTargetRange(range, fn) {
  9310. const locationRange = this.document.locationRangeFromRange(range);
  9311. return this.withTargetLocationRange(locationRange, fn);
  9312. }
  9313. withTargetDOMRange(domRange, fn) {
  9314. const locationRange = this.createLocationRangeFromDOMRange(domRange, {
  9315. strict: false
  9316. });
  9317. return this.withTargetLocationRange(locationRange, fn);
  9318. }
  9319. getExpandedRangeInDirection(direction) {
  9320. let {
  9321. length
  9322. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  9323. let [startPosition, endPosition] = Array.from(this.getSelectedRange());
  9324. if (direction === "backward") {
  9325. if (length) {
  9326. startPosition -= length;
  9327. } else {
  9328. startPosition = this.translateUTF16PositionFromOffset(startPosition, -1);
  9329. }
  9330. } else {
  9331. if (length) {
  9332. endPosition += length;
  9333. } else {
  9334. endPosition = this.translateUTF16PositionFromOffset(endPosition, 1);
  9335. }
  9336. }
  9337. return normalizeRange([startPosition, endPosition]);
  9338. }
  9339. shouldManageMovingCursorInDirection(direction) {
  9340. if (this.editingAttachment) {
  9341. return true;
  9342. }
  9343. const range = this.getExpandedRangeInDirection(direction);
  9344. return this.getAttachmentAtRange(range) != null;
  9345. }
  9346. moveCursorInDirection(direction) {
  9347. let canEditAttachment, range;
  9348. if (this.editingAttachment) {
  9349. range = this.document.getRangeOfAttachment(this.editingAttachment);
  9350. } else {
  9351. const selectedRange = this.getSelectedRange();
  9352. range = this.getExpandedRangeInDirection(direction);
  9353. canEditAttachment = !rangesAreEqual(selectedRange, range);
  9354. }
  9355. if (direction === "backward") {
  9356. this.setSelectedRange(range[0]);
  9357. } else {
  9358. this.setSelectedRange(range[1]);
  9359. }
  9360. if (canEditAttachment) {
  9361. const attachment = this.getAttachmentAtRange(range);
  9362. if (attachment) {
  9363. return this.editAttachment(attachment);
  9364. }
  9365. }
  9366. }
  9367. expandSelectionInDirection(direction) {
  9368. let {
  9369. length
  9370. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  9371. const range = this.getExpandedRangeInDirection(direction, {
  9372. length
  9373. });
  9374. return this.setSelectedRange(range);
  9375. }
  9376. expandSelectionForEditing() {
  9377. if (this.hasCurrentAttribute("href")) {
  9378. return this.expandSelectionAroundCommonAttribute("href");
  9379. }
  9380. }
  9381. expandSelectionAroundCommonAttribute(attributeName) {
  9382. const position = this.getPosition();
  9383. const range = this.document.getRangeOfCommonAttributeAtPosition(attributeName, position);
  9384. return this.setSelectedRange(range);
  9385. }
  9386. selectionContainsAttachments() {
  9387. var _this$getSelectedAtta;
  9388. return ((_this$getSelectedAtta = this.getSelectedAttachments()) === null || _this$getSelectedAtta === void 0 ? void 0 : _this$getSelectedAtta.length) > 0;
  9389. }
  9390. selectionIsInCursorTarget() {
  9391. return this.editingAttachment || this.positionIsCursorTarget(this.getPosition());
  9392. }
  9393. positionIsCursorTarget(position) {
  9394. const location = this.document.locationFromPosition(position);
  9395. if (location) {
  9396. return this.locationIsCursorTarget(location);
  9397. }
  9398. }
  9399. positionIsBlockBreak(position) {
  9400. var _this$document$getPie;
  9401. return (_this$document$getPie = this.document.getPieceAtPosition(position)) === null || _this$document$getPie === void 0 ? void 0 : _this$document$getPie.isBlockBreak();
  9402. }
  9403. getSelectedDocument() {
  9404. const selectedRange = this.getSelectedRange();
  9405. if (selectedRange) {
  9406. return this.document.getDocumentAtRange(selectedRange);
  9407. }
  9408. }
  9409. getSelectedAttachments() {
  9410. var _this$getSelectedDocu;
  9411. return (_this$getSelectedDocu = this.getSelectedDocument()) === null || _this$getSelectedDocu === void 0 ? void 0 : _this$getSelectedDocu.getAttachments();
  9412. }
  9413. // Attachments
  9414. getAttachments() {
  9415. return this.attachments.slice(0);
  9416. }
  9417. refreshAttachments() {
  9418. const attachments = this.document.getAttachments();
  9419. const {
  9420. added,
  9421. removed
  9422. } = summarizeArrayChange(this.attachments, attachments);
  9423. this.attachments = attachments;
  9424. Array.from(removed).forEach(attachment => {
  9425. var _this$delegate6, _this$delegate6$compo;
  9426. attachment.delegate = null;
  9427. (_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);
  9428. });
  9429. return (() => {
  9430. const result = [];
  9431. Array.from(added).forEach(attachment => {
  9432. var _this$delegate7, _this$delegate7$compo;
  9433. attachment.delegate = this;
  9434. 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));
  9435. });
  9436. return result;
  9437. })();
  9438. }
  9439. // Attachment delegate
  9440. attachmentDidChangeAttributes(attachment) {
  9441. var _this$delegate8, _this$delegate8$compo;
  9442. this.revision++;
  9443. 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);
  9444. }
  9445. attachmentDidChangePreviewURL(attachment) {
  9446. var _this$delegate9, _this$delegate9$compo;
  9447. this.revision++;
  9448. 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);
  9449. }
  9450. // Attachment editing
  9451. editAttachment(attachment, options) {
  9452. var _this$delegate10, _this$delegate10$comp;
  9453. if (attachment === this.editingAttachment) return;
  9454. this.stopEditingAttachment();
  9455. this.editingAttachment = attachment;
  9456. 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);
  9457. }
  9458. stopEditingAttachment() {
  9459. var _this$delegate11, _this$delegate11$comp;
  9460. if (!this.editingAttachment) return;
  9461. (_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);
  9462. this.editingAttachment = null;
  9463. }
  9464. updateAttributesForAttachment(attributes, attachment) {
  9465. return this.setDocument(this.document.updateAttributesForAttachment(attributes, attachment));
  9466. }
  9467. removeAttributeForAttachment(attribute, attachment) {
  9468. return this.setDocument(this.document.removeAttributeForAttachment(attribute, attachment));
  9469. }
  9470. // Private
  9471. breakFormattedBlock(insertion) {
  9472. let {
  9473. document
  9474. } = insertion;
  9475. const {
  9476. block
  9477. } = insertion;
  9478. let position = insertion.startPosition;
  9479. let range = [position - 1, position];
  9480. if (block.getBlockBreakPosition() === insertion.startLocation.offset) {
  9481. if (block.breaksOnReturn() && insertion.nextCharacter === "\n") {
  9482. position += 1;
  9483. } else {
  9484. document = document.removeTextAtRange(range);
  9485. }
  9486. range = [position, position];
  9487. } else if (insertion.nextCharacter === "\n") {
  9488. if (insertion.previousCharacter === "\n") {
  9489. range = [position - 1, position + 1];
  9490. } else {
  9491. range = [position, position + 1];
  9492. position += 1;
  9493. }
  9494. } else if (insertion.startLocation.offset - 1 !== 0) {
  9495. position += 1;
  9496. }
  9497. const newDocument = new Document([block.removeLastAttribute().copyWithoutText()]);
  9498. this.setDocument(document.insertDocumentAtRange(newDocument, range));
  9499. return this.setSelection(position);
  9500. }
  9501. getPreviousBlock() {
  9502. const locationRange = this.getLocationRange();
  9503. if (locationRange) {
  9504. const {
  9505. index
  9506. } = locationRange[0];
  9507. if (index > 0) {
  9508. return this.document.getBlockAtIndex(index - 1);
  9509. }
  9510. }
  9511. }
  9512. getBlock() {
  9513. const locationRange = this.getLocationRange();
  9514. if (locationRange) {
  9515. return this.document.getBlockAtIndex(locationRange[0].index);
  9516. }
  9517. }
  9518. getAttachmentAtRange(range) {
  9519. const document = this.document.getDocumentAtRange(range);
  9520. if (document.toString() === "".concat(OBJECT_REPLACEMENT_CHARACTER, "\n")) {
  9521. return document.getAttachments()[0];
  9522. }
  9523. }
  9524. notifyDelegateOfCurrentAttributesChange() {
  9525. var _this$delegate12, _this$delegate12$comp;
  9526. 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);
  9527. }
  9528. notifyDelegateOfInsertionAtRange(range) {
  9529. var _this$delegate13, _this$delegate13$comp;
  9530. 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);
  9531. }
  9532. translateUTF16PositionFromOffset(position, offset) {
  9533. const utf16string = this.document.toUTF16String();
  9534. const utf16position = utf16string.offsetFromUCS2Offset(position);
  9535. return utf16string.offsetToUCS2Offset(utf16position + offset);
  9536. }
  9537. }
  9538. Composition.proxyMethod("getSelectionManager().getPointRange");
  9539. Composition.proxyMethod("getSelectionManager().setLocationRangeFromPointRange");
  9540. Composition.proxyMethod("getSelectionManager().createLocationRangeFromDOMRange");
  9541. Composition.proxyMethod("getSelectionManager().locationIsCursorTarget");
  9542. Composition.proxyMethod("getSelectionManager().selectionIsExpanded");
  9543. Composition.proxyMethod("delegate?.getSelectionManager");
  9544. class UndoManager extends BasicObject {
  9545. constructor(composition) {
  9546. super(...arguments);
  9547. this.composition = composition;
  9548. this.undoEntries = [];
  9549. this.redoEntries = [];
  9550. }
  9551. recordUndoEntry(description) {
  9552. let {
  9553. context,
  9554. consolidatable
  9555. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  9556. const previousEntry = this.undoEntries.slice(-1)[0];
  9557. if (!consolidatable || !entryHasDescriptionAndContext(previousEntry, description, context)) {
  9558. const undoEntry = this.createEntry({
  9559. description,
  9560. context
  9561. });
  9562. this.undoEntries.push(undoEntry);
  9563. this.redoEntries = [];
  9564. }
  9565. }
  9566. undo() {
  9567. const undoEntry = this.undoEntries.pop();
  9568. if (undoEntry) {
  9569. const redoEntry = this.createEntry(undoEntry);
  9570. this.redoEntries.push(redoEntry);
  9571. return this.composition.loadSnapshot(undoEntry.snapshot);
  9572. }
  9573. }
  9574. redo() {
  9575. const redoEntry = this.redoEntries.pop();
  9576. if (redoEntry) {
  9577. const undoEntry = this.createEntry(redoEntry);
  9578. this.undoEntries.push(undoEntry);
  9579. return this.composition.loadSnapshot(redoEntry.snapshot);
  9580. }
  9581. }
  9582. canUndo() {
  9583. return this.undoEntries.length > 0;
  9584. }
  9585. canRedo() {
  9586. return this.redoEntries.length > 0;
  9587. }
  9588. // Private
  9589. createEntry() {
  9590. let {
  9591. description,
  9592. context
  9593. } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  9594. return {
  9595. description: description === null || description === void 0 ? void 0 : description.toString(),
  9596. context: JSON.stringify(context),
  9597. snapshot: this.composition.getSnapshot()
  9598. };
  9599. }
  9600. }
  9601. 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);
  9602. const BLOCK_ATTRIBUTE_NAME = "attachmentGallery";
  9603. const TEXT_ATTRIBUTE_NAME = "presentation";
  9604. const TEXT_ATTRIBUTE_VALUE = "gallery";
  9605. class Filter {
  9606. constructor(snapshot) {
  9607. this.document = snapshot.document;
  9608. this.selectedRange = snapshot.selectedRange;
  9609. }
  9610. perform() {
  9611. this.removeBlockAttribute();
  9612. return this.applyBlockAttribute();
  9613. }
  9614. getSnapshot() {
  9615. return {
  9616. document: this.document,
  9617. selectedRange: this.selectedRange
  9618. };
  9619. }
  9620. // Private
  9621. removeBlockAttribute() {
  9622. return this.findRangesOfBlocks().map(range => this.document = this.document.removeAttributeAtRange(BLOCK_ATTRIBUTE_NAME, range));
  9623. }
  9624. applyBlockAttribute() {
  9625. let offset = 0;
  9626. this.findRangesOfPieces().forEach(range => {
  9627. if (range[1] - range[0] > 1) {
  9628. range[0] += offset;
  9629. range[1] += offset;
  9630. if (this.document.getCharacterAtPosition(range[1]) !== "\n") {
  9631. this.document = this.document.insertBlockBreakAtRange(range[1]);
  9632. if (range[1] < this.selectedRange[1]) {
  9633. this.moveSelectedRangeForward();
  9634. }
  9635. range[1]++;
  9636. offset++;
  9637. }
  9638. if (range[0] !== 0) {
  9639. if (this.document.getCharacterAtPosition(range[0] - 1) !== "\n") {
  9640. this.document = this.document.insertBlockBreakAtRange(range[0]);
  9641. if (range[0] < this.selectedRange[0]) {
  9642. this.moveSelectedRangeForward();
  9643. }
  9644. range[0]++;
  9645. offset++;
  9646. }
  9647. }
  9648. this.document = this.document.applyBlockAttributeAtRange(BLOCK_ATTRIBUTE_NAME, true, range);
  9649. }
  9650. });
  9651. }
  9652. findRangesOfBlocks() {
  9653. return this.document.findRangesForBlockAttribute(BLOCK_ATTRIBUTE_NAME);
  9654. }
  9655. findRangesOfPieces() {
  9656. return this.document.findRangesForTextAttribute(TEXT_ATTRIBUTE_NAME, {
  9657. withValue: TEXT_ATTRIBUTE_VALUE
  9658. });
  9659. }
  9660. moveSelectedRangeForward() {
  9661. this.selectedRange[0] += 1;
  9662. this.selectedRange[1] += 1;
  9663. }
  9664. }
  9665. const attachmentGalleryFilter = function (snapshot) {
  9666. const filter = new Filter(snapshot);
  9667. filter.perform();
  9668. return filter.getSnapshot();
  9669. };
  9670. const DEFAULT_FILTERS = [attachmentGalleryFilter];
  9671. class Editor {
  9672. constructor(composition, selectionManager, element) {
  9673. this.insertFiles = this.insertFiles.bind(this);
  9674. this.composition = composition;
  9675. this.selectionManager = selectionManager;
  9676. this.element = element;
  9677. this.undoManager = new UndoManager(this.composition);
  9678. this.filters = DEFAULT_FILTERS.slice(0);
  9679. }
  9680. loadDocument(document) {
  9681. return this.loadSnapshot({
  9682. document,
  9683. selectedRange: [0, 0]
  9684. });
  9685. }
  9686. loadHTML() {
  9687. let html = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
  9688. const document = HTMLParser.parse(html, {
  9689. referenceElement: this.element
  9690. }).getDocument();
  9691. return this.loadDocument(document);
  9692. }
  9693. loadJSON(_ref) {
  9694. let {
  9695. document,
  9696. selectedRange
  9697. } = _ref;
  9698. document = Document.fromJSON(document);
  9699. return this.loadSnapshot({
  9700. document,
  9701. selectedRange
  9702. });
  9703. }
  9704. loadSnapshot(snapshot) {
  9705. this.undoManager = new UndoManager(this.composition);
  9706. return this.composition.loadSnapshot(snapshot);
  9707. }
  9708. getDocument() {
  9709. return this.composition.document;
  9710. }
  9711. getSelectedDocument() {
  9712. return this.composition.getSelectedDocument();
  9713. }
  9714. getSnapshot() {
  9715. return this.composition.getSnapshot();
  9716. }
  9717. toJSON() {
  9718. return this.getSnapshot();
  9719. }
  9720. // Document manipulation
  9721. deleteInDirection(direction) {
  9722. return this.composition.deleteInDirection(direction);
  9723. }
  9724. insertAttachment(attachment) {
  9725. return this.composition.insertAttachment(attachment);
  9726. }
  9727. insertAttachments(attachments) {
  9728. return this.composition.insertAttachments(attachments);
  9729. }
  9730. insertDocument(document) {
  9731. return this.composition.insertDocument(document);
  9732. }
  9733. insertFile(file) {
  9734. return this.composition.insertFile(file);
  9735. }
  9736. insertFiles(files) {
  9737. return this.composition.insertFiles(files);
  9738. }
  9739. insertHTML(html) {
  9740. return this.composition.insertHTML(html);
  9741. }
  9742. insertString(string) {
  9743. return this.composition.insertString(string);
  9744. }
  9745. insertText(text) {
  9746. return this.composition.insertText(text);
  9747. }
  9748. insertLineBreak() {
  9749. return this.composition.insertLineBreak();
  9750. }
  9751. // Selection
  9752. getSelectedRange() {
  9753. return this.composition.getSelectedRange();
  9754. }
  9755. getPosition() {
  9756. return this.composition.getPosition();
  9757. }
  9758. getClientRectAtPosition(position) {
  9759. const locationRange = this.getDocument().locationRangeFromRange([position, position + 1]);
  9760. return this.selectionManager.getClientRectAtLocationRange(locationRange);
  9761. }
  9762. expandSelectionInDirection(direction) {
  9763. return this.composition.expandSelectionInDirection(direction);
  9764. }
  9765. moveCursorInDirection(direction) {
  9766. return this.composition.moveCursorInDirection(direction);
  9767. }
  9768. setSelectedRange(selectedRange) {
  9769. return this.composition.setSelectedRange(selectedRange);
  9770. }
  9771. // Attributes
  9772. activateAttribute(name) {
  9773. let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  9774. return this.composition.setCurrentAttribute(name, value);
  9775. }
  9776. attributeIsActive(name) {
  9777. return this.composition.hasCurrentAttribute(name);
  9778. }
  9779. canActivateAttribute(name) {
  9780. return this.composition.canSetCurrentAttribute(name);
  9781. }
  9782. deactivateAttribute(name) {
  9783. return this.composition.removeCurrentAttribute(name);
  9784. }
  9785. // HTML attributes
  9786. setHTMLAtributeAtPosition(position, name, value) {
  9787. this.composition.setHTMLAtributeAtPosition(position, name, value);
  9788. }
  9789. // Nesting level
  9790. canDecreaseNestingLevel() {
  9791. return this.composition.canDecreaseNestingLevel();
  9792. }
  9793. canIncreaseNestingLevel() {
  9794. return this.composition.canIncreaseNestingLevel();
  9795. }
  9796. decreaseNestingLevel() {
  9797. if (this.canDecreaseNestingLevel()) {
  9798. return this.composition.decreaseNestingLevel();
  9799. }
  9800. }
  9801. increaseNestingLevel() {
  9802. if (this.canIncreaseNestingLevel()) {
  9803. return this.composition.increaseNestingLevel();
  9804. }
  9805. }
  9806. // Undo/redo
  9807. canRedo() {
  9808. return this.undoManager.canRedo();
  9809. }
  9810. canUndo() {
  9811. return this.undoManager.canUndo();
  9812. }
  9813. recordUndoEntry(description) {
  9814. let {
  9815. context,
  9816. consolidatable
  9817. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  9818. return this.undoManager.recordUndoEntry(description, {
  9819. context,
  9820. consolidatable
  9821. });
  9822. }
  9823. redo() {
  9824. if (this.canRedo()) {
  9825. return this.undoManager.redo();
  9826. }
  9827. }
  9828. undo() {
  9829. if (this.canUndo()) {
  9830. return this.undoManager.undo();
  9831. }
  9832. }
  9833. }
  9834. /* eslint-disable
  9835. no-var,
  9836. prefer-const,
  9837. */
  9838. class LocationMapper {
  9839. constructor(element) {
  9840. this.element = element;
  9841. }
  9842. findLocationFromContainerAndOffset(container, offset) {
  9843. let {
  9844. strict
  9845. } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
  9846. strict: true
  9847. };
  9848. let childIndex = 0;
  9849. let foundBlock = false;
  9850. const location = {
  9851. index: 0,
  9852. offset: 0
  9853. };
  9854. const attachmentElement = this.findAttachmentElementParentForNode(container);
  9855. if (attachmentElement) {
  9856. container = attachmentElement.parentNode;
  9857. offset = findChildIndexOfNode(attachmentElement);
  9858. }
  9859. const walker = walkTree(this.element, {
  9860. usingFilter: rejectAttachmentContents
  9861. });
  9862. while (walker.nextNode()) {
  9863. const node = walker.currentNode;
  9864. if (node === container && nodeIsTextNode(container)) {
  9865. if (!nodeIsCursorTarget(node)) {
  9866. location.offset += offset;
  9867. }
  9868. break;
  9869. } else {
  9870. if (node.parentNode === container) {
  9871. if (childIndex++ === offset) {
  9872. break;
  9873. }
  9874. } else if (!elementContainsNode(container, node)) {
  9875. if (childIndex > 0) {
  9876. break;
  9877. }
  9878. }
  9879. if (nodeIsBlockStart(node, {
  9880. strict
  9881. })) {
  9882. if (foundBlock) {
  9883. location.index++;
  9884. }
  9885. location.offset = 0;
  9886. foundBlock = true;
  9887. } else {
  9888. location.offset += nodeLength(node);
  9889. }
  9890. }
  9891. }
  9892. return location;
  9893. }
  9894. findContainerAndOffsetFromLocation(location) {
  9895. let container, offset;
  9896. if (location.index === 0 && location.offset === 0) {
  9897. container = this.element;
  9898. offset = 0;
  9899. while (container.firstChild) {
  9900. container = container.firstChild;
  9901. if (nodeIsBlockContainer(container)) {
  9902. offset = 1;
  9903. break;
  9904. }
  9905. }
  9906. return [container, offset];
  9907. }
  9908. let [node, nodeOffset] = this.findNodeAndOffsetFromLocation(location);
  9909. if (!node) return;
  9910. if (nodeIsTextNode(node)) {
  9911. if (nodeLength(node) === 0) {
  9912. container = node.parentNode.parentNode;
  9913. offset = findChildIndexOfNode(node.parentNode);
  9914. if (nodeIsCursorTarget(node, {
  9915. name: "right"
  9916. })) {
  9917. offset++;
  9918. }
  9919. } else {
  9920. container = node;
  9921. offset = location.offset - nodeOffset;
  9922. }
  9923. } else {
  9924. container = node.parentNode;
  9925. if (!nodeIsBlockStart(node.previousSibling)) {
  9926. if (!nodeIsBlockContainer(container)) {
  9927. while (node === container.lastChild) {
  9928. node = container;
  9929. container = container.parentNode;
  9930. if (nodeIsBlockContainer(container)) {
  9931. break;
  9932. }
  9933. }
  9934. }
  9935. }
  9936. offset = findChildIndexOfNode(node);
  9937. if (location.offset !== 0) {
  9938. offset++;
  9939. }
  9940. }
  9941. return [container, offset];
  9942. }
  9943. findNodeAndOffsetFromLocation(location) {
  9944. let node, nodeOffset;
  9945. let offset = 0;
  9946. for (const currentNode of this.getSignificantNodesForIndex(location.index)) {
  9947. const length = nodeLength(currentNode);
  9948. if (location.offset <= offset + length) {
  9949. if (nodeIsTextNode(currentNode)) {
  9950. node = currentNode;
  9951. nodeOffset = offset;
  9952. if (location.offset === nodeOffset && nodeIsCursorTarget(node)) {
  9953. break;
  9954. }
  9955. } else if (!node) {
  9956. node = currentNode;
  9957. nodeOffset = offset;
  9958. }
  9959. }
  9960. offset += length;
  9961. if (offset > location.offset) {
  9962. break;
  9963. }
  9964. }
  9965. return [node, nodeOffset];
  9966. }
  9967. // Private
  9968. findAttachmentElementParentForNode(node) {
  9969. while (node && node !== this.element) {
  9970. if (nodeIsAttachmentElement(node)) {
  9971. return node;
  9972. }
  9973. node = node.parentNode;
  9974. }
  9975. }
  9976. getSignificantNodesForIndex(index) {
  9977. const nodes = [];
  9978. const walker = walkTree(this.element, {
  9979. usingFilter: acceptSignificantNodes
  9980. });
  9981. let recordingNodes = false;
  9982. while (walker.nextNode()) {
  9983. const node = walker.currentNode;
  9984. if (nodeIsBlockStartComment(node)) {
  9985. var blockIndex;
  9986. if (blockIndex != null) {
  9987. blockIndex++;
  9988. } else {
  9989. blockIndex = 0;
  9990. }
  9991. if (blockIndex === index) {
  9992. recordingNodes = true;
  9993. } else if (recordingNodes) {
  9994. break;
  9995. }
  9996. } else if (recordingNodes) {
  9997. nodes.push(node);
  9998. }
  9999. }
  10000. return nodes;
  10001. }
  10002. }
  10003. const nodeLength = function (node) {
  10004. if (node.nodeType === Node.TEXT_NODE) {
  10005. if (nodeIsCursorTarget(node)) {
  10006. return 0;
  10007. } else {
  10008. const string = node.textContent;
  10009. return string.length;
  10010. }
  10011. } else if (tagName(node) === "br" || nodeIsAttachmentElement(node)) {
  10012. return 1;
  10013. } else {
  10014. return 0;
  10015. }
  10016. };
  10017. const acceptSignificantNodes = function (node) {
  10018. if (rejectEmptyTextNodes(node) === NodeFilter.FILTER_ACCEPT) {
  10019. return rejectAttachmentContents(node);
  10020. } else {
  10021. return NodeFilter.FILTER_REJECT;
  10022. }
  10023. };
  10024. const rejectEmptyTextNodes = function (node) {
  10025. if (nodeIsEmptyTextNode(node)) {
  10026. return NodeFilter.FILTER_REJECT;
  10027. } else {
  10028. return NodeFilter.FILTER_ACCEPT;
  10029. }
  10030. };
  10031. const rejectAttachmentContents = function (node) {
  10032. if (nodeIsAttachmentElement(node.parentNode)) {
  10033. return NodeFilter.FILTER_REJECT;
  10034. } else {
  10035. return NodeFilter.FILTER_ACCEPT;
  10036. }
  10037. };
  10038. /* eslint-disable
  10039. id-length,
  10040. no-empty,
  10041. */
  10042. class PointMapper {
  10043. createDOMRangeFromPoint(_ref) {
  10044. let {
  10045. x,
  10046. y
  10047. } = _ref;
  10048. let domRange;
  10049. if (document.caretPositionFromPoint) {
  10050. const {
  10051. offsetNode,
  10052. offset
  10053. } = document.caretPositionFromPoint(x, y);
  10054. domRange = document.createRange();
  10055. domRange.setStart(offsetNode, offset);
  10056. return domRange;
  10057. } else if (document.caretRangeFromPoint) {
  10058. return document.caretRangeFromPoint(x, y);
  10059. } else if (document.body.createTextRange) {
  10060. const originalDOMRange = getDOMRange();
  10061. try {
  10062. // IE 11 throws "Unspecified error" when using moveToPoint
  10063. // during a drag-and-drop operation.
  10064. const textRange = document.body.createTextRange();
  10065. textRange.moveToPoint(x, y);
  10066. textRange.select();
  10067. } catch (error) {}
  10068. domRange = getDOMRange();
  10069. setDOMRange(originalDOMRange);
  10070. return domRange;
  10071. }
  10072. }
  10073. getClientRectsForDOMRange(domRange) {
  10074. const array = Array.from(domRange.getClientRects());
  10075. const start = array[0];
  10076. const end = array[array.length - 1];
  10077. return [start, end];
  10078. }
  10079. }
  10080. /* eslint-disable
  10081. */
  10082. class SelectionManager extends BasicObject {
  10083. constructor(element) {
  10084. super(...arguments);
  10085. this.didMouseDown = this.didMouseDown.bind(this);
  10086. this.selectionDidChange = this.selectionDidChange.bind(this);
  10087. this.element = element;
  10088. this.locationMapper = new LocationMapper(this.element);
  10089. this.pointMapper = new PointMapper();
  10090. this.lockCount = 0;
  10091. handleEvent("mousedown", {
  10092. onElement: this.element,
  10093. withCallback: this.didMouseDown
  10094. });
  10095. }
  10096. getLocationRange() {
  10097. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  10098. if (options.strict === false) {
  10099. return this.createLocationRangeFromDOMRange(getDOMRange());
  10100. } else if (options.ignoreLock) {
  10101. return this.currentLocationRange;
  10102. } else if (this.lockedLocationRange) {
  10103. return this.lockedLocationRange;
  10104. } else {
  10105. return this.currentLocationRange;
  10106. }
  10107. }
  10108. setLocationRange(locationRange) {
  10109. if (this.lockedLocationRange) return;
  10110. locationRange = normalizeRange(locationRange);
  10111. const domRange = this.createDOMRangeFromLocationRange(locationRange);
  10112. if (domRange) {
  10113. setDOMRange(domRange);
  10114. this.updateCurrentLocationRange(locationRange);
  10115. }
  10116. }
  10117. setLocationRangeFromPointRange(pointRange) {
  10118. pointRange = normalizeRange(pointRange);
  10119. const startLocation = this.getLocationAtPoint(pointRange[0]);
  10120. const endLocation = this.getLocationAtPoint(pointRange[1]);
  10121. this.setLocationRange([startLocation, endLocation]);
  10122. }
  10123. getClientRectAtLocationRange(locationRange) {
  10124. const domRange = this.createDOMRangeFromLocationRange(locationRange);
  10125. if (domRange) {
  10126. return this.getClientRectsForDOMRange(domRange)[1];
  10127. }
  10128. }
  10129. locationIsCursorTarget(location) {
  10130. const node = Array.from(this.findNodeAndOffsetFromLocation(location))[0];
  10131. return nodeIsCursorTarget(node);
  10132. }
  10133. lock() {
  10134. if (this.lockCount++ === 0) {
  10135. this.updateCurrentLocationRange();
  10136. this.lockedLocationRange = this.getLocationRange();
  10137. }
  10138. }
  10139. unlock() {
  10140. if (--this.lockCount === 0) {
  10141. const {
  10142. lockedLocationRange
  10143. } = this;
  10144. this.lockedLocationRange = null;
  10145. if (lockedLocationRange != null) {
  10146. return this.setLocationRange(lockedLocationRange);
  10147. }
  10148. }
  10149. }
  10150. clearSelection() {
  10151. var _getDOMSelection;
  10152. return (_getDOMSelection = getDOMSelection()) === null || _getDOMSelection === void 0 ? void 0 : _getDOMSelection.removeAllRanges();
  10153. }
  10154. selectionIsCollapsed() {
  10155. var _getDOMRange;
  10156. return ((_getDOMRange = getDOMRange()) === null || _getDOMRange === void 0 ? void 0 : _getDOMRange.collapsed) === true;
  10157. }
  10158. selectionIsExpanded() {
  10159. return !this.selectionIsCollapsed();
  10160. }
  10161. createLocationRangeFromDOMRange(domRange, options) {
  10162. if (domRange == null || !this.domRangeWithinElement(domRange)) return;
  10163. const start = this.findLocationFromContainerAndOffset(domRange.startContainer, domRange.startOffset, options);
  10164. if (!start) return;
  10165. const end = domRange.collapsed ? undefined : this.findLocationFromContainerAndOffset(domRange.endContainer, domRange.endOffset, options);
  10166. return normalizeRange([start, end]);
  10167. }
  10168. didMouseDown() {
  10169. return this.pauseTemporarily();
  10170. }
  10171. pauseTemporarily() {
  10172. let resumeHandlers;
  10173. this.paused = true;
  10174. const resume = () => {
  10175. this.paused = false;
  10176. clearTimeout(resumeTimeout);
  10177. Array.from(resumeHandlers).forEach(handler => {
  10178. handler.destroy();
  10179. });
  10180. if (elementContainsNode(document, this.element)) {
  10181. return this.selectionDidChange();
  10182. }
  10183. };
  10184. const resumeTimeout = setTimeout(resume, 200);
  10185. resumeHandlers = ["mousemove", "keydown"].map(eventName => handleEvent(eventName, {
  10186. onElement: document,
  10187. withCallback: resume
  10188. }));
  10189. }
  10190. selectionDidChange() {
  10191. if (!this.paused && !innerElementIsActive(this.element)) {
  10192. return this.updateCurrentLocationRange();
  10193. }
  10194. }
  10195. updateCurrentLocationRange(locationRange) {
  10196. if (locationRange != null ? locationRange : locationRange = this.createLocationRangeFromDOMRange(getDOMRange())) {
  10197. if (!rangesAreEqual(locationRange, this.currentLocationRange)) {
  10198. var _this$delegate, _this$delegate$locati;
  10199. this.currentLocationRange = locationRange;
  10200. 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));
  10201. }
  10202. }
  10203. }
  10204. createDOMRangeFromLocationRange(locationRange) {
  10205. const rangeStart = this.findContainerAndOffsetFromLocation(locationRange[0]);
  10206. const rangeEnd = rangeIsCollapsed(locationRange) ? rangeStart : this.findContainerAndOffsetFromLocation(locationRange[1]) || rangeStart;
  10207. if (rangeStart != null && rangeEnd != null) {
  10208. const domRange = document.createRange();
  10209. domRange.setStart(...Array.from(rangeStart || []));
  10210. domRange.setEnd(...Array.from(rangeEnd || []));
  10211. return domRange;
  10212. }
  10213. }
  10214. getLocationAtPoint(point) {
  10215. const domRange = this.createDOMRangeFromPoint(point);
  10216. if (domRange) {
  10217. var _this$createLocationR;
  10218. return (_this$createLocationR = this.createLocationRangeFromDOMRange(domRange)) === null || _this$createLocationR === void 0 ? void 0 : _this$createLocationR[0];
  10219. }
  10220. }
  10221. domRangeWithinElement(domRange) {
  10222. if (domRange.collapsed) {
  10223. return elementContainsNode(this.element, domRange.startContainer);
  10224. } else {
  10225. return elementContainsNode(this.element, domRange.startContainer) && elementContainsNode(this.element, domRange.endContainer);
  10226. }
  10227. }
  10228. }
  10229. SelectionManager.proxyMethod("locationMapper.findLocationFromContainerAndOffset");
  10230. SelectionManager.proxyMethod("locationMapper.findContainerAndOffsetFromLocation");
  10231. SelectionManager.proxyMethod("locationMapper.findNodeAndOffsetFromLocation");
  10232. SelectionManager.proxyMethod("pointMapper.createDOMRangeFromPoint");
  10233. SelectionManager.proxyMethod("pointMapper.getClientRectsForDOMRange");
  10234. var models = /*#__PURE__*/Object.freeze({
  10235. __proto__: null,
  10236. Attachment: Attachment,
  10237. AttachmentManager: AttachmentManager,
  10238. AttachmentPiece: AttachmentPiece,
  10239. Block: Block,
  10240. Composition: Composition,
  10241. Document: Document,
  10242. Editor: Editor,
  10243. HTMLParser: HTMLParser,
  10244. HTMLSanitizer: HTMLSanitizer,
  10245. LineBreakInsertion: LineBreakInsertion,
  10246. LocationMapper: LocationMapper,
  10247. ManagedAttachment: ManagedAttachment,
  10248. Piece: Piece,
  10249. PointMapper: PointMapper,
  10250. SelectionManager: SelectionManager,
  10251. SplittableList: SplittableList,
  10252. StringPiece: StringPiece,
  10253. Text: Text,
  10254. UndoManager: UndoManager
  10255. });
  10256. var views = /*#__PURE__*/Object.freeze({
  10257. __proto__: null,
  10258. ObjectView: ObjectView,
  10259. AttachmentView: AttachmentView,
  10260. BlockView: BlockView,
  10261. DocumentView: DocumentView,
  10262. PieceView: PieceView,
  10263. PreviewableAttachmentView: PreviewableAttachmentView,
  10264. TextView: TextView
  10265. });
  10266. const {
  10267. lang,
  10268. css,
  10269. keyNames: keyNames$1
  10270. } = config;
  10271. const undoable = function (fn) {
  10272. return function () {
  10273. const commands = fn.apply(this, arguments);
  10274. commands.do();
  10275. if (!this.undos) {
  10276. this.undos = [];
  10277. }
  10278. this.undos.push(commands.undo);
  10279. };
  10280. };
  10281. class AttachmentEditorController extends BasicObject {
  10282. constructor(attachmentPiece, _element, container) {
  10283. let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
  10284. super(...arguments);
  10285. // Installing and uninstalling
  10286. _defineProperty(this, "makeElementMutable", undoable(() => {
  10287. return {
  10288. do: () => {
  10289. this.element.dataset.trixMutable = true;
  10290. },
  10291. undo: () => delete this.element.dataset.trixMutable
  10292. };
  10293. }));
  10294. _defineProperty(this, "addToolbar", undoable(() => {
  10295. // <div class="#{css.attachmentMetadataContainer}" data-trix-mutable="true">
  10296. // <div class="trix-button-row">
  10297. // <span class="trix-button-group trix-button-group--actions">
  10298. // <button type="button" class="trix-button trix-button--remove" title="#{lang.remove}" data-trix-action="remove">#{lang.remove}</button>
  10299. // </span>
  10300. // </div>
  10301. // </div>
  10302. const element = makeElement({
  10303. tagName: "div",
  10304. className: css.attachmentToolbar,
  10305. data: {
  10306. trixMutable: true
  10307. },
  10308. childNodes: makeElement({
  10309. tagName: "div",
  10310. className: "trix-button-row",
  10311. childNodes: makeElement({
  10312. tagName: "span",
  10313. className: "trix-button-group trix-button-group--actions",
  10314. childNodes: makeElement({
  10315. tagName: "button",
  10316. className: "trix-button trix-button--remove",
  10317. textContent: lang.remove,
  10318. attributes: {
  10319. title: lang.remove
  10320. },
  10321. data: {
  10322. trixAction: "remove"
  10323. }
  10324. })
  10325. })
  10326. })
  10327. });
  10328. if (this.attachment.isPreviewable()) {
  10329. // <div class="#{css.attachmentMetadataContainer}">
  10330. // <span class="#{css.attachmentMetadata}">
  10331. // <span class="#{css.attachmentName}" title="#{name}">#{name}</span>
  10332. // <span class="#{css.attachmentSize}">#{size}</span>
  10333. // </span>
  10334. // </div>
  10335. element.appendChild(makeElement({
  10336. tagName: "div",
  10337. className: css.attachmentMetadataContainer,
  10338. childNodes: makeElement({
  10339. tagName: "span",
  10340. className: css.attachmentMetadata,
  10341. childNodes: [makeElement({
  10342. tagName: "span",
  10343. className: css.attachmentName,
  10344. textContent: this.attachment.getFilename(),
  10345. attributes: {
  10346. title: this.attachment.getFilename()
  10347. }
  10348. }), makeElement({
  10349. tagName: "span",
  10350. className: css.attachmentSize,
  10351. textContent: this.attachment.getFormattedFilesize()
  10352. })]
  10353. })
  10354. }));
  10355. }
  10356. handleEvent("click", {
  10357. onElement: element,
  10358. withCallback: this.didClickToolbar
  10359. });
  10360. handleEvent("click", {
  10361. onElement: element,
  10362. matchingSelector: "[data-trix-action]",
  10363. withCallback: this.didClickActionButton
  10364. });
  10365. triggerEvent("trix-attachment-before-toolbar", {
  10366. onElement: this.element,
  10367. attributes: {
  10368. toolbar: element,
  10369. attachment: this.attachment
  10370. }
  10371. });
  10372. return {
  10373. do: () => this.element.appendChild(element),
  10374. undo: () => removeNode(element)
  10375. };
  10376. }));
  10377. _defineProperty(this, "installCaptionEditor", undoable(() => {
  10378. const textarea = makeElement({
  10379. tagName: "textarea",
  10380. className: css.attachmentCaptionEditor,
  10381. attributes: {
  10382. placeholder: lang.captionPlaceholder
  10383. },
  10384. data: {
  10385. trixMutable: true
  10386. }
  10387. });
  10388. textarea.value = this.attachmentPiece.getCaption();
  10389. const textareaClone = textarea.cloneNode();
  10390. textareaClone.classList.add("trix-autoresize-clone");
  10391. textareaClone.tabIndex = -1;
  10392. const autoresize = function () {
  10393. textareaClone.value = textarea.value;
  10394. textarea.style.height = textareaClone.scrollHeight + "px";
  10395. };
  10396. handleEvent("input", {
  10397. onElement: textarea,
  10398. withCallback: autoresize
  10399. });
  10400. handleEvent("input", {
  10401. onElement: textarea,
  10402. withCallback: this.didInputCaption
  10403. });
  10404. handleEvent("keydown", {
  10405. onElement: textarea,
  10406. withCallback: this.didKeyDownCaption
  10407. });
  10408. handleEvent("change", {
  10409. onElement: textarea,
  10410. withCallback: this.didChangeCaption
  10411. });
  10412. handleEvent("blur", {
  10413. onElement: textarea,
  10414. withCallback: this.didBlurCaption
  10415. });
  10416. const figcaption = this.element.querySelector("figcaption");
  10417. const editingFigcaption = figcaption.cloneNode();
  10418. return {
  10419. do: () => {
  10420. figcaption.style.display = "none";
  10421. editingFigcaption.appendChild(textarea);
  10422. editingFigcaption.appendChild(textareaClone);
  10423. editingFigcaption.classList.add("".concat(css.attachmentCaption, "--editing"));
  10424. figcaption.parentElement.insertBefore(editingFigcaption, figcaption);
  10425. autoresize();
  10426. if (this.options.editCaption) {
  10427. return defer(() => textarea.focus());
  10428. }
  10429. },
  10430. undo() {
  10431. removeNode(editingFigcaption);
  10432. figcaption.style.display = null;
  10433. }
  10434. };
  10435. }));
  10436. this.didClickToolbar = this.didClickToolbar.bind(this);
  10437. this.didClickActionButton = this.didClickActionButton.bind(this);
  10438. this.didKeyDownCaption = this.didKeyDownCaption.bind(this);
  10439. this.didInputCaption = this.didInputCaption.bind(this);
  10440. this.didChangeCaption = this.didChangeCaption.bind(this);
  10441. this.didBlurCaption = this.didBlurCaption.bind(this);
  10442. this.attachmentPiece = attachmentPiece;
  10443. this.element = _element;
  10444. this.container = container;
  10445. this.options = options;
  10446. this.attachment = this.attachmentPiece.attachment;
  10447. if (tagName(this.element) === "a") {
  10448. this.element = this.element.firstChild;
  10449. }
  10450. this.install();
  10451. }
  10452. install() {
  10453. this.makeElementMutable();
  10454. this.addToolbar();
  10455. if (this.attachment.isPreviewable()) {
  10456. this.installCaptionEditor();
  10457. }
  10458. }
  10459. uninstall() {
  10460. var _this$delegate;
  10461. let undo = this.undos.pop();
  10462. this.savePendingCaption();
  10463. while (undo) {
  10464. undo();
  10465. undo = this.undos.pop();
  10466. }
  10467. (_this$delegate = this.delegate) === null || _this$delegate === void 0 || _this$delegate.didUninstallAttachmentEditor(this);
  10468. }
  10469. // Private
  10470. savePendingCaption() {
  10471. if (this.pendingCaption != null) {
  10472. const caption = this.pendingCaption;
  10473. this.pendingCaption = null;
  10474. if (caption) {
  10475. var _this$delegate2, _this$delegate2$attac;
  10476. (_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, {
  10477. caption
  10478. }, this.attachment);
  10479. } else {
  10480. var _this$delegate3, _this$delegate3$attac;
  10481. (_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);
  10482. }
  10483. }
  10484. }
  10485. // Event handlers
  10486. didClickToolbar(event) {
  10487. event.preventDefault();
  10488. return event.stopPropagation();
  10489. }
  10490. didClickActionButton(event) {
  10491. var _this$delegate4;
  10492. const action = event.target.getAttribute("data-trix-action");
  10493. switch (action) {
  10494. case "remove":
  10495. return (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 ? void 0 : _this$delegate4.attachmentEditorDidRequestRemovalOfAttachment(this.attachment);
  10496. }
  10497. }
  10498. didKeyDownCaption(event) {
  10499. if (keyNames$1[event.keyCode] === "return") {
  10500. var _this$delegate5, _this$delegate5$attac;
  10501. event.preventDefault();
  10502. this.savePendingCaption();
  10503. 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);
  10504. }
  10505. }
  10506. didInputCaption(event) {
  10507. this.pendingCaption = event.target.value.replace(/\s/g, " ").trim();
  10508. }
  10509. didChangeCaption(event) {
  10510. return this.savePendingCaption();
  10511. }
  10512. didBlurCaption(event) {
  10513. return this.savePendingCaption();
  10514. }
  10515. }
  10516. class CompositionController extends BasicObject {
  10517. constructor(element, composition) {
  10518. super(...arguments);
  10519. this.didFocus = this.didFocus.bind(this);
  10520. this.didBlur = this.didBlur.bind(this);
  10521. this.didClickAttachment = this.didClickAttachment.bind(this);
  10522. this.element = element;
  10523. this.composition = composition;
  10524. this.documentView = new DocumentView(this.composition.document, {
  10525. element: this.element
  10526. });
  10527. handleEvent("focus", {
  10528. onElement: this.element,
  10529. withCallback: this.didFocus
  10530. });
  10531. handleEvent("blur", {
  10532. onElement: this.element,
  10533. withCallback: this.didBlur
  10534. });
  10535. handleEvent("click", {
  10536. onElement: this.element,
  10537. matchingSelector: "a[contenteditable=false]",
  10538. preventDefault: true
  10539. });
  10540. handleEvent("mousedown", {
  10541. onElement: this.element,
  10542. matchingSelector: attachmentSelector,
  10543. withCallback: this.didClickAttachment
  10544. });
  10545. handleEvent("click", {
  10546. onElement: this.element,
  10547. matchingSelector: "a".concat(attachmentSelector),
  10548. preventDefault: true
  10549. });
  10550. }
  10551. didFocus(event) {
  10552. var _this$blurPromise;
  10553. const perform = () => {
  10554. if (!this.focused) {
  10555. var _this$delegate, _this$delegate$compos;
  10556. this.focused = true;
  10557. 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);
  10558. }
  10559. };
  10560. return ((_this$blurPromise = this.blurPromise) === null || _this$blurPromise === void 0 ? void 0 : _this$blurPromise.then(perform)) || perform();
  10561. }
  10562. didBlur(event) {
  10563. this.blurPromise = new Promise(resolve => {
  10564. return defer(() => {
  10565. if (!innerElementIsActive(this.element)) {
  10566. var _this$delegate2, _this$delegate2$compo;
  10567. this.focused = null;
  10568. (_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);
  10569. }
  10570. this.blurPromise = null;
  10571. return resolve();
  10572. });
  10573. });
  10574. }
  10575. didClickAttachment(event, target) {
  10576. var _this$delegate3, _this$delegate3$compo;
  10577. const attachment = this.findAttachmentForElement(target);
  10578. const editCaption = !!findClosestElementFromNode(event.target, {
  10579. matchingSelector: "figcaption"
  10580. });
  10581. 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, {
  10582. editCaption
  10583. });
  10584. }
  10585. getSerializableElement() {
  10586. if (this.isEditingAttachment()) {
  10587. return this.documentView.shadowElement;
  10588. } else {
  10589. return this.element;
  10590. }
  10591. }
  10592. render() {
  10593. var _this$delegate6, _this$delegate6$compo;
  10594. if (this.revision !== this.composition.revision) {
  10595. this.documentView.setDocument(this.composition.document);
  10596. this.documentView.render();
  10597. this.revision = this.composition.revision;
  10598. }
  10599. if (this.canSyncDocumentView() && !this.documentView.isSynced()) {
  10600. var _this$delegate4, _this$delegate4$compo, _this$delegate5, _this$delegate5$compo;
  10601. (_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);
  10602. this.documentView.sync();
  10603. (_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);
  10604. }
  10605. 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);
  10606. }
  10607. rerenderViewForObject(object) {
  10608. this.invalidateViewForObject(object);
  10609. return this.render();
  10610. }
  10611. invalidateViewForObject(object) {
  10612. return this.documentView.invalidateViewForObject(object);
  10613. }
  10614. isViewCachingEnabled() {
  10615. return this.documentView.isViewCachingEnabled();
  10616. }
  10617. enableViewCaching() {
  10618. return this.documentView.enableViewCaching();
  10619. }
  10620. disableViewCaching() {
  10621. return this.documentView.disableViewCaching();
  10622. }
  10623. refreshViewCache() {
  10624. return this.documentView.garbageCollectCachedViews();
  10625. }
  10626. // Attachment editor management
  10627. isEditingAttachment() {
  10628. return !!this.attachmentEditor;
  10629. }
  10630. installAttachmentEditorForAttachment(attachment, options) {
  10631. var _this$attachmentEdito;
  10632. if (((_this$attachmentEdito = this.attachmentEditor) === null || _this$attachmentEdito === void 0 ? void 0 : _this$attachmentEdito.attachment) === attachment) return;
  10633. const element = this.documentView.findElementForObject(attachment);
  10634. if (!element) return;
  10635. this.uninstallAttachmentEditor();
  10636. const attachmentPiece = this.composition.document.getAttachmentPieceForAttachment(attachment);
  10637. this.attachmentEditor = new AttachmentEditorController(attachmentPiece, element, this.element, options);
  10638. this.attachmentEditor.delegate = this;
  10639. }
  10640. uninstallAttachmentEditor() {
  10641. var _this$attachmentEdito2;
  10642. return (_this$attachmentEdito2 = this.attachmentEditor) === null || _this$attachmentEdito2 === void 0 ? void 0 : _this$attachmentEdito2.uninstall();
  10643. }
  10644. // Attachment controller delegate
  10645. didUninstallAttachmentEditor() {
  10646. this.attachmentEditor = null;
  10647. return this.render();
  10648. }
  10649. attachmentEditorDidRequestUpdatingAttributesForAttachment(attributes, attachment) {
  10650. var _this$delegate7, _this$delegate7$compo;
  10651. (_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);
  10652. return this.composition.updateAttributesForAttachment(attributes, attachment);
  10653. }
  10654. attachmentEditorDidRequestRemovingAttributeForAttachment(attribute, attachment) {
  10655. var _this$delegate8, _this$delegate8$compo;
  10656. (_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);
  10657. return this.composition.removeAttributeForAttachment(attribute, attachment);
  10658. }
  10659. attachmentEditorDidRequestRemovalOfAttachment(attachment) {
  10660. var _this$delegate9, _this$delegate9$compo;
  10661. 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);
  10662. }
  10663. attachmentEditorDidRequestDeselectingAttachment(attachment) {
  10664. var _this$delegate10, _this$delegate10$comp;
  10665. 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);
  10666. }
  10667. // Private
  10668. canSyncDocumentView() {
  10669. return !this.isEditingAttachment();
  10670. }
  10671. findAttachmentForElement(element) {
  10672. return this.composition.document.getAttachmentById(parseInt(element.dataset.trixId, 10));
  10673. }
  10674. }
  10675. class Controller extends BasicObject {}
  10676. const mutableAttributeName = "data-trix-mutable";
  10677. const mutableSelector = "[".concat(mutableAttributeName, "]");
  10678. const options = {
  10679. attributes: true,
  10680. childList: true,
  10681. characterData: true,
  10682. characterDataOldValue: true,
  10683. subtree: true
  10684. };
  10685. class MutationObserver extends BasicObject {
  10686. constructor(element) {
  10687. super(element);
  10688. this.didMutate = this.didMutate.bind(this);
  10689. this.element = element;
  10690. this.observer = new window.MutationObserver(this.didMutate);
  10691. this.start();
  10692. }
  10693. start() {
  10694. this.reset();
  10695. return this.observer.observe(this.element, options);
  10696. }
  10697. stop() {
  10698. return this.observer.disconnect();
  10699. }
  10700. didMutate(mutations) {
  10701. this.mutations.push(...Array.from(this.findSignificantMutations(mutations) || []));
  10702. if (this.mutations.length) {
  10703. var _this$delegate, _this$delegate$elemen;
  10704. (_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());
  10705. return this.reset();
  10706. }
  10707. }
  10708. // Private
  10709. reset() {
  10710. this.mutations = [];
  10711. }
  10712. findSignificantMutations(mutations) {
  10713. return mutations.filter(mutation => {
  10714. return this.mutationIsSignificant(mutation);
  10715. });
  10716. }
  10717. mutationIsSignificant(mutation) {
  10718. if (this.nodeIsMutable(mutation.target)) {
  10719. return false;
  10720. }
  10721. for (const node of Array.from(this.nodesModifiedByMutation(mutation))) {
  10722. if (this.nodeIsSignificant(node)) return true;
  10723. }
  10724. return false;
  10725. }
  10726. nodeIsSignificant(node) {
  10727. return node !== this.element && !this.nodeIsMutable(node) && !nodeIsEmptyTextNode(node);
  10728. }
  10729. nodeIsMutable(node) {
  10730. return findClosestElementFromNode(node, {
  10731. matchingSelector: mutableSelector
  10732. });
  10733. }
  10734. nodesModifiedByMutation(mutation) {
  10735. const nodes = [];
  10736. switch (mutation.type) {
  10737. case "attributes":
  10738. if (mutation.attributeName !== mutableAttributeName) {
  10739. nodes.push(mutation.target);
  10740. }
  10741. break;
  10742. case "characterData":
  10743. // Changes to text nodes should consider the parent element
  10744. nodes.push(mutation.target.parentNode);
  10745. nodes.push(mutation.target);
  10746. break;
  10747. case "childList":
  10748. // Consider each added or removed node
  10749. nodes.push(...Array.from(mutation.addedNodes || []));
  10750. nodes.push(...Array.from(mutation.removedNodes || []));
  10751. break;
  10752. }
  10753. return nodes;
  10754. }
  10755. getMutationSummary() {
  10756. return this.getTextMutationSummary();
  10757. }
  10758. getTextMutationSummary() {
  10759. const {
  10760. additions,
  10761. deletions
  10762. } = this.getTextChangesFromCharacterData();
  10763. const textChanges = this.getTextChangesFromChildList();
  10764. Array.from(textChanges.additions).forEach(addition => {
  10765. if (!Array.from(additions).includes(addition)) {
  10766. additions.push(addition);
  10767. }
  10768. });
  10769. deletions.push(...Array.from(textChanges.deletions || []));
  10770. const summary = {};
  10771. const added = additions.join("");
  10772. if (added) {
  10773. summary.textAdded = added;
  10774. }
  10775. const deleted = deletions.join("");
  10776. if (deleted) {
  10777. summary.textDeleted = deleted;
  10778. }
  10779. return summary;
  10780. }
  10781. getMutationsByType(type) {
  10782. return Array.from(this.mutations).filter(mutation => mutation.type === type);
  10783. }
  10784. getTextChangesFromChildList() {
  10785. let textAdded, textRemoved;
  10786. const addedNodes = [];
  10787. const removedNodes = [];
  10788. Array.from(this.getMutationsByType("childList")).forEach(mutation => {
  10789. addedNodes.push(...Array.from(mutation.addedNodes || []));
  10790. removedNodes.push(...Array.from(mutation.removedNodes || []));
  10791. });
  10792. const singleBlockCommentRemoved = addedNodes.length === 0 && removedNodes.length === 1 && nodeIsBlockStartComment(removedNodes[0]);
  10793. if (singleBlockCommentRemoved) {
  10794. textAdded = [];
  10795. textRemoved = ["\n"];
  10796. } else {
  10797. textAdded = getTextForNodes(addedNodes);
  10798. textRemoved = getTextForNodes(removedNodes);
  10799. }
  10800. const additions = textAdded.filter((text, index) => text !== textRemoved[index]).map(normalizeSpaces);
  10801. const deletions = textRemoved.filter((text, index) => text !== textAdded[index]).map(normalizeSpaces);
  10802. return {
  10803. additions,
  10804. deletions
  10805. };
  10806. }
  10807. getTextChangesFromCharacterData() {
  10808. let added, removed;
  10809. const characterMutations = this.getMutationsByType("characterData");
  10810. if (characterMutations.length) {
  10811. const startMutation = characterMutations[0],
  10812. endMutation = characterMutations[characterMutations.length - 1];
  10813. const oldString = normalizeSpaces(startMutation.oldValue);
  10814. const newString = normalizeSpaces(endMutation.target.data);
  10815. const summarized = summarizeStringChange(oldString, newString);
  10816. added = summarized.added;
  10817. removed = summarized.removed;
  10818. }
  10819. return {
  10820. additions: added ? [added] : [],
  10821. deletions: removed ? [removed] : []
  10822. };
  10823. }
  10824. }
  10825. const getTextForNodes = function () {
  10826. let nodes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  10827. const text = [];
  10828. for (const node of Array.from(nodes)) {
  10829. switch (node.nodeType) {
  10830. case Node.TEXT_NODE:
  10831. text.push(node.data);
  10832. break;
  10833. case Node.ELEMENT_NODE:
  10834. if (tagName(node) === "br") {
  10835. text.push("\n");
  10836. } else {
  10837. text.push(...Array.from(getTextForNodes(node.childNodes) || []));
  10838. }
  10839. break;
  10840. }
  10841. }
  10842. return text;
  10843. };
  10844. /* eslint-disable
  10845. no-empty,
  10846. */
  10847. class FileVerificationOperation extends Operation {
  10848. constructor(file) {
  10849. super(...arguments);
  10850. this.file = file;
  10851. }
  10852. perform(callback) {
  10853. const reader = new FileReader();
  10854. reader.onerror = () => callback(false);
  10855. reader.onload = () => {
  10856. reader.onerror = null;
  10857. try {
  10858. reader.abort();
  10859. } catch (error) {}
  10860. return callback(true, this.file);
  10861. };
  10862. return reader.readAsArrayBuffer(this.file);
  10863. }
  10864. }
  10865. // Each software keyboard on Android emits its own set of events and some of them can be buggy.
  10866. // This class detects when some buggy events are being emitted and lets know the input controller
  10867. // that they should be ignored.
  10868. class FlakyAndroidKeyboardDetector {
  10869. constructor(element) {
  10870. this.element = element;
  10871. }
  10872. shouldIgnore(event) {
  10873. if (!browser$1.samsungAndroid) return false;
  10874. this.previousEvent = this.event;
  10875. this.event = event;
  10876. this.checkSamsungKeyboardBuggyModeStart();
  10877. this.checkSamsungKeyboardBuggyModeEnd();
  10878. return this.buggyMode;
  10879. }
  10880. // private
  10881. // The Samsung keyboard on Android can enter a buggy state in which it emits a flurry of confused events that,
  10882. // if processed, corrupts the editor. The buggy mode always starts with an insertText event, right after a
  10883. // keydown event with for an "Unidentified" key, with the same text as the editor element, except for a few
  10884. // extra whitespace, or exotic utf8, characters.
  10885. checkSamsungKeyboardBuggyModeStart() {
  10886. if (this.insertingLongTextAfterUnidentifiedChar() && differsInWhitespace(this.element.innerText, this.event.data)) {
  10887. this.buggyMode = true;
  10888. this.event.preventDefault();
  10889. }
  10890. }
  10891. // The flurry of buggy events are always insertText. If we see any other type, it means it's over.
  10892. checkSamsungKeyboardBuggyModeEnd() {
  10893. if (this.buggyMode && this.event.inputType !== "insertText") {
  10894. this.buggyMode = false;
  10895. }
  10896. }
  10897. insertingLongTextAfterUnidentifiedChar() {
  10898. var _this$event$data;
  10899. return this.isBeforeInputInsertText() && this.previousEventWasUnidentifiedKeydown() && ((_this$event$data = this.event.data) === null || _this$event$data === void 0 ? void 0 : _this$event$data.length) > 50;
  10900. }
  10901. isBeforeInputInsertText() {
  10902. return this.event.type === "beforeinput" && this.event.inputType === "insertText";
  10903. }
  10904. previousEventWasUnidentifiedKeydown() {
  10905. var _this$previousEvent, _this$previousEvent2;
  10906. 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";
  10907. }
  10908. }
  10909. const differsInWhitespace = (text1, text2) => {
  10910. return normalize(text1) === normalize(text2);
  10911. };
  10912. const whiteSpaceNormalizerRegexp = new RegExp("(".concat(OBJECT_REPLACEMENT_CHARACTER, "|").concat(ZERO_WIDTH_SPACE, "|").concat(NON_BREAKING_SPACE, "|\\s)+"), "g");
  10913. const normalize = text => text.replace(whiteSpaceNormalizerRegexp, " ").trim();
  10914. class InputController extends BasicObject {
  10915. constructor(element) {
  10916. super(...arguments);
  10917. this.element = element;
  10918. this.mutationObserver = new MutationObserver(this.element);
  10919. this.mutationObserver.delegate = this;
  10920. this.flakyKeyboardDetector = new FlakyAndroidKeyboardDetector(this.element);
  10921. for (const eventName in this.constructor.events) {
  10922. handleEvent(eventName, {
  10923. onElement: this.element,
  10924. withCallback: this.handlerFor(eventName)
  10925. });
  10926. }
  10927. }
  10928. elementDidMutate(mutationSummary) {}
  10929. editorWillSyncDocumentView() {
  10930. return this.mutationObserver.stop();
  10931. }
  10932. editorDidSyncDocumentView() {
  10933. return this.mutationObserver.start();
  10934. }
  10935. requestRender() {
  10936. var _this$delegate, _this$delegate$inputC;
  10937. 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);
  10938. }
  10939. requestReparse() {
  10940. var _this$delegate2, _this$delegate2$input;
  10941. (_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);
  10942. return this.requestRender();
  10943. }
  10944. attachFiles(files) {
  10945. const operations = Array.from(files).map(file => new FileVerificationOperation(file));
  10946. return Promise.all(operations).then(files => {
  10947. this.handleInput(function () {
  10948. var _this$delegate3, _this$responder;
  10949. (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || _this$delegate3.inputControllerWillAttachFiles();
  10950. (_this$responder = this.responder) === null || _this$responder === void 0 || _this$responder.insertFiles(files);
  10951. return this.requestRender();
  10952. });
  10953. });
  10954. }
  10955. // Private
  10956. handlerFor(eventName) {
  10957. return event => {
  10958. if (!event.defaultPrevented) {
  10959. this.handleInput(() => {
  10960. if (!innerElementIsActive(this.element)) {
  10961. if (this.flakyKeyboardDetector.shouldIgnore(event)) return;
  10962. this.eventName = eventName;
  10963. this.constructor.events[eventName].call(this, event);
  10964. }
  10965. });
  10966. }
  10967. };
  10968. }
  10969. handleInput(callback) {
  10970. try {
  10971. var _this$delegate4;
  10972. (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillHandleInput();
  10973. callback.call(this);
  10974. } finally {
  10975. var _this$delegate5;
  10976. (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.inputControllerDidHandleInput();
  10977. }
  10978. }
  10979. createLinkHTML(href, text) {
  10980. const link = document.createElement("a");
  10981. link.href = href;
  10982. link.textContent = text ? text : href;
  10983. return link.outerHTML;
  10984. }
  10985. }
  10986. _defineProperty(InputController, "events", {});
  10987. var _$codePointAt, _;
  10988. const {
  10989. browser,
  10990. keyNames
  10991. } = config;
  10992. let pastedFileCount = 0;
  10993. class Level0InputController extends InputController {
  10994. constructor() {
  10995. super(...arguments);
  10996. this.resetInputSummary();
  10997. }
  10998. setInputSummary() {
  10999. let summary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  11000. this.inputSummary.eventName = this.eventName;
  11001. for (const key in summary) {
  11002. const value = summary[key];
  11003. this.inputSummary[key] = value;
  11004. }
  11005. return this.inputSummary;
  11006. }
  11007. resetInputSummary() {
  11008. this.inputSummary = {};
  11009. }
  11010. reset() {
  11011. this.resetInputSummary();
  11012. return selectionChangeObserver.reset();
  11013. }
  11014. // Mutation observer delegate
  11015. elementDidMutate(mutationSummary) {
  11016. if (this.isComposing()) {
  11017. var _this$delegate, _this$delegate$inputC;
  11018. 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);
  11019. } else {
  11020. return this.handleInput(function () {
  11021. if (this.mutationIsSignificant(mutationSummary)) {
  11022. if (this.mutationIsExpected(mutationSummary)) {
  11023. this.requestRender();
  11024. } else {
  11025. this.requestReparse();
  11026. }
  11027. }
  11028. return this.reset();
  11029. });
  11030. }
  11031. }
  11032. mutationIsExpected(_ref) {
  11033. let {
  11034. textAdded,
  11035. textDeleted
  11036. } = _ref;
  11037. if (this.inputSummary.preferDocument) {
  11038. return true;
  11039. }
  11040. const mutationAdditionMatchesSummary = textAdded != null ? textAdded === this.inputSummary.textAdded : !this.inputSummary.textAdded;
  11041. const mutationDeletionMatchesSummary = textDeleted != null ? this.inputSummary.didDelete : !this.inputSummary.didDelete;
  11042. const unexpectedNewlineAddition = ["\n", " \n"].includes(textAdded) && !mutationAdditionMatchesSummary;
  11043. const unexpectedNewlineDeletion = textDeleted === "\n" && !mutationDeletionMatchesSummary;
  11044. const singleUnexpectedNewline = unexpectedNewlineAddition && !unexpectedNewlineDeletion || unexpectedNewlineDeletion && !unexpectedNewlineAddition;
  11045. if (singleUnexpectedNewline) {
  11046. const range = this.getSelectedRange();
  11047. if (range) {
  11048. var _this$responder;
  11049. const offset = unexpectedNewlineAddition ? textAdded.replace(/\n$/, "").length || -1 : (textAdded === null || textAdded === void 0 ? void 0 : textAdded.length) || 1;
  11050. if ((_this$responder = this.responder) !== null && _this$responder !== void 0 && _this$responder.positionIsBlockBreak(range[1] + offset)) {
  11051. return true;
  11052. }
  11053. }
  11054. }
  11055. return mutationAdditionMatchesSummary && mutationDeletionMatchesSummary;
  11056. }
  11057. mutationIsSignificant(mutationSummary) {
  11058. var _this$compositionInpu;
  11059. const textChanged = Object.keys(mutationSummary).length > 0;
  11060. const composedEmptyString = ((_this$compositionInpu = this.compositionInput) === null || _this$compositionInpu === void 0 ? void 0 : _this$compositionInpu.getEndData()) === "";
  11061. return textChanged || !composedEmptyString;
  11062. }
  11063. // Private
  11064. getCompositionInput() {
  11065. if (this.isComposing()) {
  11066. return this.compositionInput;
  11067. } else {
  11068. this.compositionInput = new CompositionInput(this);
  11069. }
  11070. }
  11071. isComposing() {
  11072. return this.compositionInput && !this.compositionInput.isEnded();
  11073. }
  11074. deleteInDirection(direction, event) {
  11075. var _this$responder2;
  11076. if (((_this$responder2 = this.responder) === null || _this$responder2 === void 0 ? void 0 : _this$responder2.deleteInDirection(direction)) === false) {
  11077. if (event) {
  11078. event.preventDefault();
  11079. return this.requestRender();
  11080. }
  11081. } else {
  11082. return this.setInputSummary({
  11083. didDelete: true
  11084. });
  11085. }
  11086. }
  11087. serializeSelectionToDataTransfer(dataTransfer) {
  11088. var _this$responder3;
  11089. if (!dataTransferIsWritable(dataTransfer)) return;
  11090. const document = (_this$responder3 = this.responder) === null || _this$responder3 === void 0 ? void 0 : _this$responder3.getSelectedDocument().toSerializableDocument();
  11091. dataTransfer.setData("application/x-trix-document", JSON.stringify(document));
  11092. dataTransfer.setData("text/html", DocumentView.render(document).innerHTML);
  11093. dataTransfer.setData("text/plain", document.toString().replace(/\n$/, ""));
  11094. return true;
  11095. }
  11096. canAcceptDataTransfer(dataTransfer) {
  11097. const types = {};
  11098. Array.from((dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.types) || []).forEach(type => {
  11099. types[type] = true;
  11100. });
  11101. return types.Files || types["application/x-trix-document"] || types["text/html"] || types["text/plain"];
  11102. }
  11103. getPastedHTMLUsingHiddenElement(callback) {
  11104. const selectedRange = this.getSelectedRange();
  11105. const style = {
  11106. position: "absolute",
  11107. left: "".concat(window.pageXOffset, "px"),
  11108. top: "".concat(window.pageYOffset, "px"),
  11109. opacity: 0
  11110. };
  11111. const element = makeElement({
  11112. style,
  11113. tagName: "div",
  11114. editable: true
  11115. });
  11116. document.body.appendChild(element);
  11117. element.focus();
  11118. return requestAnimationFrame(() => {
  11119. const html = element.innerHTML;
  11120. removeNode(element);
  11121. this.setSelectedRange(selectedRange);
  11122. return callback(html);
  11123. });
  11124. }
  11125. }
  11126. _defineProperty(Level0InputController, "events", {
  11127. keydown(event) {
  11128. if (!this.isComposing()) {
  11129. this.resetInputSummary();
  11130. }
  11131. this.inputSummary.didInput = true;
  11132. const keyName = keyNames[event.keyCode];
  11133. if (keyName) {
  11134. var _context2;
  11135. let context = this.keys;
  11136. ["ctrl", "alt", "shift", "meta"].forEach(modifier => {
  11137. if (event["".concat(modifier, "Key")]) {
  11138. var _context;
  11139. if (modifier === "ctrl") {
  11140. modifier = "control";
  11141. }
  11142. context = (_context = context) === null || _context === void 0 ? void 0 : _context[modifier];
  11143. }
  11144. });
  11145. if (((_context2 = context) === null || _context2 === void 0 ? void 0 : _context2[keyName]) != null) {
  11146. this.setInputSummary({
  11147. keyName
  11148. });
  11149. selectionChangeObserver.reset();
  11150. context[keyName].call(this, event);
  11151. }
  11152. }
  11153. if (keyEventIsKeyboardCommand(event)) {
  11154. const character = String.fromCharCode(event.keyCode).toLowerCase();
  11155. if (character) {
  11156. var _this$delegate3;
  11157. const keys = ["alt", "shift"].map(modifier => {
  11158. if (event["".concat(modifier, "Key")]) {
  11159. return modifier;
  11160. }
  11161. }).filter(key => key);
  11162. keys.push(character);
  11163. if ((_this$delegate3 = this.delegate) !== null && _this$delegate3 !== void 0 && _this$delegate3.inputControllerDidReceiveKeyboardCommand(keys)) {
  11164. event.preventDefault();
  11165. }
  11166. }
  11167. }
  11168. },
  11169. keypress(event) {
  11170. if (this.inputSummary.eventName != null) return;
  11171. if (event.metaKey) return;
  11172. if (event.ctrlKey && !event.altKey) return;
  11173. const string = stringFromKeyEvent(event);
  11174. if (string) {
  11175. var _this$delegate4, _this$responder9;
  11176. (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillPerformTyping();
  11177. (_this$responder9 = this.responder) === null || _this$responder9 === void 0 || _this$responder9.insertString(string);
  11178. return this.setInputSummary({
  11179. textAdded: string,
  11180. didDelete: this.selectionIsExpanded()
  11181. });
  11182. }
  11183. },
  11184. textInput(event) {
  11185. // Handle autocapitalization
  11186. const {
  11187. data
  11188. } = event;
  11189. const {
  11190. textAdded
  11191. } = this.inputSummary;
  11192. if (textAdded && textAdded !== data && textAdded.toUpperCase() === data) {
  11193. var _this$responder10;
  11194. const range = this.getSelectedRange();
  11195. this.setSelectedRange([range[0], range[1] + textAdded.length]);
  11196. (_this$responder10 = this.responder) === null || _this$responder10 === void 0 || _this$responder10.insertString(data);
  11197. this.setInputSummary({
  11198. textAdded: data
  11199. });
  11200. return this.setSelectedRange(range);
  11201. }
  11202. },
  11203. dragenter(event) {
  11204. event.preventDefault();
  11205. },
  11206. dragstart(event) {
  11207. var _this$delegate5, _this$delegate5$input;
  11208. this.serializeSelectionToDataTransfer(event.dataTransfer);
  11209. this.draggedRange = this.getSelectedRange();
  11210. 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);
  11211. },
  11212. dragover(event) {
  11213. if (this.draggedRange || this.canAcceptDataTransfer(event.dataTransfer)) {
  11214. event.preventDefault();
  11215. const draggingPoint = {
  11216. x: event.clientX,
  11217. y: event.clientY
  11218. };
  11219. if (!objectsAreEqual(draggingPoint, this.draggingPoint)) {
  11220. var _this$delegate6, _this$delegate6$input;
  11221. this.draggingPoint = draggingPoint;
  11222. 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);
  11223. }
  11224. }
  11225. },
  11226. dragend(event) {
  11227. var _this$delegate7, _this$delegate7$input;
  11228. (_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);
  11229. this.draggedRange = null;
  11230. this.draggingPoint = null;
  11231. },
  11232. drop(event) {
  11233. var _event$dataTransfer, _this$responder11;
  11234. event.preventDefault();
  11235. const files = (_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.files;
  11236. const documentJSON = event.dataTransfer.getData("application/x-trix-document");
  11237. const point = {
  11238. x: event.clientX,
  11239. y: event.clientY
  11240. };
  11241. (_this$responder11 = this.responder) === null || _this$responder11 === void 0 || _this$responder11.setLocationRangeFromPointRange(point);
  11242. if (files !== null && files !== void 0 && files.length) {
  11243. this.attachFiles(files);
  11244. } else if (this.draggedRange) {
  11245. var _this$delegate8, _this$responder12;
  11246. (_this$delegate8 = this.delegate) === null || _this$delegate8 === void 0 || _this$delegate8.inputControllerWillMoveText();
  11247. (_this$responder12 = this.responder) === null || _this$responder12 === void 0 || _this$responder12.moveTextFromRange(this.draggedRange);
  11248. this.draggedRange = null;
  11249. this.requestRender();
  11250. } else if (documentJSON) {
  11251. var _this$responder13;
  11252. const document = Document.fromJSONString(documentJSON);
  11253. (_this$responder13 = this.responder) === null || _this$responder13 === void 0 || _this$responder13.insertDocument(document);
  11254. this.requestRender();
  11255. }
  11256. this.draggedRange = null;
  11257. this.draggingPoint = null;
  11258. },
  11259. cut(event) {
  11260. var _this$responder14;
  11261. if ((_this$responder14 = this.responder) !== null && _this$responder14 !== void 0 && _this$responder14.selectionIsExpanded()) {
  11262. var _this$delegate9;
  11263. if (this.serializeSelectionToDataTransfer(event.clipboardData)) {
  11264. event.preventDefault();
  11265. }
  11266. (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 || _this$delegate9.inputControllerWillCutText();
  11267. this.deleteInDirection("backward");
  11268. if (event.defaultPrevented) {
  11269. return this.requestRender();
  11270. }
  11271. }
  11272. },
  11273. copy(event) {
  11274. var _this$responder15;
  11275. if ((_this$responder15 = this.responder) !== null && _this$responder15 !== void 0 && _this$responder15.selectionIsExpanded()) {
  11276. if (this.serializeSelectionToDataTransfer(event.clipboardData)) {
  11277. event.preventDefault();
  11278. }
  11279. }
  11280. },
  11281. paste(event) {
  11282. const clipboard = event.clipboardData || event.testClipboardData;
  11283. const paste = {
  11284. clipboard
  11285. };
  11286. if (!clipboard || pasteEventIsCrippledSafariHTMLPaste(event)) {
  11287. this.getPastedHTMLUsingHiddenElement(html => {
  11288. var _this$delegate10, _this$responder16, _this$delegate11;
  11289. paste.type = "text/html";
  11290. paste.html = html;
  11291. (_this$delegate10 = this.delegate) === null || _this$delegate10 === void 0 || _this$delegate10.inputControllerWillPaste(paste);
  11292. (_this$responder16 = this.responder) === null || _this$responder16 === void 0 || _this$responder16.insertHTML(paste.html);
  11293. this.requestRender();
  11294. return (_this$delegate11 = this.delegate) === null || _this$delegate11 === void 0 ? void 0 : _this$delegate11.inputControllerDidPaste(paste);
  11295. });
  11296. return;
  11297. }
  11298. const href = clipboard.getData("URL");
  11299. const html = clipboard.getData("text/html");
  11300. const name = clipboard.getData("public.url-name");
  11301. if (href) {
  11302. var _this$delegate12, _this$responder17, _this$delegate13;
  11303. let string;
  11304. paste.type = "text/html";
  11305. if (name) {
  11306. string = squishBreakableWhitespace(name).trim();
  11307. } else {
  11308. string = href;
  11309. }
  11310. paste.html = this.createLinkHTML(href, string);
  11311. (_this$delegate12 = this.delegate) === null || _this$delegate12 === void 0 || _this$delegate12.inputControllerWillPaste(paste);
  11312. this.setInputSummary({
  11313. textAdded: string,
  11314. didDelete: this.selectionIsExpanded()
  11315. });
  11316. (_this$responder17 = this.responder) === null || _this$responder17 === void 0 || _this$responder17.insertHTML(paste.html);
  11317. this.requestRender();
  11318. (_this$delegate13 = this.delegate) === null || _this$delegate13 === void 0 || _this$delegate13.inputControllerDidPaste(paste);
  11319. } else if (dataTransferIsPlainText(clipboard)) {
  11320. var _this$delegate14, _this$responder18, _this$delegate15;
  11321. paste.type = "text/plain";
  11322. paste.string = clipboard.getData("text/plain");
  11323. (_this$delegate14 = this.delegate) === null || _this$delegate14 === void 0 || _this$delegate14.inputControllerWillPaste(paste);
  11324. this.setInputSummary({
  11325. textAdded: paste.string,
  11326. didDelete: this.selectionIsExpanded()
  11327. });
  11328. (_this$responder18 = this.responder) === null || _this$responder18 === void 0 || _this$responder18.insertString(paste.string);
  11329. this.requestRender();
  11330. (_this$delegate15 = this.delegate) === null || _this$delegate15 === void 0 || _this$delegate15.inputControllerDidPaste(paste);
  11331. } else if (html) {
  11332. var _this$delegate16, _this$responder19, _this$delegate17;
  11333. paste.type = "text/html";
  11334. paste.html = html;
  11335. (_this$delegate16 = this.delegate) === null || _this$delegate16 === void 0 || _this$delegate16.inputControllerWillPaste(paste);
  11336. (_this$responder19 = this.responder) === null || _this$responder19 === void 0 || _this$responder19.insertHTML(paste.html);
  11337. this.requestRender();
  11338. (_this$delegate17 = this.delegate) === null || _this$delegate17 === void 0 || _this$delegate17.inputControllerDidPaste(paste);
  11339. } else if (Array.from(clipboard.types).includes("Files")) {
  11340. var _clipboard$items, _clipboard$items$getA;
  11341. 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);
  11342. if (file) {
  11343. var _this$delegate18, _this$responder20, _this$delegate19;
  11344. const extension = extensionForFile(file);
  11345. if (!file.name && extension) {
  11346. file.name = "pasted-file-".concat(++pastedFileCount, ".").concat(extension);
  11347. }
  11348. paste.type = "File";
  11349. paste.file = file;
  11350. (_this$delegate18 = this.delegate) === null || _this$delegate18 === void 0 || _this$delegate18.inputControllerWillAttachFiles();
  11351. (_this$responder20 = this.responder) === null || _this$responder20 === void 0 || _this$responder20.insertFile(paste.file);
  11352. this.requestRender();
  11353. (_this$delegate19 = this.delegate) === null || _this$delegate19 === void 0 || _this$delegate19.inputControllerDidPaste(paste);
  11354. }
  11355. }
  11356. event.preventDefault();
  11357. },
  11358. compositionstart(event) {
  11359. return this.getCompositionInput().start(event.data);
  11360. },
  11361. compositionupdate(event) {
  11362. return this.getCompositionInput().update(event.data);
  11363. },
  11364. compositionend(event) {
  11365. return this.getCompositionInput().end(event.data);
  11366. },
  11367. beforeinput(event) {
  11368. this.inputSummary.didInput = true;
  11369. },
  11370. input(event) {
  11371. this.inputSummary.didInput = true;
  11372. return event.stopPropagation();
  11373. }
  11374. });
  11375. _defineProperty(Level0InputController, "keys", {
  11376. backspace(event) {
  11377. var _this$delegate20;
  11378. (_this$delegate20 = this.delegate) === null || _this$delegate20 === void 0 || _this$delegate20.inputControllerWillPerformTyping();
  11379. return this.deleteInDirection("backward", event);
  11380. },
  11381. delete(event) {
  11382. var _this$delegate21;
  11383. (_this$delegate21 = this.delegate) === null || _this$delegate21 === void 0 || _this$delegate21.inputControllerWillPerformTyping();
  11384. return this.deleteInDirection("forward", event);
  11385. },
  11386. return(event) {
  11387. var _this$delegate22, _this$responder21;
  11388. this.setInputSummary({
  11389. preferDocument: true
  11390. });
  11391. (_this$delegate22 = this.delegate) === null || _this$delegate22 === void 0 || _this$delegate22.inputControllerWillPerformTyping();
  11392. return (_this$responder21 = this.responder) === null || _this$responder21 === void 0 ? void 0 : _this$responder21.insertLineBreak();
  11393. },
  11394. tab(event) {
  11395. var _this$responder22;
  11396. if ((_this$responder22 = this.responder) !== null && _this$responder22 !== void 0 && _this$responder22.canIncreaseNestingLevel()) {
  11397. var _this$responder23;
  11398. (_this$responder23 = this.responder) === null || _this$responder23 === void 0 || _this$responder23.increaseNestingLevel();
  11399. this.requestRender();
  11400. event.preventDefault();
  11401. }
  11402. },
  11403. left(event) {
  11404. if (this.selectionIsInCursorTarget()) {
  11405. var _this$responder24;
  11406. event.preventDefault();
  11407. return (_this$responder24 = this.responder) === null || _this$responder24 === void 0 ? void 0 : _this$responder24.moveCursorInDirection("backward");
  11408. }
  11409. },
  11410. right(event) {
  11411. if (this.selectionIsInCursorTarget()) {
  11412. var _this$responder25;
  11413. event.preventDefault();
  11414. return (_this$responder25 = this.responder) === null || _this$responder25 === void 0 ? void 0 : _this$responder25.moveCursorInDirection("forward");
  11415. }
  11416. },
  11417. control: {
  11418. d(event) {
  11419. var _this$delegate23;
  11420. (_this$delegate23 = this.delegate) === null || _this$delegate23 === void 0 || _this$delegate23.inputControllerWillPerformTyping();
  11421. return this.deleteInDirection("forward", event);
  11422. },
  11423. h(event) {
  11424. var _this$delegate24;
  11425. (_this$delegate24 = this.delegate) === null || _this$delegate24 === void 0 || _this$delegate24.inputControllerWillPerformTyping();
  11426. return this.deleteInDirection("backward", event);
  11427. },
  11428. o(event) {
  11429. var _this$delegate25, _this$responder26;
  11430. event.preventDefault();
  11431. (_this$delegate25 = this.delegate) === null || _this$delegate25 === void 0 || _this$delegate25.inputControllerWillPerformTyping();
  11432. (_this$responder26 = this.responder) === null || _this$responder26 === void 0 || _this$responder26.insertString("\n", {
  11433. updatePosition: false
  11434. });
  11435. return this.requestRender();
  11436. }
  11437. },
  11438. shift: {
  11439. return(event) {
  11440. var _this$delegate26, _this$responder27;
  11441. (_this$delegate26 = this.delegate) === null || _this$delegate26 === void 0 || _this$delegate26.inputControllerWillPerformTyping();
  11442. (_this$responder27 = this.responder) === null || _this$responder27 === void 0 || _this$responder27.insertString("\n");
  11443. this.requestRender();
  11444. event.preventDefault();
  11445. },
  11446. tab(event) {
  11447. var _this$responder28;
  11448. if ((_this$responder28 = this.responder) !== null && _this$responder28 !== void 0 && _this$responder28.canDecreaseNestingLevel()) {
  11449. var _this$responder29;
  11450. (_this$responder29 = this.responder) === null || _this$responder29 === void 0 || _this$responder29.decreaseNestingLevel();
  11451. this.requestRender();
  11452. event.preventDefault();
  11453. }
  11454. },
  11455. left(event) {
  11456. if (this.selectionIsInCursorTarget()) {
  11457. event.preventDefault();
  11458. return this.expandSelectionInDirection("backward");
  11459. }
  11460. },
  11461. right(event) {
  11462. if (this.selectionIsInCursorTarget()) {
  11463. event.preventDefault();
  11464. return this.expandSelectionInDirection("forward");
  11465. }
  11466. }
  11467. },
  11468. alt: {
  11469. backspace(event) {
  11470. var _this$delegate27;
  11471. this.setInputSummary({
  11472. preferDocument: false
  11473. });
  11474. return (_this$delegate27 = this.delegate) === null || _this$delegate27 === void 0 ? void 0 : _this$delegate27.inputControllerWillPerformTyping();
  11475. }
  11476. },
  11477. meta: {
  11478. backspace(event) {
  11479. var _this$delegate28;
  11480. this.setInputSummary({
  11481. preferDocument: false
  11482. });
  11483. return (_this$delegate28 = this.delegate) === null || _this$delegate28 === void 0 ? void 0 : _this$delegate28.inputControllerWillPerformTyping();
  11484. }
  11485. }
  11486. });
  11487. Level0InputController.proxyMethod("responder?.getSelectedRange");
  11488. Level0InputController.proxyMethod("responder?.setSelectedRange");
  11489. Level0InputController.proxyMethod("responder?.expandSelectionInDirection");
  11490. Level0InputController.proxyMethod("responder?.selectionIsInCursorTarget");
  11491. Level0InputController.proxyMethod("responder?.selectionIsExpanded");
  11492. const extensionForFile = file => {
  11493. var _file$type;
  11494. 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];
  11495. };
  11496. const hasStringCodePointAt = !!((_$codePointAt = (_ = " ").codePointAt) !== null && _$codePointAt !== void 0 && _$codePointAt.call(_, 0));
  11497. const stringFromKeyEvent = function (event) {
  11498. if (event.key && hasStringCodePointAt && event.key.codePointAt(0) === event.keyCode) {
  11499. return event.key;
  11500. } else {
  11501. let code;
  11502. if (event.which === null) {
  11503. code = event.keyCode;
  11504. } else if (event.which !== 0 && event.charCode !== 0) {
  11505. code = event.charCode;
  11506. }
  11507. if (code != null && keyNames[code] !== "escape") {
  11508. return UTF16String.fromCodepoints([code]).toString();
  11509. }
  11510. }
  11511. };
  11512. const pasteEventIsCrippledSafariHTMLPaste = function (event) {
  11513. const paste = event.clipboardData;
  11514. if (paste) {
  11515. if (paste.types.includes("text/html")) {
  11516. // Answer is yes if there's any possibility of Paste and Match Style in Safari,
  11517. // which is nearly impossible to detect confidently: https://bugs.webkit.org/show_bug.cgi?id=174165
  11518. for (const type of paste.types) {
  11519. const hasPasteboardFlavor = /^CorePasteboardFlavorType/.test(type);
  11520. const hasReadableDynamicData = /^dyn\./.test(type) && paste.getData(type);
  11521. const mightBePasteAndMatchStyle = hasPasteboardFlavor || hasReadableDynamicData;
  11522. if (mightBePasteAndMatchStyle) {
  11523. return true;
  11524. }
  11525. }
  11526. return false;
  11527. } else {
  11528. const isExternalHTMLPaste = paste.types.includes("com.apple.webarchive");
  11529. const isExternalRichTextPaste = paste.types.includes("com.apple.flat-rtfd");
  11530. return isExternalHTMLPaste || isExternalRichTextPaste;
  11531. }
  11532. }
  11533. };
  11534. class CompositionInput extends BasicObject {
  11535. constructor(inputController) {
  11536. super(...arguments);
  11537. this.inputController = inputController;
  11538. this.responder = this.inputController.responder;
  11539. this.delegate = this.inputController.delegate;
  11540. this.inputSummary = this.inputController.inputSummary;
  11541. this.data = {};
  11542. }
  11543. start(data) {
  11544. this.data.start = data;
  11545. if (this.isSignificant()) {
  11546. var _this$responder5;
  11547. if (this.inputSummary.eventName === "keypress" && this.inputSummary.textAdded) {
  11548. var _this$responder4;
  11549. (_this$responder4 = this.responder) === null || _this$responder4 === void 0 || _this$responder4.deleteInDirection("left");
  11550. }
  11551. if (!this.selectionIsExpanded()) {
  11552. this.insertPlaceholder();
  11553. this.requestRender();
  11554. }
  11555. this.range = (_this$responder5 = this.responder) === null || _this$responder5 === void 0 ? void 0 : _this$responder5.getSelectedRange();
  11556. }
  11557. }
  11558. update(data) {
  11559. this.data.update = data;
  11560. if (this.isSignificant()) {
  11561. const range = this.selectPlaceholder();
  11562. if (range) {
  11563. this.forgetPlaceholder();
  11564. this.range = range;
  11565. }
  11566. }
  11567. }
  11568. end(data) {
  11569. this.data.end = data;
  11570. if (this.isSignificant()) {
  11571. this.forgetPlaceholder();
  11572. if (this.canApplyToDocument()) {
  11573. var _this$delegate2, _this$responder6, _this$responder7, _this$responder8;
  11574. this.setInputSummary({
  11575. preferDocument: true,
  11576. didInput: false
  11577. });
  11578. (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || _this$delegate2.inputControllerWillPerformTyping();
  11579. (_this$responder6 = this.responder) === null || _this$responder6 === void 0 || _this$responder6.setSelectedRange(this.range);
  11580. (_this$responder7 = this.responder) === null || _this$responder7 === void 0 || _this$responder7.insertString(this.data.end);
  11581. return (_this$responder8 = this.responder) === null || _this$responder8 === void 0 ? void 0 : _this$responder8.setSelectedRange(this.range[0] + this.data.end.length);
  11582. } else if (this.data.start != null || this.data.update != null) {
  11583. this.requestReparse();
  11584. return this.inputController.reset();
  11585. }
  11586. } else {
  11587. return this.inputController.reset();
  11588. }
  11589. }
  11590. getEndData() {
  11591. return this.data.end;
  11592. }
  11593. isEnded() {
  11594. return this.getEndData() != null;
  11595. }
  11596. isSignificant() {
  11597. if (browser.composesExistingText) {
  11598. return this.inputSummary.didInput;
  11599. } else {
  11600. return true;
  11601. }
  11602. }
  11603. // Private
  11604. canApplyToDocument() {
  11605. var _this$data$start, _this$data$end;
  11606. 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;
  11607. }
  11608. }
  11609. CompositionInput.proxyMethod("inputController.setInputSummary");
  11610. CompositionInput.proxyMethod("inputController.requestRender");
  11611. CompositionInput.proxyMethod("inputController.requestReparse");
  11612. CompositionInput.proxyMethod("responder?.selectionIsExpanded");
  11613. CompositionInput.proxyMethod("responder?.insertPlaceholder");
  11614. CompositionInput.proxyMethod("responder?.selectPlaceholder");
  11615. CompositionInput.proxyMethod("responder?.forgetPlaceholder");
  11616. class Level2InputController extends InputController {
  11617. constructor() {
  11618. super(...arguments);
  11619. this.render = this.render.bind(this);
  11620. }
  11621. elementDidMutate() {
  11622. if (this.scheduledRender) {
  11623. if (this.composing) {
  11624. var _this$delegate, _this$delegate$inputC;
  11625. 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);
  11626. }
  11627. } else {
  11628. return this.reparse();
  11629. }
  11630. }
  11631. scheduleRender() {
  11632. return this.scheduledRender ? this.scheduledRender : this.scheduledRender = requestAnimationFrame(this.render);
  11633. }
  11634. render() {
  11635. var _this$afterRender;
  11636. cancelAnimationFrame(this.scheduledRender);
  11637. this.scheduledRender = null;
  11638. if (!this.composing) {
  11639. var _this$delegate2;
  11640. (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 || _this$delegate2.render();
  11641. }
  11642. (_this$afterRender = this.afterRender) === null || _this$afterRender === void 0 || _this$afterRender.call(this);
  11643. this.afterRender = null;
  11644. }
  11645. reparse() {
  11646. var _this$delegate3;
  11647. return (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 ? void 0 : _this$delegate3.reparse();
  11648. }
  11649. // Responder helpers
  11650. insertString() {
  11651. var _this$delegate4;
  11652. let string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
  11653. let options = arguments.length > 1 ? arguments[1] : undefined;
  11654. (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.inputControllerWillPerformTyping();
  11655. return this.withTargetDOMRange(function () {
  11656. var _this$responder;
  11657. return (_this$responder = this.responder) === null || _this$responder === void 0 ? void 0 : _this$responder.insertString(string, options);
  11658. });
  11659. }
  11660. toggleAttributeIfSupported(attributeName) {
  11661. if (getAllAttributeNames().includes(attributeName)) {
  11662. var _this$delegate5;
  11663. (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.inputControllerWillPerformFormatting(attributeName);
  11664. return this.withTargetDOMRange(function () {
  11665. var _this$responder2;
  11666. return (_this$responder2 = this.responder) === null || _this$responder2 === void 0 ? void 0 : _this$responder2.toggleCurrentAttribute(attributeName);
  11667. });
  11668. }
  11669. }
  11670. activateAttributeIfSupported(attributeName, value) {
  11671. if (getAllAttributeNames().includes(attributeName)) {
  11672. var _this$delegate6;
  11673. (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 || _this$delegate6.inputControllerWillPerformFormatting(attributeName);
  11674. return this.withTargetDOMRange(function () {
  11675. var _this$responder3;
  11676. return (_this$responder3 = this.responder) === null || _this$responder3 === void 0 ? void 0 : _this$responder3.setCurrentAttribute(attributeName, value);
  11677. });
  11678. }
  11679. }
  11680. deleteInDirection(direction) {
  11681. let {
  11682. recordUndoEntry
  11683. } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
  11684. recordUndoEntry: true
  11685. };
  11686. if (recordUndoEntry) {
  11687. var _this$delegate7;
  11688. (_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || _this$delegate7.inputControllerWillPerformTyping();
  11689. }
  11690. const perform = () => {
  11691. var _this$responder4;
  11692. return (_this$responder4 = this.responder) === null || _this$responder4 === void 0 ? void 0 : _this$responder4.deleteInDirection(direction);
  11693. };
  11694. const domRange = this.getTargetDOMRange({
  11695. minLength: this.composing ? 1 : 2
  11696. });
  11697. if (domRange) {
  11698. return this.withTargetDOMRange(domRange, perform);
  11699. } else {
  11700. return perform();
  11701. }
  11702. }
  11703. // Selection helpers
  11704. withTargetDOMRange(domRange, fn) {
  11705. if (typeof domRange === "function") {
  11706. fn = domRange;
  11707. domRange = this.getTargetDOMRange();
  11708. }
  11709. if (domRange) {
  11710. var _this$responder5;
  11711. return (_this$responder5 = this.responder) === null || _this$responder5 === void 0 ? void 0 : _this$responder5.withTargetDOMRange(domRange, fn.bind(this));
  11712. } else {
  11713. selectionChangeObserver.reset();
  11714. return fn.call(this);
  11715. }
  11716. }
  11717. getTargetDOMRange() {
  11718. var _this$event$getTarget, _this$event;
  11719. let {
  11720. minLength
  11721. } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
  11722. minLength: 0
  11723. };
  11724. const targetRanges = (_this$event$getTarget = (_this$event = this.event).getTargetRanges) === null || _this$event$getTarget === void 0 ? void 0 : _this$event$getTarget.call(_this$event);
  11725. if (targetRanges) {
  11726. if (targetRanges.length) {
  11727. const domRange = staticRangeToRange(targetRanges[0]);
  11728. if (minLength === 0 || domRange.toString().length >= minLength) {
  11729. return domRange;
  11730. }
  11731. }
  11732. }
  11733. }
  11734. withEvent(event, fn) {
  11735. let result;
  11736. this.event = event;
  11737. try {
  11738. result = fn.call(this);
  11739. } finally {
  11740. this.event = null;
  11741. }
  11742. return result;
  11743. }
  11744. }
  11745. _defineProperty(Level2InputController, "events", {
  11746. keydown(event) {
  11747. if (keyEventIsKeyboardCommand(event)) {
  11748. var _this$delegate8;
  11749. const command = keyboardCommandFromKeyEvent(event);
  11750. if ((_this$delegate8 = this.delegate) !== null && _this$delegate8 !== void 0 && _this$delegate8.inputControllerDidReceiveKeyboardCommand(command)) {
  11751. event.preventDefault();
  11752. }
  11753. } else {
  11754. let name = event.key;
  11755. if (event.altKey) {
  11756. name += "+Alt";
  11757. }
  11758. if (event.shiftKey) {
  11759. name += "+Shift";
  11760. }
  11761. const handler = this.constructor.keys[name];
  11762. if (handler) {
  11763. return this.withEvent(event, handler);
  11764. }
  11765. }
  11766. },
  11767. // Handle paste event to work around beforeinput.insertFromPaste browser bugs.
  11768. // Safe to remove each condition once fixed upstream.
  11769. paste(event) {
  11770. var _event$clipboardData;
  11771. // https://bugs.webkit.org/show_bug.cgi?id=194921
  11772. let paste;
  11773. const href = (_event$clipboardData = event.clipboardData) === null || _event$clipboardData === void 0 ? void 0 : _event$clipboardData.getData("URL");
  11774. if (pasteEventHasFilesOnly(event)) {
  11775. event.preventDefault();
  11776. return this.attachFiles(event.clipboardData.files);
  11777. // https://bugs.chromium.org/p/chromium/issues/detail?id=934448
  11778. } else if (pasteEventHasPlainTextOnly(event)) {
  11779. var _this$delegate9, _this$responder6, _this$delegate10;
  11780. event.preventDefault();
  11781. paste = {
  11782. type: "text/plain",
  11783. string: event.clipboardData.getData("text/plain")
  11784. };
  11785. (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 || _this$delegate9.inputControllerWillPaste(paste);
  11786. (_this$responder6 = this.responder) === null || _this$responder6 === void 0 || _this$responder6.insertString(paste.string);
  11787. this.render();
  11788. return (_this$delegate10 = this.delegate) === null || _this$delegate10 === void 0 ? void 0 : _this$delegate10.inputControllerDidPaste(paste);
  11789. // https://bugs.webkit.org/show_bug.cgi?id=196702
  11790. } else if (href) {
  11791. var _this$delegate11, _this$responder7, _this$delegate12;
  11792. event.preventDefault();
  11793. paste = {
  11794. type: "text/html",
  11795. html: this.createLinkHTML(href)
  11796. };
  11797. (_this$delegate11 = this.delegate) === null || _this$delegate11 === void 0 || _this$delegate11.inputControllerWillPaste(paste);
  11798. (_this$responder7 = this.responder) === null || _this$responder7 === void 0 || _this$responder7.insertHTML(paste.html);
  11799. this.render();
  11800. return (_this$delegate12 = this.delegate) === null || _this$delegate12 === void 0 ? void 0 : _this$delegate12.inputControllerDidPaste(paste);
  11801. }
  11802. },
  11803. beforeinput(event) {
  11804. const handler = this.constructor.inputTypes[event.inputType];
  11805. const immmediateRender = shouldRenderInmmediatelyToDealWithIOSDictation(event);
  11806. if (handler) {
  11807. this.withEvent(event, handler);
  11808. if (!immmediateRender) {
  11809. this.scheduleRender();
  11810. }
  11811. }
  11812. if (immmediateRender) {
  11813. this.render();
  11814. }
  11815. },
  11816. input(event) {
  11817. selectionChangeObserver.reset();
  11818. },
  11819. dragstart(event) {
  11820. var _this$responder8;
  11821. if ((_this$responder8 = this.responder) !== null && _this$responder8 !== void 0 && _this$responder8.selectionContainsAttachments()) {
  11822. var _this$responder9;
  11823. event.dataTransfer.setData("application/x-trix-dragging", true);
  11824. this.dragging = {
  11825. range: (_this$responder9 = this.responder) === null || _this$responder9 === void 0 ? void 0 : _this$responder9.getSelectedRange(),
  11826. point: pointFromEvent(event)
  11827. };
  11828. }
  11829. },
  11830. dragenter(event) {
  11831. if (dragEventHasFiles(event)) {
  11832. event.preventDefault();
  11833. }
  11834. },
  11835. dragover(event) {
  11836. if (this.dragging) {
  11837. event.preventDefault();
  11838. const point = pointFromEvent(event);
  11839. if (!objectsAreEqual(point, this.dragging.point)) {
  11840. var _this$responder10;
  11841. this.dragging.point = point;
  11842. return (_this$responder10 = this.responder) === null || _this$responder10 === void 0 ? void 0 : _this$responder10.setLocationRangeFromPointRange(point);
  11843. }
  11844. } else if (dragEventHasFiles(event)) {
  11845. event.preventDefault();
  11846. }
  11847. },
  11848. drop(event) {
  11849. if (this.dragging) {
  11850. var _this$delegate13, _this$responder11;
  11851. event.preventDefault();
  11852. (_this$delegate13 = this.delegate) === null || _this$delegate13 === void 0 || _this$delegate13.inputControllerWillMoveText();
  11853. (_this$responder11 = this.responder) === null || _this$responder11 === void 0 || _this$responder11.moveTextFromRange(this.dragging.range);
  11854. this.dragging = null;
  11855. return this.scheduleRender();
  11856. } else if (dragEventHasFiles(event)) {
  11857. var _this$responder12;
  11858. event.preventDefault();
  11859. const point = pointFromEvent(event);
  11860. (_this$responder12 = this.responder) === null || _this$responder12 === void 0 || _this$responder12.setLocationRangeFromPointRange(point);
  11861. return this.attachFiles(event.dataTransfer.files);
  11862. }
  11863. },
  11864. dragend() {
  11865. if (this.dragging) {
  11866. var _this$responder13;
  11867. (_this$responder13 = this.responder) === null || _this$responder13 === void 0 || _this$responder13.setSelectedRange(this.dragging.range);
  11868. this.dragging = null;
  11869. }
  11870. },
  11871. compositionend(event) {
  11872. if (this.composing) {
  11873. this.composing = false;
  11874. if (!browser$1.recentAndroid) this.scheduleRender();
  11875. }
  11876. }
  11877. });
  11878. _defineProperty(Level2InputController, "keys", {
  11879. ArrowLeft() {
  11880. var _this$responder14;
  11881. if ((_this$responder14 = this.responder) !== null && _this$responder14 !== void 0 && _this$responder14.shouldManageMovingCursorInDirection("backward")) {
  11882. var _this$responder15;
  11883. this.event.preventDefault();
  11884. return (_this$responder15 = this.responder) === null || _this$responder15 === void 0 ? void 0 : _this$responder15.moveCursorInDirection("backward");
  11885. }
  11886. },
  11887. ArrowRight() {
  11888. var _this$responder16;
  11889. if ((_this$responder16 = this.responder) !== null && _this$responder16 !== void 0 && _this$responder16.shouldManageMovingCursorInDirection("forward")) {
  11890. var _this$responder17;
  11891. this.event.preventDefault();
  11892. return (_this$responder17 = this.responder) === null || _this$responder17 === void 0 ? void 0 : _this$responder17.moveCursorInDirection("forward");
  11893. }
  11894. },
  11895. Backspace() {
  11896. var _this$responder18;
  11897. if ((_this$responder18 = this.responder) !== null && _this$responder18 !== void 0 && _this$responder18.shouldManageDeletingInDirection("backward")) {
  11898. var _this$delegate14, _this$responder19;
  11899. this.event.preventDefault();
  11900. (_this$delegate14 = this.delegate) === null || _this$delegate14 === void 0 || _this$delegate14.inputControllerWillPerformTyping();
  11901. (_this$responder19 = this.responder) === null || _this$responder19 === void 0 || _this$responder19.deleteInDirection("backward");
  11902. return this.render();
  11903. }
  11904. },
  11905. Tab() {
  11906. var _this$responder20;
  11907. if ((_this$responder20 = this.responder) !== null && _this$responder20 !== void 0 && _this$responder20.canIncreaseNestingLevel()) {
  11908. var _this$responder21;
  11909. this.event.preventDefault();
  11910. (_this$responder21 = this.responder) === null || _this$responder21 === void 0 || _this$responder21.increaseNestingLevel();
  11911. return this.render();
  11912. }
  11913. },
  11914. "Tab+Shift"() {
  11915. var _this$responder22;
  11916. if ((_this$responder22 = this.responder) !== null && _this$responder22 !== void 0 && _this$responder22.canDecreaseNestingLevel()) {
  11917. var _this$responder23;
  11918. this.event.preventDefault();
  11919. (_this$responder23 = this.responder) === null || _this$responder23 === void 0 || _this$responder23.decreaseNestingLevel();
  11920. return this.render();
  11921. }
  11922. }
  11923. });
  11924. _defineProperty(Level2InputController, "inputTypes", {
  11925. deleteByComposition() {
  11926. return this.deleteInDirection("backward", {
  11927. recordUndoEntry: false
  11928. });
  11929. },
  11930. deleteByCut() {
  11931. return this.deleteInDirection("backward");
  11932. },
  11933. deleteByDrag() {
  11934. this.event.preventDefault();
  11935. return this.withTargetDOMRange(function () {
  11936. var _this$responder24;
  11937. this.deleteByDragRange = (_this$responder24 = this.responder) === null || _this$responder24 === void 0 ? void 0 : _this$responder24.getSelectedRange();
  11938. });
  11939. },
  11940. deleteCompositionText() {
  11941. return this.deleteInDirection("backward", {
  11942. recordUndoEntry: false
  11943. });
  11944. },
  11945. deleteContent() {
  11946. return this.deleteInDirection("backward");
  11947. },
  11948. deleteContentBackward() {
  11949. return this.deleteInDirection("backward");
  11950. },
  11951. deleteContentForward() {
  11952. return this.deleteInDirection("forward");
  11953. },
  11954. deleteEntireSoftLine() {
  11955. return this.deleteInDirection("forward");
  11956. },
  11957. deleteHardLineBackward() {
  11958. return this.deleteInDirection("backward");
  11959. },
  11960. deleteHardLineForward() {
  11961. return this.deleteInDirection("forward");
  11962. },
  11963. deleteSoftLineBackward() {
  11964. return this.deleteInDirection("backward");
  11965. },
  11966. deleteSoftLineForward() {
  11967. return this.deleteInDirection("forward");
  11968. },
  11969. deleteWordBackward() {
  11970. return this.deleteInDirection("backward");
  11971. },
  11972. deleteWordForward() {
  11973. return this.deleteInDirection("forward");
  11974. },
  11975. formatBackColor() {
  11976. return this.activateAttributeIfSupported("backgroundColor", this.event.data);
  11977. },
  11978. formatBold() {
  11979. return this.toggleAttributeIfSupported("bold");
  11980. },
  11981. formatFontColor() {
  11982. return this.activateAttributeIfSupported("color", this.event.data);
  11983. },
  11984. formatFontName() {
  11985. return this.activateAttributeIfSupported("font", this.event.data);
  11986. },
  11987. formatIndent() {
  11988. var _this$responder25;
  11989. if ((_this$responder25 = this.responder) !== null && _this$responder25 !== void 0 && _this$responder25.canIncreaseNestingLevel()) {
  11990. return this.withTargetDOMRange(function () {
  11991. var _this$responder26;
  11992. return (_this$responder26 = this.responder) === null || _this$responder26 === void 0 ? void 0 : _this$responder26.increaseNestingLevel();
  11993. });
  11994. }
  11995. },
  11996. formatItalic() {
  11997. return this.toggleAttributeIfSupported("italic");
  11998. },
  11999. formatJustifyCenter() {
  12000. return this.toggleAttributeIfSupported("justifyCenter");
  12001. },
  12002. formatJustifyFull() {
  12003. return this.toggleAttributeIfSupported("justifyFull");
  12004. },
  12005. formatJustifyLeft() {
  12006. return this.toggleAttributeIfSupported("justifyLeft");
  12007. },
  12008. formatJustifyRight() {
  12009. return this.toggleAttributeIfSupported("justifyRight");
  12010. },
  12011. formatOutdent() {
  12012. var _this$responder27;
  12013. if ((_this$responder27 = this.responder) !== null && _this$responder27 !== void 0 && _this$responder27.canDecreaseNestingLevel()) {
  12014. return this.withTargetDOMRange(function () {
  12015. var _this$responder28;
  12016. return (_this$responder28 = this.responder) === null || _this$responder28 === void 0 ? void 0 : _this$responder28.decreaseNestingLevel();
  12017. });
  12018. }
  12019. },
  12020. formatRemove() {
  12021. this.withTargetDOMRange(function () {
  12022. for (const attributeName in (_this$responder29 = this.responder) === null || _this$responder29 === void 0 ? void 0 : _this$responder29.getCurrentAttributes()) {
  12023. var _this$responder29, _this$responder30;
  12024. (_this$responder30 = this.responder) === null || _this$responder30 === void 0 || _this$responder30.removeCurrentAttribute(attributeName);
  12025. }
  12026. });
  12027. },
  12028. formatSetBlockTextDirection() {
  12029. return this.activateAttributeIfSupported("blockDir", this.event.data);
  12030. },
  12031. formatSetInlineTextDirection() {
  12032. return this.activateAttributeIfSupported("textDir", this.event.data);
  12033. },
  12034. formatStrikeThrough() {
  12035. return this.toggleAttributeIfSupported("strike");
  12036. },
  12037. formatSubscript() {
  12038. return this.toggleAttributeIfSupported("sub");
  12039. },
  12040. formatSuperscript() {
  12041. return this.toggleAttributeIfSupported("sup");
  12042. },
  12043. formatUnderline() {
  12044. return this.toggleAttributeIfSupported("underline");
  12045. },
  12046. historyRedo() {
  12047. var _this$delegate15;
  12048. return (_this$delegate15 = this.delegate) === null || _this$delegate15 === void 0 ? void 0 : _this$delegate15.inputControllerWillPerformRedo();
  12049. },
  12050. historyUndo() {
  12051. var _this$delegate16;
  12052. return (_this$delegate16 = this.delegate) === null || _this$delegate16 === void 0 ? void 0 : _this$delegate16.inputControllerWillPerformUndo();
  12053. },
  12054. insertCompositionText() {
  12055. this.composing = true;
  12056. return this.insertString(this.event.data);
  12057. },
  12058. insertFromComposition() {
  12059. this.composing = false;
  12060. return this.insertString(this.event.data);
  12061. },
  12062. insertFromDrop() {
  12063. const range = this.deleteByDragRange;
  12064. if (range) {
  12065. var _this$delegate17;
  12066. this.deleteByDragRange = null;
  12067. (_this$delegate17 = this.delegate) === null || _this$delegate17 === void 0 || _this$delegate17.inputControllerWillMoveText();
  12068. return this.withTargetDOMRange(function () {
  12069. var _this$responder31;
  12070. return (_this$responder31 = this.responder) === null || _this$responder31 === void 0 ? void 0 : _this$responder31.moveTextFromRange(range);
  12071. });
  12072. }
  12073. },
  12074. insertFromPaste() {
  12075. const {
  12076. dataTransfer
  12077. } = this.event;
  12078. const paste = {
  12079. dataTransfer
  12080. };
  12081. const href = dataTransfer.getData("URL");
  12082. const html = dataTransfer.getData("text/html");
  12083. if (href) {
  12084. var _this$delegate18;
  12085. let string;
  12086. this.event.preventDefault();
  12087. paste.type = "text/html";
  12088. const name = dataTransfer.getData("public.url-name");
  12089. if (name) {
  12090. string = squishBreakableWhitespace(name).trim();
  12091. } else {
  12092. string = href;
  12093. }
  12094. paste.html = this.createLinkHTML(href, string);
  12095. (_this$delegate18 = this.delegate) === null || _this$delegate18 === void 0 || _this$delegate18.inputControllerWillPaste(paste);
  12096. this.withTargetDOMRange(function () {
  12097. var _this$responder32;
  12098. return (_this$responder32 = this.responder) === null || _this$responder32 === void 0 ? void 0 : _this$responder32.insertHTML(paste.html);
  12099. });
  12100. this.afterRender = () => {
  12101. var _this$delegate19;
  12102. return (_this$delegate19 = this.delegate) === null || _this$delegate19 === void 0 ? void 0 : _this$delegate19.inputControllerDidPaste(paste);
  12103. };
  12104. } else if (dataTransferIsPlainText(dataTransfer)) {
  12105. var _this$delegate20;
  12106. paste.type = "text/plain";
  12107. paste.string = dataTransfer.getData("text/plain");
  12108. (_this$delegate20 = this.delegate) === null || _this$delegate20 === void 0 || _this$delegate20.inputControllerWillPaste(paste);
  12109. this.withTargetDOMRange(function () {
  12110. var _this$responder33;
  12111. return (_this$responder33 = this.responder) === null || _this$responder33 === void 0 ? void 0 : _this$responder33.insertString(paste.string);
  12112. });
  12113. this.afterRender = () => {
  12114. var _this$delegate21;
  12115. return (_this$delegate21 = this.delegate) === null || _this$delegate21 === void 0 ? void 0 : _this$delegate21.inputControllerDidPaste(paste);
  12116. };
  12117. } else if (processableFilePaste(this.event)) {
  12118. var _this$delegate22;
  12119. paste.type = "File";
  12120. paste.file = dataTransfer.files[0];
  12121. (_this$delegate22 = this.delegate) === null || _this$delegate22 === void 0 || _this$delegate22.inputControllerWillPaste(paste);
  12122. this.withTargetDOMRange(function () {
  12123. var _this$responder34;
  12124. return (_this$responder34 = this.responder) === null || _this$responder34 === void 0 ? void 0 : _this$responder34.insertFile(paste.file);
  12125. });
  12126. this.afterRender = () => {
  12127. var _this$delegate23;
  12128. return (_this$delegate23 = this.delegate) === null || _this$delegate23 === void 0 ? void 0 : _this$delegate23.inputControllerDidPaste(paste);
  12129. };
  12130. } else if (html) {
  12131. var _this$delegate24;
  12132. this.event.preventDefault();
  12133. paste.type = "text/html";
  12134. paste.html = html;
  12135. (_this$delegate24 = this.delegate) === null || _this$delegate24 === void 0 || _this$delegate24.inputControllerWillPaste(paste);
  12136. this.withTargetDOMRange(function () {
  12137. var _this$responder35;
  12138. return (_this$responder35 = this.responder) === null || _this$responder35 === void 0 ? void 0 : _this$responder35.insertHTML(paste.html);
  12139. });
  12140. this.afterRender = () => {
  12141. var _this$delegate25;
  12142. return (_this$delegate25 = this.delegate) === null || _this$delegate25 === void 0 ? void 0 : _this$delegate25.inputControllerDidPaste(paste);
  12143. };
  12144. }
  12145. },
  12146. insertFromYank() {
  12147. return this.insertString(this.event.data);
  12148. },
  12149. insertLineBreak() {
  12150. return this.insertString("\n");
  12151. },
  12152. insertLink() {
  12153. return this.activateAttributeIfSupported("href", this.event.data);
  12154. },
  12155. insertOrderedList() {
  12156. return this.toggleAttributeIfSupported("number");
  12157. },
  12158. insertParagraph() {
  12159. var _this$delegate26;
  12160. (_this$delegate26 = this.delegate) === null || _this$delegate26 === void 0 || _this$delegate26.inputControllerWillPerformTyping();
  12161. return this.withTargetDOMRange(function () {
  12162. var _this$responder36;
  12163. return (_this$responder36 = this.responder) === null || _this$responder36 === void 0 ? void 0 : _this$responder36.insertLineBreak();
  12164. });
  12165. },
  12166. insertReplacementText() {
  12167. const replacement = this.event.dataTransfer.getData("text/plain");
  12168. const domRange = this.event.getTargetRanges()[0];
  12169. this.withTargetDOMRange(domRange, () => {
  12170. this.insertString(replacement, {
  12171. updatePosition: false
  12172. });
  12173. });
  12174. },
  12175. insertText() {
  12176. var _this$event$dataTrans;
  12177. 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")));
  12178. },
  12179. insertTranspose() {
  12180. return this.insertString(this.event.data);
  12181. },
  12182. insertUnorderedList() {
  12183. return this.toggleAttributeIfSupported("bullet");
  12184. }
  12185. });
  12186. const staticRangeToRange = function (staticRange) {
  12187. const range = document.createRange();
  12188. range.setStart(staticRange.startContainer, staticRange.startOffset);
  12189. range.setEnd(staticRange.endContainer, staticRange.endOffset);
  12190. return range;
  12191. };
  12192. // Event helpers
  12193. const dragEventHasFiles = event => {
  12194. var _event$dataTransfer;
  12195. return Array.from(((_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.types) || []).includes("Files");
  12196. };
  12197. const processableFilePaste = event => {
  12198. var _event$dataTransfer$f;
  12199. // Paste events that only have files are handled by the paste event handler,
  12200. // to work around Safari not supporting beforeinput.insertFromPaste for files.
  12201. // MS Office text pastes include a file with a screenshot of the text, but we should
  12202. // handle them as text pastes.
  12203. return ((_event$dataTransfer$f = event.dataTransfer.files) === null || _event$dataTransfer$f === void 0 ? void 0 : _event$dataTransfer$f[0]) && !pasteEventHasFilesOnly(event) && !dataTransferIsMsOfficePaste(event);
  12204. };
  12205. const pasteEventHasFilesOnly = function (event) {
  12206. const clipboard = event.clipboardData;
  12207. if (clipboard) {
  12208. const fileTypes = Array.from(clipboard.types).filter(type => type.match(/file/i)); // "Files", "application/x-moz-file"
  12209. return fileTypes.length === clipboard.types.length && clipboard.files.length >= 1;
  12210. }
  12211. };
  12212. const pasteEventHasPlainTextOnly = function (event) {
  12213. const clipboard = event.clipboardData;
  12214. if (clipboard) {
  12215. return clipboard.types.includes("text/plain") && clipboard.types.length === 1;
  12216. }
  12217. };
  12218. const keyboardCommandFromKeyEvent = function (event) {
  12219. const command = [];
  12220. if (event.altKey) {
  12221. command.push("alt");
  12222. }
  12223. if (event.shiftKey) {
  12224. command.push("shift");
  12225. }
  12226. command.push(event.key);
  12227. return command;
  12228. };
  12229. const pointFromEvent = event => ({
  12230. x: event.clientX,
  12231. y: event.clientY
  12232. });
  12233. const attributeButtonSelector = "[data-trix-attribute]";
  12234. const actionButtonSelector = "[data-trix-action]";
  12235. const toolbarButtonSelector = "".concat(attributeButtonSelector, ", ").concat(actionButtonSelector);
  12236. const dialogSelector = "[data-trix-dialog]";
  12237. const activeDialogSelector = "".concat(dialogSelector, "[data-trix-active]");
  12238. const dialogButtonSelector = "".concat(dialogSelector, " [data-trix-method]");
  12239. const dialogInputSelector = "".concat(dialogSelector, " [data-trix-input]");
  12240. const getInputForDialog = (element, attributeName) => {
  12241. if (!attributeName) {
  12242. attributeName = getAttributeName(element);
  12243. }
  12244. return element.querySelector("[data-trix-input][name='".concat(attributeName, "']"));
  12245. };
  12246. const getActionName = element => element.getAttribute("data-trix-action");
  12247. const getAttributeName = element => {
  12248. return element.getAttribute("data-trix-attribute") || element.getAttribute("data-trix-dialog-attribute");
  12249. };
  12250. const getDialogName = element => element.getAttribute("data-trix-dialog");
  12251. class ToolbarController extends BasicObject {
  12252. constructor(element) {
  12253. super(element);
  12254. this.didClickActionButton = this.didClickActionButton.bind(this);
  12255. this.didClickAttributeButton = this.didClickAttributeButton.bind(this);
  12256. this.didClickDialogButton = this.didClickDialogButton.bind(this);
  12257. this.didKeyDownDialogInput = this.didKeyDownDialogInput.bind(this);
  12258. this.element = element;
  12259. this.attributes = {};
  12260. this.actions = {};
  12261. this.resetDialogInputs();
  12262. handleEvent("mousedown", {
  12263. onElement: this.element,
  12264. matchingSelector: actionButtonSelector,
  12265. withCallback: this.didClickActionButton
  12266. });
  12267. handleEvent("mousedown", {
  12268. onElement: this.element,
  12269. matchingSelector: attributeButtonSelector,
  12270. withCallback: this.didClickAttributeButton
  12271. });
  12272. handleEvent("click", {
  12273. onElement: this.element,
  12274. matchingSelector: toolbarButtonSelector,
  12275. preventDefault: true
  12276. });
  12277. handleEvent("click", {
  12278. onElement: this.element,
  12279. matchingSelector: dialogButtonSelector,
  12280. withCallback: this.didClickDialogButton
  12281. });
  12282. handleEvent("keydown", {
  12283. onElement: this.element,
  12284. matchingSelector: dialogInputSelector,
  12285. withCallback: this.didKeyDownDialogInput
  12286. });
  12287. }
  12288. // Event handlers
  12289. didClickActionButton(event, element) {
  12290. var _this$delegate;
  12291. (_this$delegate = this.delegate) === null || _this$delegate === void 0 || _this$delegate.toolbarDidClickButton();
  12292. event.preventDefault();
  12293. const actionName = getActionName(element);
  12294. if (this.getDialog(actionName)) {
  12295. return this.toggleDialog(actionName);
  12296. } else {
  12297. var _this$delegate2;
  12298. return (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 ? void 0 : _this$delegate2.toolbarDidInvokeAction(actionName, element);
  12299. }
  12300. }
  12301. didClickAttributeButton(event, element) {
  12302. var _this$delegate3;
  12303. (_this$delegate3 = this.delegate) === null || _this$delegate3 === void 0 || _this$delegate3.toolbarDidClickButton();
  12304. event.preventDefault();
  12305. const attributeName = getAttributeName(element);
  12306. if (this.getDialog(attributeName)) {
  12307. this.toggleDialog(attributeName);
  12308. } else {
  12309. var _this$delegate4;
  12310. (_this$delegate4 = this.delegate) === null || _this$delegate4 === void 0 || _this$delegate4.toolbarDidToggleAttribute(attributeName);
  12311. }
  12312. return this.refreshAttributeButtons();
  12313. }
  12314. didClickDialogButton(event, element) {
  12315. const dialogElement = findClosestElementFromNode(element, {
  12316. matchingSelector: dialogSelector
  12317. });
  12318. const method = element.getAttribute("data-trix-method");
  12319. return this[method].call(this, dialogElement);
  12320. }
  12321. didKeyDownDialogInput(event, element) {
  12322. if (event.keyCode === 13) {
  12323. // Enter key
  12324. event.preventDefault();
  12325. const attribute = element.getAttribute("name");
  12326. const dialog = this.getDialog(attribute);
  12327. this.setAttribute(dialog);
  12328. }
  12329. if (event.keyCode === 27) {
  12330. // Escape key
  12331. event.preventDefault();
  12332. return this.hideDialog();
  12333. }
  12334. }
  12335. // Action buttons
  12336. updateActions(actions) {
  12337. this.actions = actions;
  12338. return this.refreshActionButtons();
  12339. }
  12340. refreshActionButtons() {
  12341. return this.eachActionButton((element, actionName) => {
  12342. element.disabled = this.actions[actionName] === false;
  12343. });
  12344. }
  12345. eachActionButton(callback) {
  12346. return Array.from(this.element.querySelectorAll(actionButtonSelector)).map(element => callback(element, getActionName(element)));
  12347. }
  12348. // Attribute buttons
  12349. updateAttributes(attributes) {
  12350. this.attributes = attributes;
  12351. return this.refreshAttributeButtons();
  12352. }
  12353. refreshAttributeButtons() {
  12354. return this.eachAttributeButton((element, attributeName) => {
  12355. element.disabled = this.attributes[attributeName] === false;
  12356. if (this.attributes[attributeName] || this.dialogIsVisible(attributeName)) {
  12357. element.setAttribute("data-trix-active", "");
  12358. return element.classList.add("trix-active");
  12359. } else {
  12360. element.removeAttribute("data-trix-active");
  12361. return element.classList.remove("trix-active");
  12362. }
  12363. });
  12364. }
  12365. eachAttributeButton(callback) {
  12366. return Array.from(this.element.querySelectorAll(attributeButtonSelector)).map(element => callback(element, getAttributeName(element)));
  12367. }
  12368. applyKeyboardCommand(keys) {
  12369. const keyString = JSON.stringify(keys.sort());
  12370. for (const button of Array.from(this.element.querySelectorAll("[data-trix-key]"))) {
  12371. const buttonKeys = button.getAttribute("data-trix-key").split("+");
  12372. const buttonKeyString = JSON.stringify(buttonKeys.sort());
  12373. if (buttonKeyString === keyString) {
  12374. triggerEvent("mousedown", {
  12375. onElement: button
  12376. });
  12377. return true;
  12378. }
  12379. }
  12380. return false;
  12381. }
  12382. // Dialogs
  12383. dialogIsVisible(dialogName) {
  12384. const element = this.getDialog(dialogName);
  12385. if (element) {
  12386. return element.hasAttribute("data-trix-active");
  12387. }
  12388. }
  12389. toggleDialog(dialogName) {
  12390. if (this.dialogIsVisible(dialogName)) {
  12391. return this.hideDialog();
  12392. } else {
  12393. return this.showDialog(dialogName);
  12394. }
  12395. }
  12396. showDialog(dialogName) {
  12397. var _this$delegate5, _this$delegate6;
  12398. this.hideDialog();
  12399. (_this$delegate5 = this.delegate) === null || _this$delegate5 === void 0 || _this$delegate5.toolbarWillShowDialog();
  12400. const element = this.getDialog(dialogName);
  12401. element.setAttribute("data-trix-active", "");
  12402. element.classList.add("trix-active");
  12403. Array.from(element.querySelectorAll("input[disabled]")).forEach(disabledInput => {
  12404. disabledInput.removeAttribute("disabled");
  12405. });
  12406. const attributeName = getAttributeName(element);
  12407. if (attributeName) {
  12408. const input = getInputForDialog(element, dialogName);
  12409. if (input) {
  12410. input.value = this.attributes[attributeName] || "";
  12411. input.select();
  12412. }
  12413. }
  12414. return (_this$delegate6 = this.delegate) === null || _this$delegate6 === void 0 ? void 0 : _this$delegate6.toolbarDidShowDialog(dialogName);
  12415. }
  12416. setAttribute(dialogElement) {
  12417. const attributeName = getAttributeName(dialogElement);
  12418. const input = getInputForDialog(dialogElement, attributeName);
  12419. if (input.willValidate && !input.checkValidity()) {
  12420. input.setAttribute("data-trix-validate", "");
  12421. input.classList.add("trix-validate");
  12422. return input.focus();
  12423. } else {
  12424. var _this$delegate7;
  12425. (_this$delegate7 = this.delegate) === null || _this$delegate7 === void 0 || _this$delegate7.toolbarDidUpdateAttribute(attributeName, input.value);
  12426. return this.hideDialog();
  12427. }
  12428. }
  12429. removeAttribute(dialogElement) {
  12430. var _this$delegate8;
  12431. const attributeName = getAttributeName(dialogElement);
  12432. (_this$delegate8 = this.delegate) === null || _this$delegate8 === void 0 || _this$delegate8.toolbarDidRemoveAttribute(attributeName);
  12433. return this.hideDialog();
  12434. }
  12435. hideDialog() {
  12436. const element = this.element.querySelector(activeDialogSelector);
  12437. if (element) {
  12438. var _this$delegate9;
  12439. element.removeAttribute("data-trix-active");
  12440. element.classList.remove("trix-active");
  12441. this.resetDialogInputs();
  12442. return (_this$delegate9 = this.delegate) === null || _this$delegate9 === void 0 ? void 0 : _this$delegate9.toolbarDidHideDialog(getDialogName(element));
  12443. }
  12444. }
  12445. resetDialogInputs() {
  12446. Array.from(this.element.querySelectorAll(dialogInputSelector)).forEach(input => {
  12447. input.setAttribute("disabled", "disabled");
  12448. input.removeAttribute("data-trix-validate");
  12449. input.classList.remove("trix-validate");
  12450. });
  12451. }
  12452. getDialog(dialogName) {
  12453. return this.element.querySelector("[data-trix-dialog=".concat(dialogName, "]"));
  12454. }
  12455. }
  12456. const snapshotsAreEqual = (a, b) => rangesAreEqual(a.selectedRange, b.selectedRange) && a.document.isEqualTo(b.document);
  12457. class EditorController extends Controller {
  12458. constructor(_ref) {
  12459. let {
  12460. editorElement,
  12461. document,
  12462. html
  12463. } = _ref;
  12464. super(...arguments);
  12465. this.editorElement = editorElement;
  12466. this.selectionManager = new SelectionManager(this.editorElement);
  12467. this.selectionManager.delegate = this;
  12468. this.composition = new Composition();
  12469. this.composition.delegate = this;
  12470. this.attachmentManager = new AttachmentManager(this.composition.getAttachments());
  12471. this.attachmentManager.delegate = this;
  12472. this.inputController = input.getLevel() === 2 ? new Level2InputController(this.editorElement) : new Level0InputController(this.editorElement);
  12473. this.inputController.delegate = this;
  12474. this.inputController.responder = this.composition;
  12475. this.compositionController = new CompositionController(this.editorElement, this.composition);
  12476. this.compositionController.delegate = this;
  12477. this.toolbarController = new ToolbarController(this.editorElement.toolbarElement);
  12478. this.toolbarController.delegate = this;
  12479. this.editor = new Editor(this.composition, this.selectionManager, this.editorElement);
  12480. if (document) {
  12481. this.editor.loadDocument(document);
  12482. } else {
  12483. this.editor.loadHTML(html);
  12484. }
  12485. }
  12486. registerSelectionManager() {
  12487. return selectionChangeObserver.registerSelectionManager(this.selectionManager);
  12488. }
  12489. unregisterSelectionManager() {
  12490. return selectionChangeObserver.unregisterSelectionManager(this.selectionManager);
  12491. }
  12492. render() {
  12493. return this.compositionController.render();
  12494. }
  12495. reparse() {
  12496. return this.composition.replaceHTML(this.editorElement.innerHTML);
  12497. }
  12498. // Composition delegate
  12499. compositionDidChangeDocument(document) {
  12500. this.notifyEditorElement("document-change");
  12501. if (!this.handlingInput) {
  12502. return this.render();
  12503. }
  12504. }
  12505. compositionDidChangeCurrentAttributes(currentAttributes) {
  12506. this.currentAttributes = currentAttributes;
  12507. this.toolbarController.updateAttributes(this.currentAttributes);
  12508. this.updateCurrentActions();
  12509. return this.notifyEditorElement("attributes-change", {
  12510. attributes: this.currentAttributes
  12511. });
  12512. }
  12513. compositionDidPerformInsertionAtRange(range) {
  12514. if (this.pasting) {
  12515. this.pastedRange = range;
  12516. }
  12517. }
  12518. compositionShouldAcceptFile(file) {
  12519. return this.notifyEditorElement("file-accept", {
  12520. file
  12521. });
  12522. }
  12523. compositionDidAddAttachment(attachment) {
  12524. const managedAttachment = this.attachmentManager.manageAttachment(attachment);
  12525. return this.notifyEditorElement("attachment-add", {
  12526. attachment: managedAttachment
  12527. });
  12528. }
  12529. compositionDidEditAttachment(attachment) {
  12530. this.compositionController.rerenderViewForObject(attachment);
  12531. const managedAttachment = this.attachmentManager.manageAttachment(attachment);
  12532. this.notifyEditorElement("attachment-edit", {
  12533. attachment: managedAttachment
  12534. });
  12535. return this.notifyEditorElement("change");
  12536. }
  12537. compositionDidChangeAttachmentPreviewURL(attachment) {
  12538. this.compositionController.invalidateViewForObject(attachment);
  12539. return this.notifyEditorElement("change");
  12540. }
  12541. compositionDidRemoveAttachment(attachment) {
  12542. const managedAttachment = this.attachmentManager.unmanageAttachment(attachment);
  12543. return this.notifyEditorElement("attachment-remove", {
  12544. attachment: managedAttachment
  12545. });
  12546. }
  12547. compositionDidStartEditingAttachment(attachment, options) {
  12548. this.attachmentLocationRange = this.composition.document.getLocationRangeOfAttachment(attachment);
  12549. this.compositionController.installAttachmentEditorForAttachment(attachment, options);
  12550. return this.selectionManager.setLocationRange(this.attachmentLocationRange);
  12551. }
  12552. compositionDidStopEditingAttachment(attachment) {
  12553. this.compositionController.uninstallAttachmentEditor();
  12554. this.attachmentLocationRange = null;
  12555. }
  12556. compositionDidRequestChangingSelectionToLocationRange(locationRange) {
  12557. if (this.loadingSnapshot && !this.isFocused()) return;
  12558. this.requestedLocationRange = locationRange;
  12559. this.compositionRevisionWhenLocationRangeRequested = this.composition.revision;
  12560. if (!this.handlingInput) {
  12561. return this.render();
  12562. }
  12563. }
  12564. compositionWillLoadSnapshot() {
  12565. this.loadingSnapshot = true;
  12566. }
  12567. compositionDidLoadSnapshot() {
  12568. this.compositionController.refreshViewCache();
  12569. this.render();
  12570. this.loadingSnapshot = false;
  12571. }
  12572. getSelectionManager() {
  12573. return this.selectionManager;
  12574. }
  12575. // Attachment manager delegate
  12576. attachmentManagerDidRequestRemovalOfAttachment(attachment) {
  12577. return this.removeAttachment(attachment);
  12578. }
  12579. // Document controller delegate
  12580. compositionControllerWillSyncDocumentView() {
  12581. this.inputController.editorWillSyncDocumentView();
  12582. this.selectionManager.lock();
  12583. return this.selectionManager.clearSelection();
  12584. }
  12585. compositionControllerDidSyncDocumentView() {
  12586. this.inputController.editorDidSyncDocumentView();
  12587. this.selectionManager.unlock();
  12588. this.updateCurrentActions();
  12589. return this.notifyEditorElement("sync");
  12590. }
  12591. compositionControllerDidRender() {
  12592. if (this.requestedLocationRange) {
  12593. if (this.compositionRevisionWhenLocationRangeRequested === this.composition.revision) {
  12594. this.selectionManager.setLocationRange(this.requestedLocationRange);
  12595. }
  12596. this.requestedLocationRange = null;
  12597. this.compositionRevisionWhenLocationRangeRequested = null;
  12598. }
  12599. if (this.renderedCompositionRevision !== this.composition.revision) {
  12600. this.runEditorFilters();
  12601. this.composition.updateCurrentAttributes();
  12602. this.notifyEditorElement("render");
  12603. }
  12604. this.renderedCompositionRevision = this.composition.revision;
  12605. }
  12606. compositionControllerDidFocus() {
  12607. if (this.isFocusedInvisibly()) {
  12608. this.setLocationRange({
  12609. index: 0,
  12610. offset: 0
  12611. });
  12612. }
  12613. this.toolbarController.hideDialog();
  12614. return this.notifyEditorElement("focus");
  12615. }
  12616. compositionControllerDidBlur() {
  12617. return this.notifyEditorElement("blur");
  12618. }
  12619. compositionControllerDidSelectAttachment(attachment, options) {
  12620. this.toolbarController.hideDialog();
  12621. return this.composition.editAttachment(attachment, options);
  12622. }
  12623. compositionControllerDidRequestDeselectingAttachment(attachment) {
  12624. const locationRange = this.attachmentLocationRange || this.composition.document.getLocationRangeOfAttachment(attachment);
  12625. return this.selectionManager.setLocationRange(locationRange[1]);
  12626. }
  12627. compositionControllerWillUpdateAttachment(attachment) {
  12628. return this.editor.recordUndoEntry("Edit Attachment", {
  12629. context: attachment.id,
  12630. consolidatable: true
  12631. });
  12632. }
  12633. compositionControllerDidRequestRemovalOfAttachment(attachment) {
  12634. return this.removeAttachment(attachment);
  12635. }
  12636. // Input controller delegate
  12637. inputControllerWillHandleInput() {
  12638. this.handlingInput = true;
  12639. this.requestedRender = false;
  12640. }
  12641. inputControllerDidRequestRender() {
  12642. this.requestedRender = true;
  12643. }
  12644. inputControllerDidHandleInput() {
  12645. this.handlingInput = false;
  12646. if (this.requestedRender) {
  12647. this.requestedRender = false;
  12648. return this.render();
  12649. }
  12650. }
  12651. inputControllerDidAllowUnhandledInput() {
  12652. return this.notifyEditorElement("change");
  12653. }
  12654. inputControllerDidRequestReparse() {
  12655. return this.reparse();
  12656. }
  12657. inputControllerWillPerformTyping() {
  12658. return this.recordTypingUndoEntry();
  12659. }
  12660. inputControllerWillPerformFormatting(attributeName) {
  12661. return this.recordFormattingUndoEntry(attributeName);
  12662. }
  12663. inputControllerWillCutText() {
  12664. return this.editor.recordUndoEntry("Cut");
  12665. }
  12666. inputControllerWillPaste(paste) {
  12667. this.editor.recordUndoEntry("Paste");
  12668. this.pasting = true;
  12669. return this.notifyEditorElement("before-paste", {
  12670. paste
  12671. });
  12672. }
  12673. inputControllerDidPaste(paste) {
  12674. paste.range = this.pastedRange;
  12675. this.pastedRange = null;
  12676. this.pasting = null;
  12677. return this.notifyEditorElement("paste", {
  12678. paste
  12679. });
  12680. }
  12681. inputControllerWillMoveText() {
  12682. return this.editor.recordUndoEntry("Move");
  12683. }
  12684. inputControllerWillAttachFiles() {
  12685. return this.editor.recordUndoEntry("Drop Files");
  12686. }
  12687. inputControllerWillPerformUndo() {
  12688. return this.editor.undo();
  12689. }
  12690. inputControllerWillPerformRedo() {
  12691. return this.editor.redo();
  12692. }
  12693. inputControllerDidReceiveKeyboardCommand(keys) {
  12694. return this.toolbarController.applyKeyboardCommand(keys);
  12695. }
  12696. inputControllerDidStartDrag() {
  12697. this.locationRangeBeforeDrag = this.selectionManager.getLocationRange();
  12698. }
  12699. inputControllerDidReceiveDragOverPoint(point) {
  12700. return this.selectionManager.setLocationRangeFromPointRange(point);
  12701. }
  12702. inputControllerDidCancelDrag() {
  12703. this.selectionManager.setLocationRange(this.locationRangeBeforeDrag);
  12704. this.locationRangeBeforeDrag = null;
  12705. }
  12706. // Selection manager delegate
  12707. locationRangeDidChange(locationRange) {
  12708. this.composition.updateCurrentAttributes();
  12709. this.updateCurrentActions();
  12710. if (this.attachmentLocationRange && !rangesAreEqual(this.attachmentLocationRange, locationRange)) {
  12711. this.composition.stopEditingAttachment();
  12712. }
  12713. return this.notifyEditorElement("selection-change");
  12714. }
  12715. // Toolbar controller delegate
  12716. toolbarDidClickButton() {
  12717. if (!this.getLocationRange()) {
  12718. return this.setLocationRange({
  12719. index: 0,
  12720. offset: 0
  12721. });
  12722. }
  12723. }
  12724. toolbarDidInvokeAction(actionName, invokingElement) {
  12725. return this.invokeAction(actionName, invokingElement);
  12726. }
  12727. toolbarDidToggleAttribute(attributeName) {
  12728. this.recordFormattingUndoEntry(attributeName);
  12729. this.composition.toggleCurrentAttribute(attributeName);
  12730. this.render();
  12731. if (!this.selectionFrozen) {
  12732. return this.editorElement.focus();
  12733. }
  12734. }
  12735. toolbarDidUpdateAttribute(attributeName, value) {
  12736. this.recordFormattingUndoEntry(attributeName);
  12737. this.composition.setCurrentAttribute(attributeName, value);
  12738. this.render();
  12739. if (!this.selectionFrozen) {
  12740. return this.editorElement.focus();
  12741. }
  12742. }
  12743. toolbarDidRemoveAttribute(attributeName) {
  12744. this.recordFormattingUndoEntry(attributeName);
  12745. this.composition.removeCurrentAttribute(attributeName);
  12746. this.render();
  12747. if (!this.selectionFrozen) {
  12748. return this.editorElement.focus();
  12749. }
  12750. }
  12751. toolbarWillShowDialog(dialogElement) {
  12752. this.composition.expandSelectionForEditing();
  12753. return this.freezeSelection();
  12754. }
  12755. toolbarDidShowDialog(dialogName) {
  12756. return this.notifyEditorElement("toolbar-dialog-show", {
  12757. dialogName
  12758. });
  12759. }
  12760. toolbarDidHideDialog(dialogName) {
  12761. this.thawSelection();
  12762. this.editorElement.focus();
  12763. return this.notifyEditorElement("toolbar-dialog-hide", {
  12764. dialogName
  12765. });
  12766. }
  12767. // Selection
  12768. freezeSelection() {
  12769. if (!this.selectionFrozen) {
  12770. this.selectionManager.lock();
  12771. this.composition.freezeSelection();
  12772. this.selectionFrozen = true;
  12773. return this.render();
  12774. }
  12775. }
  12776. thawSelection() {
  12777. if (this.selectionFrozen) {
  12778. this.composition.thawSelection();
  12779. this.selectionManager.unlock();
  12780. this.selectionFrozen = false;
  12781. return this.render();
  12782. }
  12783. }
  12784. canInvokeAction(actionName) {
  12785. if (this.actionIsExternal(actionName)) {
  12786. return true;
  12787. } else {
  12788. var _this$actions$actionN;
  12789. 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));
  12790. }
  12791. }
  12792. invokeAction(actionName, invokingElement) {
  12793. if (this.actionIsExternal(actionName)) {
  12794. return this.notifyEditorElement("action-invoke", {
  12795. actionName,
  12796. invokingElement
  12797. });
  12798. } else {
  12799. var _this$actions$actionN2;
  12800. 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);
  12801. }
  12802. }
  12803. actionIsExternal(actionName) {
  12804. return /^x-./.test(actionName);
  12805. }
  12806. getCurrentActions() {
  12807. const result = {};
  12808. for (const actionName in this.actions) {
  12809. result[actionName] = this.canInvokeAction(actionName);
  12810. }
  12811. return result;
  12812. }
  12813. updateCurrentActions() {
  12814. const currentActions = this.getCurrentActions();
  12815. if (!objectsAreEqual(currentActions, this.currentActions)) {
  12816. this.currentActions = currentActions;
  12817. this.toolbarController.updateActions(this.currentActions);
  12818. return this.notifyEditorElement("actions-change", {
  12819. actions: this.currentActions
  12820. });
  12821. }
  12822. }
  12823. // Editor filters
  12824. runEditorFilters() {
  12825. let snapshot = this.composition.getSnapshot();
  12826. Array.from(this.editor.filters).forEach(filter => {
  12827. const {
  12828. document,
  12829. selectedRange
  12830. } = snapshot;
  12831. snapshot = filter.call(this.editor, snapshot) || {};
  12832. if (!snapshot.document) {
  12833. snapshot.document = document;
  12834. }
  12835. if (!snapshot.selectedRange) {
  12836. snapshot.selectedRange = selectedRange;
  12837. }
  12838. });
  12839. if (!snapshotsAreEqual(snapshot, this.composition.getSnapshot())) {
  12840. return this.composition.loadSnapshot(snapshot);
  12841. }
  12842. }
  12843. // Private
  12844. updateInputElement() {
  12845. const element = this.compositionController.getSerializableElement();
  12846. const value = serializeToContentType(element, "text/html");
  12847. return this.editorElement.setFormValue(value);
  12848. }
  12849. notifyEditorElement(message, data) {
  12850. switch (message) {
  12851. case "document-change":
  12852. this.documentChangedSinceLastRender = true;
  12853. break;
  12854. case "render":
  12855. if (this.documentChangedSinceLastRender) {
  12856. this.documentChangedSinceLastRender = false;
  12857. this.notifyEditorElement("change");
  12858. }
  12859. break;
  12860. case "change":
  12861. case "attachment-add":
  12862. case "attachment-edit":
  12863. case "attachment-remove":
  12864. this.updateInputElement();
  12865. break;
  12866. }
  12867. return this.editorElement.notify(message, data);
  12868. }
  12869. removeAttachment(attachment) {
  12870. this.editor.recordUndoEntry("Delete Attachment");
  12871. this.composition.removeAttachment(attachment);
  12872. return this.render();
  12873. }
  12874. recordFormattingUndoEntry(attributeName) {
  12875. const blockConfig = getBlockConfig(attributeName);
  12876. const locationRange = this.selectionManager.getLocationRange();
  12877. if (blockConfig || !rangeIsCollapsed(locationRange)) {
  12878. return this.editor.recordUndoEntry("Formatting", {
  12879. context: this.getUndoContext(),
  12880. consolidatable: true
  12881. });
  12882. }
  12883. }
  12884. recordTypingUndoEntry() {
  12885. return this.editor.recordUndoEntry("Typing", {
  12886. context: this.getUndoContext(this.currentAttributes),
  12887. consolidatable: true
  12888. });
  12889. }
  12890. getUndoContext() {
  12891. for (var _len = arguments.length, context = new Array(_len), _key = 0; _key < _len; _key++) {
  12892. context[_key] = arguments[_key];
  12893. }
  12894. return [this.getLocationContext(), this.getTimeContext(), ...Array.from(context)];
  12895. }
  12896. getLocationContext() {
  12897. const locationRange = this.selectionManager.getLocationRange();
  12898. if (rangeIsCollapsed(locationRange)) {
  12899. return locationRange[0].index;
  12900. } else {
  12901. return locationRange;
  12902. }
  12903. }
  12904. getTimeContext() {
  12905. if (undo.interval > 0) {
  12906. return Math.floor(new Date().getTime() / undo.interval);
  12907. } else {
  12908. return 0;
  12909. }
  12910. }
  12911. isFocused() {
  12912. var _this$editorElement$o;
  12913. return this.editorElement === ((_this$editorElement$o = this.editorElement.ownerDocument) === null || _this$editorElement$o === void 0 ? void 0 : _this$editorElement$o.activeElement);
  12914. }
  12915. // Detect "Cursor disappears sporadically" Firefox bug.
  12916. // - https://bugzilla.mozilla.org/show_bug.cgi?id=226301
  12917. isFocusedInvisibly() {
  12918. return this.isFocused() && !this.getLocationRange();
  12919. }
  12920. get actions() {
  12921. return this.constructor.actions;
  12922. }
  12923. }
  12924. _defineProperty(EditorController, "actions", {
  12925. undo: {
  12926. test() {
  12927. return this.editor.canUndo();
  12928. },
  12929. perform() {
  12930. return this.editor.undo();
  12931. }
  12932. },
  12933. redo: {
  12934. test() {
  12935. return this.editor.canRedo();
  12936. },
  12937. perform() {
  12938. return this.editor.redo();
  12939. }
  12940. },
  12941. link: {
  12942. test() {
  12943. return this.editor.canActivateAttribute("href");
  12944. }
  12945. },
  12946. increaseNestingLevel: {
  12947. test() {
  12948. return this.editor.canIncreaseNestingLevel();
  12949. },
  12950. perform() {
  12951. return this.editor.increaseNestingLevel() && this.render();
  12952. }
  12953. },
  12954. decreaseNestingLevel: {
  12955. test() {
  12956. return this.editor.canDecreaseNestingLevel();
  12957. },
  12958. perform() {
  12959. return this.editor.decreaseNestingLevel() && this.render();
  12960. }
  12961. },
  12962. attachFiles: {
  12963. test() {
  12964. return true;
  12965. },
  12966. perform() {
  12967. return input.pickFiles(this.editor.insertFiles);
  12968. }
  12969. }
  12970. });
  12971. EditorController.proxyMethod("getSelectionManager().setLocationRange");
  12972. EditorController.proxyMethod("getSelectionManager().getLocationRange");
  12973. var controllers = /*#__PURE__*/Object.freeze({
  12974. __proto__: null,
  12975. AttachmentEditorController: AttachmentEditorController,
  12976. CompositionController: CompositionController,
  12977. Controller: Controller,
  12978. EditorController: EditorController,
  12979. InputController: InputController,
  12980. Level0InputController: Level0InputController,
  12981. Level2InputController: Level2InputController,
  12982. ToolbarController: ToolbarController
  12983. });
  12984. var observers = /*#__PURE__*/Object.freeze({
  12985. __proto__: null,
  12986. MutationObserver: MutationObserver,
  12987. SelectionChangeObserver: SelectionChangeObserver
  12988. });
  12989. var operations = /*#__PURE__*/Object.freeze({
  12990. __proto__: null,
  12991. FileVerificationOperation: FileVerificationOperation,
  12992. ImagePreloadOperation: ImagePreloadOperation
  12993. });
  12994. 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}");
  12995. class TrixToolbarElement extends HTMLElement {
  12996. // Element lifecycle
  12997. connectedCallback() {
  12998. if (this.innerHTML === "") {
  12999. this.innerHTML = toolbar.getDefaultHTML();
  13000. }
  13001. }
  13002. }
  13003. let id = 0;
  13004. // Contenteditable support helpers
  13005. const autofocus = function (element) {
  13006. if (!document.querySelector(":focus")) {
  13007. if (element.hasAttribute("autofocus") && document.querySelector("[autofocus]") === element) {
  13008. return element.focus();
  13009. }
  13010. }
  13011. };
  13012. const makeEditable = function (element) {
  13013. if (element.hasAttribute("contenteditable")) {
  13014. return;
  13015. }
  13016. element.setAttribute("contenteditable", "");
  13017. return handleEventOnce("focus", {
  13018. onElement: element,
  13019. withCallback() {
  13020. return configureContentEditable(element);
  13021. }
  13022. });
  13023. };
  13024. const configureContentEditable = function (element) {
  13025. disableObjectResizing(element);
  13026. return setDefaultParagraphSeparator(element);
  13027. };
  13028. const disableObjectResizing = function (element) {
  13029. var _document$queryComman, _document;
  13030. if ((_document$queryComman = (_document = document).queryCommandSupported) !== null && _document$queryComman !== void 0 && _document$queryComman.call(_document, "enableObjectResizing")) {
  13031. document.execCommand("enableObjectResizing", false, false);
  13032. return handleEvent("mscontrolselect", {
  13033. onElement: element,
  13034. preventDefault: true
  13035. });
  13036. }
  13037. };
  13038. const setDefaultParagraphSeparator = function (element) {
  13039. var _document$queryComman2, _document2;
  13040. if ((_document$queryComman2 = (_document2 = document).queryCommandSupported) !== null && _document$queryComman2 !== void 0 && _document$queryComman2.call(_document2, "DefaultParagraphSeparator")) {
  13041. const {
  13042. tagName
  13043. } = attributes.default;
  13044. if (["div", "p"].includes(tagName)) {
  13045. return document.execCommand("DefaultParagraphSeparator", false, tagName);
  13046. }
  13047. }
  13048. };
  13049. // Accessibility helpers
  13050. const addAccessibilityRole = function (element) {
  13051. if (element.hasAttribute("role")) {
  13052. return;
  13053. }
  13054. return element.setAttribute("role", "textbox");
  13055. };
  13056. const ensureAriaLabel = function (element) {
  13057. if (element.hasAttribute("aria-label") || element.hasAttribute("aria-labelledby")) {
  13058. return;
  13059. }
  13060. const update = function () {
  13061. const texts = Array.from(element.labels).map(label => {
  13062. if (!label.contains(element)) return label.textContent;
  13063. }).filter(text => text);
  13064. const text = texts.join(" ");
  13065. if (text) {
  13066. return element.setAttribute("aria-label", text);
  13067. } else {
  13068. return element.removeAttribute("aria-label");
  13069. }
  13070. };
  13071. update();
  13072. return handleEvent("focus", {
  13073. onElement: element,
  13074. withCallback: update
  13075. });
  13076. };
  13077. // Style
  13078. const cursorTargetStyles = function () {
  13079. if (browser$1.forcesObjectResizing) {
  13080. return {
  13081. display: "inline",
  13082. width: "auto"
  13083. };
  13084. } else {
  13085. return {
  13086. display: "inline-block",
  13087. width: "1px"
  13088. };
  13089. }
  13090. }();
  13091. 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}"));
  13092. var _internals = /*#__PURE__*/new WeakMap();
  13093. var _validate = /*#__PURE__*/new WeakSet();
  13094. class ElementInternalsDelegate {
  13095. constructor(element) {
  13096. _classPrivateMethodInitSpec(this, _validate);
  13097. _classPrivateFieldInitSpec(this, _internals, {
  13098. writable: true,
  13099. value: void 0
  13100. });
  13101. this.element = element;
  13102. _classPrivateFieldSet(this, _internals, element.attachInternals());
  13103. }
  13104. connectedCallback() {
  13105. _classPrivateMethodGet(this, _validate, _validate2).call(this);
  13106. }
  13107. disconnectedCallback() {}
  13108. get labels() {
  13109. return _classPrivateFieldGet(this, _internals).labels;
  13110. }
  13111. get disabled() {
  13112. var _this$element$inputEl;
  13113. return (_this$element$inputEl = this.element.inputElement) === null || _this$element$inputEl === void 0 ? void 0 : _this$element$inputEl.disabled;
  13114. }
  13115. set disabled(value) {
  13116. this.element.toggleAttribute("disabled", value);
  13117. }
  13118. get required() {
  13119. return this.element.hasAttribute("required");
  13120. }
  13121. set required(value) {
  13122. this.element.toggleAttribute("required", value);
  13123. _classPrivateMethodGet(this, _validate, _validate2).call(this);
  13124. }
  13125. get validity() {
  13126. return _classPrivateFieldGet(this, _internals).validity;
  13127. }
  13128. get validationMessage() {
  13129. return _classPrivateFieldGet(this, _internals).validationMessage;
  13130. }
  13131. get willValidate() {
  13132. return _classPrivateFieldGet(this, _internals).willValidate;
  13133. }
  13134. setFormValue(value) {
  13135. _classPrivateMethodGet(this, _validate, _validate2).call(this);
  13136. }
  13137. checkValidity() {
  13138. return _classPrivateFieldGet(this, _internals).checkValidity();
  13139. }
  13140. reportValidity() {
  13141. return _classPrivateFieldGet(this, _internals).reportValidity();
  13142. }
  13143. setCustomValidity(validationMessage) {
  13144. _classPrivateMethodGet(this, _validate, _validate2).call(this, validationMessage);
  13145. }
  13146. }
  13147. function _validate2() {
  13148. let customValidationMessage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
  13149. const {
  13150. required,
  13151. value
  13152. } = this.element;
  13153. const valueMissing = required && !value;
  13154. const customError = !!customValidationMessage;
  13155. const input = makeElement("input", {
  13156. required
  13157. });
  13158. const validationMessage = customValidationMessage || input.validationMessage;
  13159. _classPrivateFieldGet(this, _internals).setValidity({
  13160. valueMissing,
  13161. customError
  13162. }, validationMessage);
  13163. }
  13164. var _focusHandler = /*#__PURE__*/new WeakMap();
  13165. var _resetBubbled = /*#__PURE__*/new WeakMap();
  13166. var _clickBubbled = /*#__PURE__*/new WeakMap();
  13167. class LegacyDelegate {
  13168. constructor(element) {
  13169. _classPrivateFieldInitSpec(this, _focusHandler, {
  13170. writable: true,
  13171. value: void 0
  13172. });
  13173. _classPrivateFieldInitSpec(this, _resetBubbled, {
  13174. writable: true,
  13175. value: event => {
  13176. if (event.defaultPrevented) return;
  13177. if (event.target !== this.element.form) return;
  13178. this.element.reset();
  13179. }
  13180. });
  13181. _classPrivateFieldInitSpec(this, _clickBubbled, {
  13182. writable: true,
  13183. value: event => {
  13184. if (event.defaultPrevented) return;
  13185. if (this.element.contains(event.target)) return;
  13186. const label = findClosestElementFromNode(event.target, {
  13187. matchingSelector: "label"
  13188. });
  13189. if (!label) return;
  13190. if (!Array.from(this.labels).includes(label)) return;
  13191. this.element.focus();
  13192. }
  13193. });
  13194. this.element = element;
  13195. }
  13196. connectedCallback() {
  13197. _classPrivateFieldSet(this, _focusHandler, ensureAriaLabel(this.element));
  13198. window.addEventListener("reset", _classPrivateFieldGet(this, _resetBubbled), false);
  13199. window.addEventListener("click", _classPrivateFieldGet(this, _clickBubbled), false);
  13200. }
  13201. disconnectedCallback() {
  13202. var _classPrivateFieldGet2;
  13203. (_classPrivateFieldGet2 = _classPrivateFieldGet(this, _focusHandler)) === null || _classPrivateFieldGet2 === void 0 || _classPrivateFieldGet2.destroy();
  13204. window.removeEventListener("reset", _classPrivateFieldGet(this, _resetBubbled), false);
  13205. window.removeEventListener("click", _classPrivateFieldGet(this, _clickBubbled), false);
  13206. }
  13207. get labels() {
  13208. const labels = [];
  13209. if (this.element.id && this.element.ownerDocument) {
  13210. labels.push(...Array.from(this.element.ownerDocument.querySelectorAll("label[for='".concat(this.element.id, "']")) || []));
  13211. }
  13212. const label = findClosestElementFromNode(this.element, {
  13213. matchingSelector: "label"
  13214. });
  13215. if (label) {
  13216. if ([this.element, null].includes(label.control)) {
  13217. labels.push(label);
  13218. }
  13219. }
  13220. return labels;
  13221. }
  13222. get disabled() {
  13223. console.warn("This browser does not support the [disabled] attribute for trix-editor elements.");
  13224. return false;
  13225. }
  13226. set disabled(value) {
  13227. console.warn("This browser does not support the [disabled] attribute for trix-editor elements.");
  13228. }
  13229. get required() {
  13230. console.warn("This browser does not support the [required] attribute for trix-editor elements.");
  13231. return false;
  13232. }
  13233. set required(value) {
  13234. console.warn("This browser does not support the [required] attribute for trix-editor elements.");
  13235. }
  13236. get validity() {
  13237. console.warn("This browser does not support the validity property for trix-editor elements.");
  13238. return null;
  13239. }
  13240. get validationMessage() {
  13241. console.warn("This browser does not support the validationMessage property for trix-editor elements.");
  13242. return "";
  13243. }
  13244. get willValidate() {
  13245. console.warn("This browser does not support the willValidate property for trix-editor elements.");
  13246. return false;
  13247. }
  13248. setFormValue(value) {}
  13249. checkValidity() {
  13250. console.warn("This browser does not support checkValidity() for trix-editor elements.");
  13251. return true;
  13252. }
  13253. reportValidity() {
  13254. console.warn("This browser does not support reportValidity() for trix-editor elements.");
  13255. return true;
  13256. }
  13257. setCustomValidity(validationMessage) {
  13258. console.warn("This browser does not support setCustomValidity(validationMessage) for trix-editor elements.");
  13259. }
  13260. }
  13261. var _delegate = /*#__PURE__*/new WeakMap();
  13262. class TrixEditorElement extends HTMLElement {
  13263. constructor() {
  13264. super();
  13265. _classPrivateFieldInitSpec(this, _delegate, {
  13266. writable: true,
  13267. value: void 0
  13268. });
  13269. _classPrivateFieldSet(this, _delegate, this.constructor.formAssociated ? new ElementInternalsDelegate(this) : new LegacyDelegate(this));
  13270. }
  13271. // Properties
  13272. get trixId() {
  13273. if (this.hasAttribute("trix-id")) {
  13274. return this.getAttribute("trix-id");
  13275. } else {
  13276. this.setAttribute("trix-id", ++id);
  13277. return this.trixId;
  13278. }
  13279. }
  13280. get labels() {
  13281. return _classPrivateFieldGet(this, _delegate).labels;
  13282. }
  13283. get disabled() {
  13284. return _classPrivateFieldGet(this, _delegate).disabled;
  13285. }
  13286. set disabled(value) {
  13287. _classPrivateFieldGet(this, _delegate).disabled = value;
  13288. }
  13289. get required() {
  13290. return _classPrivateFieldGet(this, _delegate).required;
  13291. }
  13292. set required(value) {
  13293. _classPrivateFieldGet(this, _delegate).required = value;
  13294. }
  13295. get validity() {
  13296. return _classPrivateFieldGet(this, _delegate).validity;
  13297. }
  13298. get validationMessage() {
  13299. return _classPrivateFieldGet(this, _delegate).validationMessage;
  13300. }
  13301. get willValidate() {
  13302. return _classPrivateFieldGet(this, _delegate).willValidate;
  13303. }
  13304. get type() {
  13305. return this.localName;
  13306. }
  13307. get toolbarElement() {
  13308. if (this.hasAttribute("toolbar")) {
  13309. var _this$ownerDocument;
  13310. return (_this$ownerDocument = this.ownerDocument) === null || _this$ownerDocument === void 0 ? void 0 : _this$ownerDocument.getElementById(this.getAttribute("toolbar"));
  13311. } else if (this.parentNode) {
  13312. const toolbarId = "trix-toolbar-".concat(this.trixId);
  13313. this.setAttribute("toolbar", toolbarId);
  13314. const element = makeElement("trix-toolbar", {
  13315. id: toolbarId
  13316. });
  13317. this.parentNode.insertBefore(element, this);
  13318. return element;
  13319. } else {
  13320. return undefined;
  13321. }
  13322. }
  13323. get form() {
  13324. var _this$inputElement;
  13325. return (_this$inputElement = this.inputElement) === null || _this$inputElement === void 0 ? void 0 : _this$inputElement.form;
  13326. }
  13327. get inputElement() {
  13328. if (this.hasAttribute("input")) {
  13329. var _this$ownerDocument2;
  13330. return (_this$ownerDocument2 = this.ownerDocument) === null || _this$ownerDocument2 === void 0 ? void 0 : _this$ownerDocument2.getElementById(this.getAttribute("input"));
  13331. } else if (this.parentNode) {
  13332. const inputId = "trix-input-".concat(this.trixId);
  13333. this.setAttribute("input", inputId);
  13334. const element = makeElement("input", {
  13335. type: "hidden",
  13336. id: inputId
  13337. });
  13338. this.parentNode.insertBefore(element, this.nextElementSibling);
  13339. return element;
  13340. } else {
  13341. return undefined;
  13342. }
  13343. }
  13344. get editor() {
  13345. var _this$editorControlle;
  13346. return (_this$editorControlle = this.editorController) === null || _this$editorControlle === void 0 ? void 0 : _this$editorControlle.editor;
  13347. }
  13348. get name() {
  13349. var _this$inputElement2;
  13350. return (_this$inputElement2 = this.inputElement) === null || _this$inputElement2 === void 0 ? void 0 : _this$inputElement2.name;
  13351. }
  13352. get value() {
  13353. var _this$inputElement3;
  13354. return (_this$inputElement3 = this.inputElement) === null || _this$inputElement3 === void 0 ? void 0 : _this$inputElement3.value;
  13355. }
  13356. set value(defaultValue) {
  13357. var _this$editor;
  13358. this.defaultValue = defaultValue;
  13359. (_this$editor = this.editor) === null || _this$editor === void 0 || _this$editor.loadHTML(this.defaultValue);
  13360. }
  13361. // Controller delegate methods
  13362. notify(message, data) {
  13363. if (this.editorController) {
  13364. return triggerEvent("trix-".concat(message), {
  13365. onElement: this,
  13366. attributes: data
  13367. });
  13368. }
  13369. }
  13370. setFormValue(value) {
  13371. if (this.inputElement) {
  13372. this.inputElement.value = value;
  13373. _classPrivateFieldGet(this, _delegate).setFormValue(value);
  13374. }
  13375. }
  13376. // Element lifecycle
  13377. connectedCallback() {
  13378. if (!this.hasAttribute("data-trix-internal")) {
  13379. makeEditable(this);
  13380. addAccessibilityRole(this);
  13381. if (!this.editorController) {
  13382. triggerEvent("trix-before-initialize", {
  13383. onElement: this
  13384. });
  13385. this.editorController = new EditorController({
  13386. editorElement: this,
  13387. html: this.defaultValue = this.value
  13388. });
  13389. requestAnimationFrame(() => triggerEvent("trix-initialize", {
  13390. onElement: this
  13391. }));
  13392. }
  13393. this.editorController.registerSelectionManager();
  13394. _classPrivateFieldGet(this, _delegate).connectedCallback();
  13395. autofocus(this);
  13396. }
  13397. }
  13398. disconnectedCallback() {
  13399. var _this$editorControlle2;
  13400. (_this$editorControlle2 = this.editorController) === null || _this$editorControlle2 === void 0 || _this$editorControlle2.unregisterSelectionManager();
  13401. _classPrivateFieldGet(this, _delegate).disconnectedCallback();
  13402. }
  13403. // Form support
  13404. checkValidity() {
  13405. return _classPrivateFieldGet(this, _delegate).checkValidity();
  13406. }
  13407. reportValidity() {
  13408. return _classPrivateFieldGet(this, _delegate).reportValidity();
  13409. }
  13410. setCustomValidity(validationMessage) {
  13411. _classPrivateFieldGet(this, _delegate).setCustomValidity(validationMessage);
  13412. }
  13413. formDisabledCallback(disabled) {
  13414. if (this.inputElement) {
  13415. this.inputElement.disabled = disabled;
  13416. }
  13417. this.toggleAttribute("contenteditable", !disabled);
  13418. }
  13419. formResetCallback() {
  13420. this.reset();
  13421. }
  13422. reset() {
  13423. this.value = this.defaultValue;
  13424. }
  13425. }
  13426. _defineProperty(TrixEditorElement, "formAssociated", "ElementInternals" in window);
  13427. var elements = /*#__PURE__*/Object.freeze({
  13428. __proto__: null,
  13429. TrixEditorElement: TrixEditorElement,
  13430. TrixToolbarElement: TrixToolbarElement
  13431. });
  13432. var filters = /*#__PURE__*/Object.freeze({
  13433. __proto__: null,
  13434. Filter: Filter,
  13435. attachmentGalleryFilter: attachmentGalleryFilter
  13436. });
  13437. const Trix = {
  13438. VERSION: version,
  13439. config,
  13440. core,
  13441. models,
  13442. views,
  13443. controllers,
  13444. observers,
  13445. operations,
  13446. elements,
  13447. filters
  13448. };
  13449. // Expose models under the Trix constant for compatibility with v1
  13450. Object.assign(Trix, models);
  13451. function start() {
  13452. if (!customElements.get("trix-toolbar")) {
  13453. customElements.define("trix-toolbar", TrixToolbarElement);
  13454. }
  13455. if (!customElements.get("trix-editor")) {
  13456. customElements.define("trix-editor", TrixEditorElement);
  13457. }
  13458. }
  13459. window.Trix = Trix;
  13460. setTimeout(start, 0);
  13461. return Trix;
  13462. }));