@ebl-vue/editorjs 2.31.9 → 2.31.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editorjs.mjs +862 -816
- package/dist/editorjs.mjs.map +1 -0
- package/dist/editorjs.umd.js +13 -12
- package/dist/editorjs.umd.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editorjs.umd.js","sources":["../../../node_modules/@babel/register/lib/browser.cjs","../src/components/polyfills.ts","../node_modules/nanoid/index.browser.js","../src/components/utils.ts","../src/components/dom.ts","../src/components/i18n/index.ts","../src/components/errors/critical.ts","../src/components/utils/events.ts","../src/components/block/api.ts","../src/components/utils/listeners.ts","../src/components/__module.ts","../src/components/selection.ts","../src/components/utils/mutations.ts","../src/components/events/RedactorDomChanged.ts","../src/components/events/BlockChanged.ts","../src/components/events/FakeCursorAboutToBeToggled.ts","../src/components/events/FakeCursorHaveBeenSet.ts","../src/components/events/EditorMobileLayoutToggled.ts","../src/components/utils/tools.ts","../src/components/utils/blocks.ts","../types/utils/popover/popover-item-type.ts","../src/components/block/index.ts","../src/components/modules/api/blocks.ts","../src/components/utils/api.ts","../src/components/modules/api/caret.ts","../src/components/modules/api/events.ts","../src/components/modules/api/i18n.ts","../src/components/modules/api/index.ts","../src/components/modules/api/inlineToolbar.ts","../src/components/modules/api/listeners.ts","../../../node_modules/codex-notifier/dist/bundle.js","../src/components/utils/notifier.ts","../src/components/modules/api/notifier.ts","../src/components/modules/api/readonly.ts","../../../node_modules/html-janitor/src/html-janitor.js","../src/components/utils/sanitizer.ts","../src/components/modules/api/sanitizer.ts","../src/components/modules/api/saver.ts","../src/components/modules/api/selection.ts","../src/components/modules/api/tools.ts","../src/components/modules/api/styles.ts","../src/components/modules/api/toolbar.ts","../../../node_modules/codex-tooltip/dist/tooltip.js","../src/components/utils/tooltip.ts","../src/components/modules/api/tooltip.ts","../src/components/modules/api/ui.ts","../src/components/i18n/namespace-internal.ts","../src/components/utils/resolve-aliases.ts","../src/components/domIterator.ts","../src/components/flipper.ts","../node_modules/@codexteam/icons/dist/index.mjs","../src/components/utils/bem.ts","../src/components/utils/popover/components/hint/hint.const.ts","../src/components/utils/popover/components/hint/hint.ts","../src/components/utils/popover/components/popover-item/popover-item.ts","../src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts","../src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts","../src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.const.ts","../src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.ts","../types/utils/popover/popover-event.ts","../src/components/utils/popover/popover.const.ts","../src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.const.ts","../src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.ts","../src/components/utils/popover/popover-abstract.ts","../src/components/utils/popover/components/search-input/search-input.types.ts","../src/components/utils/popover/components/search-input/search-input.const.ts","../src/components/utils/popover/components/search-input/search-input.ts","../src/components/utils/popover/popover-desktop.ts","../src/components/utils/popover/popover-inline.ts","../src/components/utils/scroll-locker.ts","../src/components/utils/popover/components/popover-header/popover-header.const.ts","../src/components/utils/popover/components/popover-header/popover-header.ts","../src/components/utils/popover/utils/popover-states-history.ts","../src/components/utils/popover/popover-mobile.ts","../src/components/modules/toolbar/blockSettings.ts","../../../node_modules/@codexteam/shortcuts/dist/shortcuts.js","../src/components/utils/shortcuts.ts","../src/components/ui/toolbox.ts","../src/components/events/BlockHovered.ts","../src/components/utils/keyboard.ts","../src/components/modules/toolbar/toolbarIcon.ts","../src/components/modules/toolbar/index.ts","../types/tools/adapters/tool-type.ts","../src/components/tools/base.ts","../src/components/modules/toolbar/inline.ts","../src/components/utils/caret.ts","../../../node_modules/@editorjs/dom/dist/allInputsSelector/allInputsSelector.js","../../../node_modules/@editorjs/dom/dist/allInputsSelector/index.js","../../../node_modules/@editorjs/dom/dist/isNativeInput/isNativeInput.js","../../../node_modules/@editorjs/dom/dist/isNativeInput/index.js","../../../node_modules/@editorjs/dom/dist/append/append.js","../../../node_modules/@editorjs/dom/dist/append/index.js","../../../node_modules/@editorjs/dom/dist/blockElements/blockElements.js","../../../node_modules/@editorjs/dom/dist/blockElements/index.js","../../../node_modules/@editorjs/dom/dist/calculateBaseline/calculateBaseline.js","../../../node_modules/@editorjs/dom/dist/calculateBaseline/index.js","../../../node_modules/@editorjs/dom/dist/isContentEditable/isContentEditable.js","../../../node_modules/@editorjs/dom/dist/isContentEditable/index.js","../../../node_modules/@editorjs/dom/dist/canSetCaret/canSetCaret.js","../../../node_modules/@editorjs/dom/dist/canSetCaret/index.js","../../../node_modules/@editorjs/helpers/dist/cacheable/cacheable.js","../../../node_modules/@editorjs/helpers/dist/userOS/getUserOS.js","../../../node_modules/@editorjs/helpers/dist/empty/notEmpty.js","../../../node_modules/@editorjs/helpers/dist/empty/isEmpty.js","../../../node_modules/@editorjs/helpers/dist/userOS/isIosDevice.js","../../../node_modules/@editorjs/helpers/dist/beautifyShortcut/beautifyShortcut.js","../../../node_modules/@editorjs/helpers/dist/capitalize/capitalize.js","../../../node_modules/@editorjs/helpers/dist/copyTextToClipboard/copyTextToClipboard.js","../../../node_modules/@editorjs/helpers/dist/debounce/debounce.js","../../../node_modules/@editorjs/helpers/dist/typeOf/typeOf.js","../../../node_modules/@editorjs/helpers/dist/typeOf/isBoolean.js","../../../node_modules/@editorjs/helpers/dist/typeOf/isFunction.js","../../../node_modules/@editorjs/helpers/dist/typeOf/isClass.js","../../../node_modules/@editorjs/helpers/dist/typeOf/isNumber.js","../../../node_modules/@editorjs/helpers/dist/typeOf/isObject.js","../../../node_modules/@editorjs/helpers/dist/typeOf/isPromise.js","../../../node_modules/@editorjs/helpers/dist/typeOf/isString.js","../../../node_modules/@editorjs/helpers/dist/typeOf/isUndefined.js","../../../node_modules/@editorjs/helpers/dist/deepMerge/deepMerge.js","../../../node_modules/@editorjs/helpers/dist/deprecationAssert/deprecationAssert.js","../../../node_modules/@editorjs/helpers/dist/getValidUrl/getValidUrl.js","../../../node_modules/@editorjs/helpers/dist/isPrintableKey/isPrintableKey.js","../../../node_modules/@editorjs/helpers/dist/keyCodes/keyCodes.js","../../../node_modules/@editorjs/helpers/dist/keyCodes/mouseButtons.js","../../../node_modules/@editorjs/helpers/dist/promiseQueue/promiseQueue.js","../../../node_modules/@editorjs/helpers/dist/throttle/throttle.js","../../../node_modules/@editorjs/dom/dist/containsOnlyInlineElements/containsOnlyInlineElements.js","../../../node_modules/@editorjs/dom/dist/containsOnlyInlineElements/index.js","../../../node_modules/@editorjs/dom/dist/make/make.js","../../../node_modules/@editorjs/dom/dist/make/index.js","../../../node_modules/@editorjs/dom/dist/fragmentToString/fragmentToString.js","../../../node_modules/@editorjs/dom/dist/fragmentToString/index.js","../../../node_modules/@editorjs/dom/dist/getContentLength/getContentLength.js","../../../node_modules/@editorjs/dom/dist/getContentLength/index.js","../../../node_modules/@editorjs/dom/dist/getDeepestBlockElements/getDeepestBlockElements.js","../../../node_modules/@editorjs/dom/dist/getDeepestBlockElements/index.js","../../../node_modules/@editorjs/dom/dist/isLineBreakTag/isLineBreakTag.js","../../../node_modules/@editorjs/dom/dist/isLineBreakTag/index.js","../../../node_modules/@editorjs/dom/dist/isSingleTag/isSingleTag.js","../../../node_modules/@editorjs/dom/dist/isSingleTag/index.js","../../../node_modules/@editorjs/dom/dist/getDeepestNode/getDeepestNode.js","../../../node_modules/@editorjs/dom/dist/getDeepestNode/index.js","../../../node_modules/@editorjs/dom/dist/findAllInputs/findAllInputs.js","../../../node_modules/@editorjs/dom/dist/findAllInputs/index.js","../../../node_modules/@editorjs/dom/dist/isCollapsedWhitespaces/isCollapsedWhitespaces.js","../../../node_modules/@editorjs/dom/dist/isCollapsedWhitespaces/index.js","../../../node_modules/@editorjs/dom/dist/isElement/isElement.js","../../../node_modules/@editorjs/dom/dist/isElement/index.js","../../../node_modules/@editorjs/dom/dist/isLeaf/isLeaf.js","../../../node_modules/@editorjs/dom/dist/isLeaf/index.js","../../../node_modules/@editorjs/dom/dist/isNodeEmpty/isNodeEmpty.js","../../../node_modules/@editorjs/dom/dist/isNodeEmpty/index.js","../../../node_modules/@editorjs/dom/dist/isEmpty/isEmpty.js","../../../node_modules/@editorjs/dom/dist/isEmpty/index.js","../../../node_modules/@editorjs/dom/dist/isFragment/isFragment.js","../../../node_modules/@editorjs/dom/dist/isFragment/index.js","../../../node_modules/@editorjs/dom/dist/isHtmlString/isHtmlString.js","../../../node_modules/@editorjs/dom/dist/isHtmlString/index.js","../../../node_modules/@editorjs/dom/dist/offset/offset.js","../../../node_modules/@editorjs/dom/dist/offset/index.js","../../../node_modules/@editorjs/dom/dist/prepend/prepend.js","../../../node_modules/@editorjs/dom/dist/prepend/index.js","../../../node_modules/@editorjs/dom/dist/index.js","../../../node_modules/@editorjs/caret/dist/getContenteditableSlice/getContenteditableSlice.js","../../../node_modules/@editorjs/caret/dist/checkContenteditableSliceForEmptiness/checkContenteditableSliceForEmptiness.js","../../../node_modules/@editorjs/caret/dist/checkContenteditableSliceForEmptiness/index.js","../../../node_modules/@editorjs/caret/dist/getContenteditableSlice/index.js","../../../node_modules/@editorjs/caret/dist/focus/focus.js","../../../node_modules/@editorjs/caret/dist/focus/index.js","../../../node_modules/@editorjs/caret/dist/getCaretNodeAndOffset/getCaretNodeAndOffset.js","../../../node_modules/@editorjs/caret/dist/getCaretNodeAndOffset/index.js","../../../node_modules/@editorjs/caret/dist/getRange/getRange.js","../../../node_modules/@editorjs/caret/dist/getRange/index.js","../../../node_modules/@editorjs/caret/dist/isCaretAtEndOfInput/isCaretAtEndOfInput.js","../../../node_modules/@editorjs/caret/dist/isCaretAtEndOfInput/index.js","../../../node_modules/@editorjs/caret/dist/isCaretAtStartOfInput/isCaretAtStartOfInput.js","../../../node_modules/@editorjs/caret/dist/isCaretAtStartOfInput/index.js","../../../node_modules/@editorjs/caret/dist/save/save.js","../../../node_modules/@editorjs/caret/dist/save/index.js","../../../node_modules/@editorjs/caret/dist/index.js","../src/components/modules/blockEvents.ts","../src/components/blocks.ts","../types/events/block/BlockRemoved.ts","../types/events/block/BlockAdded.ts","../types/events/block/BlockMoved.ts","../types/events/block/BlockChanged.ts","../src/components/utils/promise-queue.ts","../src/components/modules/blockManager.ts","../src/components/modules/blockSelection.ts","../src/components/modules/caret.ts","../src/components/modules/crossBlockSelection.ts","../src/components/modules/dragNDrop.ts","../src/components/constants.ts","../src/components/modules/modificationsObserver.ts","../src/components/modules/paste.ts","../src/components/modules/readonly.ts","../src/components/modules/rectangleSelection.ts","../src/components/modules/renderer.ts","../src/components/modules/saver.ts","../../../node_modules/@editorjs/paragraph/dist/paragraph.mjs","../src/components/inline-tools/inline-tool-bold.ts","../src/components/inline-tools/inline-tool-italic.ts","../src/components/inline-tools/inline-tool-link.ts","../src/components/inline-tools/inline-tool-convert.ts","../src/tools/stub/index.ts","../src/components/tools/inline.ts","../src/components/tools/tune.ts","../src/components/tools/collection.ts","../src/components/tools/block.ts","../src/components/tools/factory.ts","../src/components/block-tunes/block-tune-move-down.ts","../src/components/block-tunes/block-tune-delete.ts","../src/components/block-tunes/block-tune-move-up.ts","../src/components/modules/tools.ts","../src/components/modules/ui.ts","../src/components/modules/index.ts","../src/components/core.ts","../src/codex.ts"],"sourcesContent":["function register() {}\nmodule.exports = Object.assign(register, {\n default: register,\n register,\n revert: function revert() {},\n __esModule: true\n});\n\n//# sourceMappingURL=browser.cjs.map\n","'use strict';\r\n\r\n/**\r\n * Extend Element interface to include prefixed and experimental properties\r\n */\r\ninterface Element {\r\n matchesSelector: (selector: string) => boolean;\r\n mozMatchesSelector: (selector: string) => boolean;\r\n msMatchesSelector: (selector: string) => boolean;\r\n oMatchesSelector: (selector: string) => boolean;\r\n\r\n prepend: (...nodes: Array<string | Node>) => void;\r\n append: (...nodes: Array<string | Node>) => void;\r\n}\r\n\r\n/**\r\n * The Element.matches() method returns true if the element\r\n * would be selected by the specified selector string;\r\n * otherwise, returns false.\r\n *\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill}\r\n * @param {string} s - selector\r\n */\r\nif (!Element.prototype.matches) {\r\n Element.prototype.matches = Element.prototype.matchesSelector ||\r\n Element.prototype.mozMatchesSelector ||\r\n Element.prototype.msMatchesSelector ||\r\n Element.prototype.oMatchesSelector ||\r\n Element.prototype.webkitMatchesSelector ||\r\n function (s): boolean {\r\n const matches = (this.document || this.ownerDocument).querySelectorAll(s);\r\n let i = matches.length;\r\n\r\n while (--i >= 0 && matches.item(i) !== this) {\r\n }\r\n\r\n return i > -1;\r\n };\r\n}\r\n\r\n/**\r\n * The Element.closest() method returns the closest ancestor\r\n * of the current element (or the current element itself) which\r\n * matches the selectors given in parameter.\r\n * If there isn't such an ancestor, it returns null.\r\n *\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill}\r\n * @param {string} s - selector\r\n */\r\nif (!Element.prototype.closest) {\r\n Element.prototype.closest = function (s): Element | null {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n let el = this;\r\n\r\n if (!document.documentElement.contains(el)) {\r\n return null;\r\n }\r\n\r\n do {\r\n if (el.matches(s)) {\r\n return el;\r\n }\r\n\r\n el = el.parentElement || el.parentNode;\r\n } while (el !== null);\r\n\r\n return null;\r\n };\r\n}\r\n\r\n/**\r\n * The ParentNode.prepend method inserts a set of Node objects\r\n * or DOMString objects before the first child of the ParentNode.\r\n * DOMString objects are inserted as equivalent Text nodes.\r\n *\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/prepend#Polyfill}\r\n * @param {Node | Node[] | string | string[]} nodes - nodes to prepend\r\n */\r\nif (!Element.prototype.prepend) {\r\n Element.prototype.prepend = function prepend(nodes: Array<Node | string> | Node | string): void {\r\n const docFrag = document.createDocumentFragment();\r\n\r\n if (!Array.isArray(nodes)) {\r\n nodes = [ nodes ];\r\n }\r\n\r\n nodes.forEach((node: Node | string) => {\r\n const isNode = node instanceof Node;\r\n\r\n docFrag.appendChild(isNode ? node as Node : document.createTextNode(node as string));\r\n });\r\n\r\n this.insertBefore(docFrag, this.firstChild);\r\n };\r\n}\r\n\r\ninterface Element {\r\n /**\r\n * Scrolls the current element into the visible area of the browser window\r\n *\r\n * @param centerIfNeeded - true, if the element should be aligned so it is centered within the visible area of the scrollable ancestor.\r\n */\r\n scrollIntoViewIfNeeded(centerIfNeeded?: boolean): void;\r\n}\r\n\r\n/**\r\n * ScrollIntoViewIfNeeded polyfill by KilianSSL (forked from hsablonniere)\r\n *\r\n * @see {@link https://gist.github.com/KilianSSL/774297b76378566588f02538631c3137}\r\n * @param centerIfNeeded - true, if the element should be aligned so it is centered within the visible area of the scrollable ancestor.\r\n */\r\nif (!Element.prototype.scrollIntoViewIfNeeded) {\r\n Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded): void {\r\n centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded;\r\n\r\n const parent = this.parentNode,\r\n parentComputedStyle = window.getComputedStyle(parent, null),\r\n parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),\r\n parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),\r\n overTop = this.offsetTop - parent.offsetTop < parent.scrollTop,\r\n overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),\r\n overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft,\r\n overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),\r\n alignWithTop = overTop && !overBottom;\r\n\r\n if ((overTop || overBottom) && centerIfNeeded) {\r\n parent.scrollTop = this.offsetTop - parent.offsetTop - parent.clientHeight / 2 - parentBorderTopWidth + this.clientHeight / 2;\r\n }\r\n\r\n if ((overLeft || overRight) && centerIfNeeded) {\r\n parent.scrollLeft = this.offsetLeft - parent.offsetLeft - parent.clientWidth / 2 - parentBorderLeftWidth + this.clientWidth / 2;\r\n }\r\n\r\n if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {\r\n this.scrollIntoView(alignWithTop);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * RequestIdleCallback polyfill (shims)\r\n *\r\n * @see https://developer.chrome.com/blog/using-requestidlecallback/\r\n * @param cb - callback to be executed when the browser is idle\r\n */\r\nwindow.requestIdleCallback = window.requestIdleCallback || function (cb) {\r\n const start = Date.now();\r\n\r\n return setTimeout(function () {\r\n cb({\r\n didTimeout: false,\r\n timeRemaining: function () {\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n return Math.max(0, 50 - (Date.now() - start));\r\n },\r\n });\r\n }, 1);\r\n};\r\n\r\nwindow.cancelIdleCallback = window.cancelIdleCallback || function (id) {\r\n clearTimeout(id);\r\n};\r\n","export { urlAlphabet } from './url-alphabet/index.js'\nexport let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))\nexport let customRandom = (alphabet, defaultSize, getRandom) => {\n let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1\n let step = -~((1.6 * mask * defaultSize) / alphabet.length)\n return (size = defaultSize) => {\n let id = ''\n while (true) {\n let bytes = getRandom(step)\n let j = step\n while (j--) {\n id += alphabet[bytes[j] & mask] || ''\n if (id.length === size) return id\n }\n }\n }\n}\nexport let customAlphabet = (alphabet, size = 21) =>\n customRandom(alphabet, size, random)\nexport let nanoid = (size = 21) =>\n crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {\n byte &= 63\n if (byte < 36) {\n id += byte.toString(36)\n } else if (byte < 62) {\n id += (byte - 26).toString(36).toUpperCase()\n } else if (byte > 62) {\n id += '-'\n } else {\n id += '_'\n }\n return id\n }, '')\n","/**\r\n * Class Util\r\n */\r\n\r\nimport { nanoid } from 'nanoid';\r\nimport Dom from './dom';\r\n\r\n/**\r\n * Possible log levels\r\n */\r\nexport enum LogLevels {\r\n VERBOSE = 'VERBOSE',\r\n INFO = 'INFO',\r\n WARN = 'WARN',\r\n ERROR = 'ERROR',\r\n}\r\n\r\n/**\r\n * Allow to use global VERSION, that will be overwritten by Webpack\r\n */\r\ndeclare const VERSION: string;\r\n\r\n/**\r\n * @typedef {object} ChainData\r\n * @property {object} data - data that will be passed to the success or fallback\r\n * @property {Function} function - function's that must be called asynchronously\r\n * @interface ChainData\r\n */\r\nexport interface ChainData {\r\n data?: object;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n function: (...args: any[]) => any;\r\n}\r\n\r\n/**\r\n * Editor.js utils\r\n */\r\n\r\n/**\r\n * Returns basic key codes as constants\r\n *\r\n * @returns {{}}\r\n */\r\nexport const keyCodes = {\r\n BACKSPACE: 8,\r\n TAB: 9,\r\n ENTER: 13,\r\n SHIFT: 16,\r\n CTRL: 17,\r\n ALT: 18,\r\n ESC: 27,\r\n SPACE: 32,\r\n LEFT: 37,\r\n UP: 38,\r\n DOWN: 40,\r\n RIGHT: 39,\r\n DELETE: 46,\r\n META: 91,\r\n SLASH: 191,\r\n};\r\n\r\n/**\r\n * Return mouse buttons codes\r\n */\r\nexport const mouseButtons = {\r\n LEFT: 0,\r\n WHEEL: 1,\r\n RIGHT: 2,\r\n BACKWARD: 3,\r\n FORWARD: 4,\r\n};\r\n\r\n/**\r\n * Custom logger\r\n *\r\n * @param {boolean} labeled — if true, Editor.js label is shown\r\n * @param {string} msg - message\r\n * @param {string} type - logging type 'log'|'warn'|'error'|'info'\r\n * @param {*} [args] - argument to log with a message\r\n * @param {string} style - additional styling to message\r\n */\r\nfunction _log(\r\n labeled: boolean,\r\n msg: string,\r\n type = 'log',\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n args?: any,\r\n style = 'color: inherit'\r\n): void {\r\n if (!('console' in window) || !window.console[type]) {\r\n return;\r\n }\r\n\r\n const isSimpleType = ['info', 'log', 'warn', 'error'].includes(type);\r\n const argsToPass = [];\r\n\r\n switch (_log.logLevel) {\r\n case LogLevels.ERROR:\r\n if (type !== 'error') {\r\n return;\r\n }\r\n break;\r\n\r\n case LogLevels.WARN:\r\n if (!['error', 'warn'].includes(type)) {\r\n return;\r\n }\r\n break;\r\n\r\n case LogLevels.INFO:\r\n if (!isSimpleType || labeled) {\r\n return;\r\n }\r\n break;\r\n }\r\n\r\n if (args) {\r\n argsToPass.push(args);\r\n }\r\n\r\n const editorLabelText = `Editor.js ${VERSION}`;\"Editor.js 2.31.0\"; //\r\n const editorLabelStyle = `line-height: 1em;\r\n color: #006FEA;\r\n display: inline-block;\r\n font-size: 11px;\r\n line-height: 1em;\r\n background-color: #fff;\r\n padding: 4px 9px;\r\n border-radius: 30px;\r\n border: 1px solid rgba(56, 138, 229, 0.16);\r\n margin: 4px 5px 4px 0;`;\r\n\r\n if (labeled) {\r\n if (isSimpleType) {\r\n argsToPass.unshift(editorLabelStyle, style);\r\n msg = `%c${editorLabelText}%c ${msg}`;\r\n } else {\r\n msg = `( ${editorLabelText} )${msg}`;\r\n }\r\n }\r\n\r\n try {\r\n if (!isSimpleType) {\r\n console[type](msg);\r\n } else if (args) {\r\n console[type](`${msg} %o`, ...argsToPass);\r\n } else {\r\n console[type](msg, ...argsToPass);\r\n }\r\n } catch (ignored) {}\r\n}\r\n\r\n/**\r\n * Current log level\r\n */\r\n_log.logLevel = LogLevels.VERBOSE;\r\n\r\n/**\r\n * Set current log level\r\n *\r\n * @param {LogLevels} logLevel - log level to set\r\n */\r\nexport function setLogLevel(logLevel: LogLevels): void {\r\n _log.logLevel = logLevel;\r\n}\r\n\r\n/**\r\n * _log method proxy without Editor.js label\r\n */\r\nexport const log = _log.bind(window, false);\r\n\r\n/**\r\n * _log method proxy with Editor.js label\r\n */\r\nexport const logLabeled = _log.bind(window, true);\r\n\r\n/**\r\n * Return string representation of the object type\r\n *\r\n * @param {*} object - object to get type\r\n * @returns {string}\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function typeOf(object: any): string {\r\n return Object.prototype.toString.call(object).match(/\\s([a-zA-Z]+)/)[1].toLowerCase();\r\n}\r\n\r\n/**\r\n * Check if passed variable is a function\r\n *\r\n * @param {*} fn - function to check\r\n * @returns {boolean}\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function isFunction(fn: any): fn is (...args: any[]) => any {\r\n return typeOf(fn) === 'function' || typeOf(fn) === 'asyncfunction';\r\n}\r\n\r\n/**\r\n * Checks if passed argument is an object\r\n *\r\n * @param {*} v - object to check\r\n * @returns {boolean}\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function isObject(v: any): v is object {\r\n return typeOf(v) === 'object';\r\n}\r\n\r\n/**\r\n * Checks if passed argument is a string\r\n *\r\n * @param {*} v - variable to check\r\n * @returns {boolean}\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function isString(v: any): v is string {\r\n return typeOf(v) === 'string';\r\n}\r\n\r\n/**\r\n * Checks if passed argument is boolean\r\n *\r\n * @param {*} v - variable to check\r\n * @returns {boolean}\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function isBoolean(v: any): v is boolean {\r\n return typeOf(v) === 'boolean';\r\n}\r\n\r\n/**\r\n * Checks if passed argument is number\r\n *\r\n * @param {*} v - variable to check\r\n * @returns {boolean}\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function isNumber(v: any): v is number {\r\n return typeOf(v) === 'number';\r\n}\r\n\r\n/**\r\n * Checks if passed argument is undefined\r\n *\r\n * @param {*} v - variable to check\r\n * @returns {boolean}\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function isUndefined(v: any): v is undefined {\r\n return typeOf(v) === 'undefined';\r\n}\r\n\r\n/**\r\n * Check if passed function is a class\r\n *\r\n * @param {Function} fn - function to check\r\n * @returns {boolean}\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function isClass(fn: any): boolean {\r\n return isFunction(fn) && /^\\s*class\\s+/.test(fn.toString());\r\n}\r\n\r\n/**\r\n * Checks if object is empty\r\n *\r\n * @param {object} object - object to check\r\n * @returns {boolean}\r\n */\r\nexport function isEmpty(object: object): boolean {\r\n if (!object) {\r\n return true;\r\n }\r\n\r\n return Object.keys(object).length === 0 && object.constructor === Object;\r\n}\r\n\r\n/**\r\n * Check if passed object is a Promise\r\n *\r\n * @param {*} object - object to check\r\n * @returns {boolean}\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function isPromise(object: any): object is Promise<any> {\r\n return Promise.resolve(object) === object;\r\n}\r\n\r\n/* eslint-disable @typescript-eslint/no-magic-numbers */\r\n/**\r\n * Returns true if passed key code is printable (a-Z, 0-9, etc) character.\r\n *\r\n * @param {number} keyCode - key code\r\n * @returns {boolean}\r\n */\r\nexport function isPrintableKey(keyCode: number): boolean {\r\n return (keyCode > 47 && keyCode < 58) || // number keys\r\n keyCode === 32 || keyCode === 13 || // Space bar & return key(s)\r\n keyCode === 229 || // processing key input for certain languages — Chinese, Japanese, etc.\r\n (keyCode > 64 && keyCode < 91) || // letter keys\r\n (keyCode > 95 && keyCode < 112) || // Numpad keys\r\n (keyCode > 185 && keyCode < 193) || // ;=,-./` (in order)\r\n (keyCode > 218 && keyCode < 223); // [\\]' (in order)\r\n}\r\n/* eslint-enable @typescript-eslint/no-magic-numbers */\r\n\r\n/**\r\n * Fires a promise sequence asynchronously\r\n *\r\n * @param {ChainData[]} chains - list or ChainData's\r\n * @param {Function} success - success callback\r\n * @param {Function} fallback - callback that fires in case of errors\r\n * @returns {Promise}\r\n * @deprecated use PromiseQueue.ts instead\r\n */\r\nexport async function sequence(\r\n chains: ChainData[],\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n success: (data: object) => void = (): void => {},\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n fallback: (data: object) => void = (): void => {}\r\n): Promise<void> {\r\n /**\r\n * Decorator\r\n *\r\n * @param {ChainData} chainData - Chain data\r\n * @param {Function} successCallback - success callback\r\n * @param {Function} fallbackCallback - fail callback\r\n * @returns {Promise}\r\n */\r\n async function waitNextBlock(\r\n chainData: ChainData,\r\n successCallback: (data: object) => void,\r\n fallbackCallback: (data: object) => void\r\n ): Promise<void> {\r\n try {\r\n await chainData.function(chainData.data);\r\n await successCallback(!isUndefined(chainData.data) ? chainData.data : {});\r\n } catch (e) {\r\n fallbackCallback(!isUndefined(chainData.data) ? chainData.data : {});\r\n }\r\n }\r\n\r\n /**\r\n * pluck each element from queue\r\n * First, send resolved Promise as previous value\r\n * Each plugins \"prepare\" method returns a Promise, that's why\r\n * reduce current element will not be able to continue while can't get\r\n * a resolved Promise\r\n */\r\n return chains.reduce(async (previousValue, currentValue) => {\r\n await previousValue;\r\n\r\n return waitNextBlock(currentValue, success, fallback);\r\n }, Promise.resolve());\r\n}\r\n\r\n/**\r\n * Make array from array-like collection\r\n *\r\n * @param {ArrayLike} collection - collection to convert to array\r\n * @returns {Array}\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function array(collection: ArrayLike<any>): any[] {\r\n return Array.prototype.slice.call(collection);\r\n}\r\n\r\n/**\r\n * Delays method execution\r\n *\r\n * @param {Function} method - method to execute\r\n * @param {number} timeout - timeout in ms\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function delay(method: (...args: any[]) => any, timeout: number) {\r\n return function (): void {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const context = this,\r\n // eslint-disable-next-line prefer-rest-params\r\n args = arguments;\r\n\r\n window.setTimeout(() => method.apply(context, args), timeout);\r\n };\r\n}\r\n\r\n/**\r\n * Get file extension\r\n *\r\n * @param {File} file - file\r\n * @returns {string}\r\n */\r\nexport function getFileExtension(file: File): string {\r\n return file.name.split('.').pop();\r\n}\r\n\r\n/**\r\n * Check if string is MIME type\r\n *\r\n * @param {string} type - string to check\r\n * @returns {boolean}\r\n */\r\nexport function isValidMimeType(type: string): boolean {\r\n return /^[-\\w]+\\/([-+\\w]+|\\*)$/.test(type);\r\n}\r\n\r\n/**\r\n * Debouncing method\r\n * Call method after passed time\r\n *\r\n * Note that this method returns Function and declared variable need to be called\r\n *\r\n * @param {Function} func - function that we're throttling\r\n * @param {number} wait - time in milliseconds\r\n * @param {boolean} immediate - call now\r\n * @returns {Function}\r\n */\r\nexport function debounce(func: (...args: unknown[]) => void, wait?: number, immediate?: boolean): () => void {\r\n let timeout;\r\n\r\n return (...args: unknown[]): void => {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const context = this;\r\n\r\n // eslint-disable-next-line @typescript-eslint/explicit-function-return-type\r\n const later = () => {\r\n timeout = null;\r\n if (!immediate) {\r\n func.apply(context, args);\r\n }\r\n };\r\n\r\n const callNow = immediate && !timeout;\r\n\r\n window.clearTimeout(timeout);\r\n timeout = window.setTimeout(later, wait);\r\n if (callNow) {\r\n func.apply(context, args);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Returns a function, that, when invoked, will only be triggered at most once during a given window of time.\r\n *\r\n * @param func - function to throttle\r\n * @param wait - function will be called only once for that period\r\n * @param options - Normally, the throttled function will run as much as it can\r\n * without ever going more than once per `wait` duration;\r\n * but if you'd like to disable the execution on the leading edge, pass\r\n * `{leading: false}`. To disable execution on the trailing edge, ditto.\r\n */\r\nexport function throttle(func, wait, options: {leading?: boolean; trailing?: boolean} = undefined): () => void {\r\n let context, args, result;\r\n let timeout = null;\r\n let previous = 0;\r\n\r\n if (!options) {\r\n options = {};\r\n }\r\n\r\n const later = function (): void {\r\n previous = options.leading === false ? 0 : Date.now();\r\n timeout = null;\r\n result = func.apply(context, args);\r\n\r\n if (!timeout) {\r\n context = args = null;\r\n }\r\n };\r\n\r\n return function (): unknown {\r\n const now = Date.now();\r\n\r\n if (!previous && options.leading === false) {\r\n previous = now;\r\n }\r\n\r\n const remaining = wait - (now - previous);\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n context = this;\r\n\r\n // eslint-disable-next-line prefer-rest-params\r\n args = arguments;\r\n\r\n if (remaining <= 0 || remaining > wait) {\r\n if (timeout) {\r\n clearTimeout(timeout);\r\n timeout = null;\r\n }\r\n previous = now;\r\n result = func.apply(context, args);\r\n\r\n if (!timeout) {\r\n context = args = null;\r\n }\r\n } else if (!timeout && options.trailing !== false) {\r\n timeout = setTimeout(later, remaining);\r\n }\r\n\r\n return result;\r\n };\r\n}\r\n\r\n/**\r\n * Copies passed text to the clipboard\r\n *\r\n * @param text - text to copy\r\n */\r\nexport function copyTextToClipboard(text): void {\r\n const el = Dom.make('div', 'codex-editor-clipboard', {\r\n innerHTML: text,\r\n });\r\n\r\n document.body.appendChild(el);\r\n\r\n const selection = window.getSelection();\r\n const range = document.createRange();\r\n\r\n range.selectNode(el);\r\n\r\n window.getSelection().removeAllRanges();\r\n selection.addRange(range);\r\n\r\n document.execCommand('copy');\r\n document.body.removeChild(el);\r\n}\r\n\r\n/**\r\n * Returns object with os name as key and boolean as value. Shows current user OS\r\n */\r\nexport function getUserOS(): {[key: string]: boolean} {\r\n const OS = {\r\n win: false,\r\n mac: false,\r\n x11: false,\r\n linux: false,\r\n };\r\n\r\n const userOS = Object.keys(OS).find((os: string) => window.navigator.appVersion.toLowerCase().indexOf(os) !== -1);\r\n\r\n if (userOS) {\r\n OS[userOS] = true;\r\n\r\n return OS;\r\n }\r\n\r\n return OS;\r\n}\r\n\r\n/**\r\n * Capitalizes first letter of the string\r\n *\r\n * @param {string} text - text to capitalize\r\n * @returns {string}\r\n */\r\nexport function capitalize(text: string): string {\r\n return text[0].toUpperCase() + text.slice(1);\r\n}\r\n\r\n/**\r\n * Merge to objects recursively\r\n *\r\n * @param {object} target - merge target\r\n * @param {object[]} sources - merge sources\r\n * @returns {object}\r\n */\r\nexport function deepMerge<T extends object>(target, ...sources): T {\r\n if (!sources.length) {\r\n return target;\r\n }\r\n const source = sources.shift();\r\n\r\n if (isObject(target) && isObject(source)) {\r\n for (const key in source) {\r\n if (isObject(source[key])) {\r\n if (!target[key]) {\r\n Object.assign(target, { [key]: {} });\r\n }\r\n\r\n deepMerge(target[key], source[key]);\r\n } else {\r\n Object.assign(target, { [key]: source[key] });\r\n }\r\n }\r\n }\r\n\r\n return deepMerge(target, ...sources);\r\n}\r\n\r\n/**\r\n * Return true if current device supports touch events\r\n *\r\n * Note! This is a simple solution, it can give false-positive results.\r\n * To detect touch devices more carefully, use 'touchstart' event listener\r\n *\r\n * @see http://www.stucox.com/blog/you-cant-detect-a-touchscreen/\r\n * @returns {boolean}\r\n */\r\nexport const isTouchSupported: boolean = 'ontouchstart' in document.documentElement;\r\n\r\n/**\r\n * Make shortcut command more human-readable\r\n *\r\n * @param {string} shortcut — string like 'CMD+B'\r\n */\r\nexport function beautifyShortcut(shortcut: string): string {\r\n const OS = getUserOS();\r\n\r\n shortcut = shortcut\r\n .replace(/shift/gi, '⇧')\r\n .replace(/backspace/gi, '⌫')\r\n .replace(/enter/gi, '⏎')\r\n .replace(/up/gi, '↑')\r\n .replace(/left/gi, '→')\r\n .replace(/down/gi, '↓')\r\n .replace(/right/gi, '←')\r\n .replace(/escape/gi, '⎋')\r\n .replace(/insert/gi, 'Ins')\r\n .replace(/delete/gi, '␡')\r\n .replace(/\\+/gi, ' + ');\r\n\r\n if (OS.mac) {\r\n shortcut = shortcut.replace(/ctrl|cmd/gi, '⌘').replace(/alt/gi, '⌥');\r\n } else {\r\n shortcut = shortcut.replace(/cmd/gi, 'Ctrl').replace(/windows/gi, 'WIN');\r\n }\r\n\r\n return shortcut;\r\n}\r\n\r\n/**\r\n * Returns valid URL. If it is going outside and valid, it returns itself\r\n * If url has `one slash`, then it concatenates with window location origin\r\n * or when url has `two lack` it appends only protocol\r\n *\r\n * @param {string} url - url to prettify\r\n */\r\nexport function getValidUrl(url: string): string {\r\n try {\r\n const urlObject = new URL(url);\r\n\r\n return urlObject.href;\r\n } catch (e) {\r\n // do nothing but handle below\r\n }\r\n\r\n if (url.substring(0, 2) === '//') {\r\n return window.location.protocol + url;\r\n } else {\r\n return window.location.origin + url;\r\n }\r\n}\r\n\r\n/**\r\n * Create a block id\r\n *\r\n * @returns {string}\r\n */\r\nexport function generateBlockId(): string {\r\n const idLen = 10;\r\n\r\n return nanoid(idLen);\r\n}\r\n\r\n/**\r\n * Opens new Tab with passed URL\r\n *\r\n * @param {string} url - URL address to redirect\r\n */\r\nexport function openTab(url: string): void {\r\n window.open(url, '_blank');\r\n}\r\n\r\n/**\r\n * Returns random generated identifier\r\n *\r\n * @param {string} prefix - identifier prefix\r\n * @returns {string}\r\n */\r\nexport function generateId(prefix = ''): string {\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n return `${prefix}${(Math.floor(Math.random() * 1e8)).toString(16)}`;\r\n}\r\n\r\n/**\r\n * Common method for printing a warning about the usage of deprecated property or method.\r\n *\r\n * @param condition - condition for deprecation.\r\n * @param oldProperty - deprecated property.\r\n * @param newProperty - the property that should be used instead.\r\n */\r\nexport function deprecationAssert(condition: boolean, oldProperty: string, newProperty: string): void {\r\n const message = `«${oldProperty}» is deprecated and will be removed in the next major release. Please use the «${newProperty}» instead.`;\r\n\r\n if (condition) {\r\n logLabeled(message, 'warn');\r\n }\r\n}\r\n\r\n/**\r\n * Decorator which provides ability to cache method or accessor result\r\n *\r\n * @param target - target instance or constructor function\r\n * @param propertyKey - method or accessor name\r\n * @param descriptor - property descriptor\r\n */\r\nexport function cacheable<Target, Value, Arguments extends unknown[] = unknown[]>(\r\n target: Target,\r\n propertyKey: string,\r\n descriptor: PropertyDescriptor\r\n): PropertyDescriptor {\r\n const propertyToOverride = descriptor.value ? 'value' : 'get';\r\n const originalMethod = descriptor[propertyToOverride];\r\n const cacheKey = `#${propertyKey}Cache`;\r\n\r\n /**\r\n * Override get or value descriptor property to cache return value\r\n *\r\n * @param args - method args\r\n */\r\n descriptor[propertyToOverride] = function (...args: Arguments): Value {\r\n /**\r\n * If there is no cache, create it\r\n */\r\n if (this[cacheKey] === undefined) {\r\n this[cacheKey] = originalMethod.apply(this, ...args);\r\n }\r\n\r\n return this[cacheKey];\r\n };\r\n\r\n /**\r\n * If get accessor has been overridden, we need to override set accessor to clear cache\r\n *\r\n * @param value - value to set\r\n */\r\n if (propertyToOverride === 'get' && descriptor.set) {\r\n const originalSet = descriptor.set;\r\n\r\n descriptor.set = function (value: unknown): void {\r\n delete target[cacheKey];\r\n\r\n originalSet.apply(this, value);\r\n };\r\n }\r\n\r\n return descriptor;\r\n}\r\n\r\n/**\r\n * All screens below this width will be treated as mobile;\r\n */\r\nexport const mobileScreenBreakpoint = 650;\r\n\r\n/**\r\n * True if screen has mobile size\r\n */\r\nexport function isMobileScreen(): boolean {\r\n return window.matchMedia(`(max-width: ${mobileScreenBreakpoint}px)`).matches;\r\n}\r\n\r\n/**\r\n * True if current device runs iOS\r\n */\r\nexport const isIosDevice =\r\n typeof window !== 'undefined' &&\r\n window.navigator &&\r\n window.navigator.platform &&\r\n (/iP(ad|hone|od)/.test(window.navigator.platform) ||\r\n (window.navigator.platform === 'MacIntel' && window.navigator.maxTouchPoints > 1));\r\n\r\n/**\r\n * Compares two values with unknown type\r\n *\r\n * @param var1 - value to compare\r\n * @param var2 - value to compare with\r\n * @returns {boolean} true if they are equal\r\n */\r\nexport function equals(var1: unknown, var2: unknown): boolean {\r\n const isVar1NonPrimitive = Array.isArray(var1) || isObject(var1);\r\n const isVar2NonPrimitive = Array.isArray(var2) || isObject(var2);\r\n\r\n if (isVar1NonPrimitive || isVar2NonPrimitive) {\r\n return JSON.stringify(var1) === JSON.stringify(var2);\r\n }\r\n\r\n return var1 === var2;\r\n}\r\n","import * as _ from './utils';\r\n\r\n/**\r\n * DOM manipulations helper\r\n *\r\n * @todo get rid of class and make separate utility functions\r\n */\r\nexport default class Dom {\r\n /**\r\n * Check if passed tag has no closed tag\r\n *\r\n * @param {HTMLElement} tag - element to check\r\n * @returns {boolean}\r\n */\r\n public static isSingleTag(tag: HTMLElement): boolean {\r\n return tag.tagName && [\r\n 'AREA',\r\n 'BASE',\r\n 'BR',\r\n 'COL',\r\n 'COMMAND',\r\n 'EMBED',\r\n 'HR',\r\n 'IMG',\r\n 'INPUT',\r\n 'KEYGEN',\r\n 'LINK',\r\n 'META',\r\n 'PARAM',\r\n 'SOURCE',\r\n 'TRACK',\r\n 'WBR',\r\n ].includes(tag.tagName);\r\n }\r\n\r\n /**\r\n * Check if element is BR or WBR\r\n *\r\n * @param {HTMLElement} element - element to check\r\n * @returns {boolean}\r\n */\r\n public static isLineBreakTag(element: HTMLElement): element is HTMLBRElement {\r\n return element && element.tagName && [\r\n 'BR',\r\n 'WBR',\r\n ].includes(element.tagName);\r\n }\r\n\r\n /**\r\n * Helper for making Elements with class name and attributes\r\n *\r\n * @param {string} tagName - new Element tag name\r\n * @param {string[]|string} [classNames] - list or name of CSS class name(s)\r\n * @param {object} [attributes] - any attributes\r\n * @returns {HTMLElement}\r\n */\r\n public static make(tagName: string, classNames: string | (string | undefined)[] | null = null, attributes: object = {}): HTMLElement {\r\n const el = document.createElement(tagName);\r\n\r\n if (Array.isArray(classNames)) {\r\n const validClassnames = classNames.filter(className => className !== undefined) as string[];\r\n\r\n el.classList.add(...validClassnames);\r\n } else if (classNames) {\r\n el.classList.add(classNames);\r\n }\r\n\r\n for (const attrName in attributes) {\r\n if (Object.prototype.hasOwnProperty.call(attributes, attrName)) {\r\n el[attrName] = attributes[attrName];\r\n }\r\n }\r\n\r\n return el;\r\n }\r\n\r\n /**\r\n * Creates Text Node with the passed content\r\n *\r\n * @param {string} content - text content\r\n * @returns {Text}\r\n */\r\n public static text(content: string): Text {\r\n return document.createTextNode(content);\r\n }\r\n\r\n /**\r\n * Append one or several elements to the parent\r\n *\r\n * @param {Element|DocumentFragment} parent - where to append\r\n * @param {Element|Element[]|DocumentFragment|Text|Text[]} elements - element or elements list\r\n */\r\n public static append(\r\n parent: Element | DocumentFragment,\r\n elements: Element | Element[] | DocumentFragment | Text | Text[]\r\n ): void {\r\n if (Array.isArray(elements)) {\r\n elements.forEach((el) => parent.appendChild(el));\r\n } else {\r\n parent.appendChild(elements);\r\n }\r\n }\r\n\r\n /**\r\n * Append element or a couple to the beginning of the parent elements\r\n *\r\n * @param {Element} parent - where to append\r\n * @param {Element|Element[]} elements - element or elements list\r\n */\r\n public static prepend(parent: Element, elements: Element | Element[]): void {\r\n if (Array.isArray(elements)) {\r\n elements = elements.reverse();\r\n elements.forEach((el) => parent.prepend(el));\r\n } else {\r\n parent.prepend(elements);\r\n }\r\n }\r\n\r\n /**\r\n * Swap two elements in parent\r\n *\r\n * @param {HTMLElement} el1 - from\r\n * @param {HTMLElement} el2 - to\r\n * @deprecated\r\n */\r\n public static swap(el1: HTMLElement, el2: HTMLElement): void {\r\n // create marker element and insert it where el1 is\r\n const temp = document.createElement('div'),\r\n parent = el1.parentNode;\r\n\r\n parent.insertBefore(temp, el1);\r\n\r\n // move el1 to right before el2\r\n parent.insertBefore(el1, el2);\r\n\r\n // move el2 to right before where el1 used to be\r\n parent.insertBefore(el2, temp);\r\n\r\n // remove temporary marker node\r\n parent.removeChild(temp);\r\n }\r\n\r\n /**\r\n * Selector Decorator\r\n *\r\n * Returns first match\r\n *\r\n * @param {Element} el - element we searching inside. Default - DOM Document\r\n * @param {string} selector - searching string\r\n * @returns {Element}\r\n */\r\n public static find(el: Element | Document = document, selector: string): Element | null {\r\n return el.querySelector(selector);\r\n }\r\n\r\n /**\r\n * Get Element by Id\r\n *\r\n * @param {string} id - id to find\r\n * @returns {HTMLElement | null}\r\n */\r\n public static get(id: string): HTMLElement | null {\r\n return document.getElementById(id);\r\n }\r\n\r\n /**\r\n * Selector Decorator.\r\n *\r\n * Returns all matches\r\n *\r\n * @param {Element|Document} el - element we searching inside. Default - DOM Document\r\n * @param {string} selector - searching string\r\n * @returns {NodeList}\r\n */\r\n public static findAll(el: Element | Document = document, selector: string): NodeList {\r\n return el.querySelectorAll(selector);\r\n }\r\n\r\n /**\r\n * Returns CSS selector for all text inputs\r\n */\r\n public static get allInputsSelector(): string {\r\n const allowedInputTypes = ['text', 'password', 'email', 'number', 'search', 'tel', 'url'];\r\n\r\n return '[contenteditable=true], textarea, input:not([type]), ' +\r\n allowedInputTypes.map((type) => `input[type=\"${type}\"]`).join(', ');\r\n }\r\n\r\n /**\r\n * Find all contenteditable, textarea and editable input elements passed holder contains\r\n *\r\n * @param holder - element where to find inputs\r\n */\r\n public static findAllInputs(holder: Element): HTMLElement[] {\r\n return _.array(holder.querySelectorAll(Dom.allInputsSelector))\r\n /**\r\n * If contenteditable element contains block elements, treat them as inputs.\r\n */\r\n .reduce((result, input) => {\r\n if (Dom.isNativeInput(input) || Dom.containsOnlyInlineElements(input)) {\r\n return [...result, input];\r\n }\r\n\r\n return [...result, ...Dom.getDeepestBlockElements(input)];\r\n }, []);\r\n }\r\n\r\n /**\r\n * Search for deepest node which is Leaf.\r\n * Leaf is the vertex that doesn't have any child nodes\r\n *\r\n * @description Method recursively goes throw the all Node until it finds the Leaf\r\n * @param {Node} node - root Node. From this vertex we start Deep-first search\r\n * {@link https://en.wikipedia.org/wiki/Depth-first_search}\r\n * @param {boolean} [atLast] - find last text node\r\n * @returns - it can be text Node or Element Node, so that caret will able to work with it\r\n * Can return null if node is Document or DocumentFragment, or node is not attached to the DOM\r\n */\r\n public static getDeepestNode(node: Node, atLast = false): Node | null {\r\n /**\r\n * Current function have two directions:\r\n * - starts from first child and every time gets first or nextSibling in special cases\r\n * - starts from last child and gets last or previousSibling\r\n *\r\n * @type {string}\r\n */\r\n const child = atLast ? 'lastChild' : 'firstChild',\r\n sibling = atLast ? 'previousSibling' : 'nextSibling';\r\n\r\n if (node && node.nodeType === Node.ELEMENT_NODE && node[child]) {\r\n let nodeChild = node[child] as Node;\r\n\r\n /**\r\n * special case when child is single tag that can't contain any content\r\n */\r\n if (\r\n Dom.isSingleTag(nodeChild as HTMLElement) &&\r\n !Dom.isNativeInput(nodeChild) &&\r\n !Dom.isLineBreakTag(nodeChild as HTMLElement)\r\n ) {\r\n /**\r\n * 1) We need to check the next sibling. If it is Node Element then continue searching for deepest\r\n * from sibling\r\n *\r\n * 2) If single tag's next sibling is null, then go back to parent and check his sibling\r\n * In case of Node Element continue searching\r\n *\r\n * 3) If none of conditions above happened return parent Node Element\r\n */\r\n if (nodeChild[sibling]) {\r\n nodeChild = nodeChild[sibling];\r\n } else if (nodeChild.parentNode[sibling]) {\r\n nodeChild = nodeChild.parentNode[sibling];\r\n } else {\r\n return nodeChild.parentNode;\r\n }\r\n }\r\n\r\n return this.getDeepestNode(nodeChild, atLast);\r\n }\r\n\r\n return node;\r\n }\r\n\r\n /**\r\n * Check if object is DOM node\r\n *\r\n * @param {*} node - object to check\r\n * @returns {boolean}\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n public static isElement(node: any): node is Element {\r\n if (_.isNumber(node)) {\r\n return false;\r\n }\r\n\r\n return node && node.nodeType && node.nodeType === Node.ELEMENT_NODE;\r\n }\r\n\r\n /**\r\n * Check if object is DocumentFragment node\r\n *\r\n * @param {object} node - object to check\r\n * @returns {boolean}\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n public static isFragment(node: any): node is DocumentFragment {\r\n if (_.isNumber(node)) {\r\n return false;\r\n }\r\n\r\n return node && node.nodeType && node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;\r\n }\r\n\r\n /**\r\n * Check if passed element is contenteditable\r\n *\r\n * @param {HTMLElement} element - html element to check\r\n * @returns {boolean}\r\n */\r\n public static isContentEditable(element: HTMLElement): boolean {\r\n return element.contentEditable === 'true';\r\n }\r\n\r\n /**\r\n * Checks target if it is native input\r\n *\r\n * @param {*} target - HTML element or string\r\n * @returns {boolean}\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n public static isNativeInput(target: any): target is HTMLInputElement | HTMLTextAreaElement {\r\n const nativeInputs = [\r\n 'INPUT',\r\n 'TEXTAREA',\r\n ];\r\n\r\n return target && target.tagName ? nativeInputs.includes(target.tagName) : false;\r\n }\r\n\r\n /**\r\n * Checks if we can set caret\r\n *\r\n * @param {HTMLElement} target - target to check\r\n * @returns {boolean}\r\n */\r\n public static canSetCaret(target: HTMLElement): boolean {\r\n let result = true;\r\n\r\n if (Dom.isNativeInput(target)) {\r\n switch (target.type) {\r\n case 'file':\r\n case 'checkbox':\r\n case 'radio':\r\n case 'hidden':\r\n case 'submit':\r\n case 'button':\r\n case 'image':\r\n case 'reset':\r\n result = false;\r\n break;\r\n }\r\n } else {\r\n result = Dom.isContentEditable(target);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Checks node if it is empty\r\n *\r\n * @description Method checks simple Node without any childs for emptiness\r\n * If you have Node with 2 or more children id depth, you better use {@link Dom#isEmpty} method\r\n * @param {Node} node - node to check\r\n * @param {string} [ignoreChars] - char or substring to treat as empty\r\n * @returns {boolean} true if it is empty\r\n */\r\n public static isNodeEmpty(node: Node, ignoreChars?: string): boolean {\r\n let nodeText;\r\n\r\n if (this.isSingleTag(node as HTMLElement) && !this.isLineBreakTag(node as HTMLElement)) {\r\n return false;\r\n }\r\n\r\n if (this.isElement(node) && this.isNativeInput(node)) {\r\n nodeText = (node as HTMLInputElement).value;\r\n } else {\r\n nodeText = node.textContent.replace('\\u200B', '');\r\n }\r\n\r\n if (ignoreChars) {\r\n nodeText = nodeText.replace(new RegExp(ignoreChars, 'g'), '');\r\n }\r\n\r\n return nodeText.length === 0;\r\n }\r\n\r\n /**\r\n * checks node if it is doesn't have any child nodes\r\n *\r\n * @param {Node} node - node to check\r\n * @returns {boolean}\r\n */\r\n public static isLeaf(node: Node): boolean {\r\n if (!node) {\r\n return false;\r\n }\r\n\r\n return node.childNodes.length === 0;\r\n }\r\n\r\n /**\r\n * breadth-first search (BFS)\r\n * {@link https://en.wikipedia.org/wiki/Breadth-first_search}\r\n *\r\n * @description Pushes to stack all DOM leafs and checks for emptiness\r\n * @param {Node} node - node to check\r\n * @param {string} [ignoreChars] - char or substring to treat as empty\r\n * @returns {boolean}\r\n */\r\n public static isEmpty(node: Node, ignoreChars?: string): boolean {\r\n const treeWalker = [ node ];\r\n\r\n while (treeWalker.length > 0) {\r\n node = treeWalker.shift();\r\n\r\n if (!node) {\r\n continue;\r\n }\r\n\r\n if (this.isLeaf(node) && !this.isNodeEmpty(node, ignoreChars)) {\r\n return false;\r\n }\r\n\r\n if (node.childNodes) {\r\n treeWalker.push(...Array.from(node.childNodes));\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Check if string contains html elements\r\n *\r\n * @param {string} str - string to check\r\n * @returns {boolean}\r\n */\r\n public static isHTMLString(str: string): boolean {\r\n const wrapper = Dom.make('div');\r\n\r\n wrapper.innerHTML = str;\r\n\r\n return wrapper.childElementCount > 0;\r\n }\r\n\r\n /**\r\n * Return length of node`s text content\r\n *\r\n * @param {Node} node - node with content\r\n * @returns {number}\r\n */\r\n public static getContentLength(node: Node): number {\r\n if (Dom.isNativeInput(node)) {\r\n return (node as HTMLInputElement).value.length;\r\n }\r\n\r\n if (node.nodeType === Node.TEXT_NODE) {\r\n return (node as Text).length;\r\n }\r\n\r\n return node.textContent.length;\r\n }\r\n\r\n /**\r\n * Return array of names of block html elements\r\n *\r\n * @returns {string[]}\r\n */\r\n public static get blockElements(): string[] {\r\n return [\r\n 'address',\r\n 'article',\r\n 'aside',\r\n 'blockquote',\r\n 'canvas',\r\n 'div',\r\n 'dl',\r\n 'dt',\r\n 'fieldset',\r\n 'figcaption',\r\n 'figure',\r\n 'footer',\r\n 'form',\r\n 'h1',\r\n 'h2',\r\n 'h3',\r\n 'h4',\r\n 'h5',\r\n 'h6',\r\n 'header',\r\n 'hgroup',\r\n 'hr',\r\n 'li',\r\n 'main',\r\n 'nav',\r\n 'noscript',\r\n 'ol',\r\n 'output',\r\n 'p',\r\n 'pre',\r\n 'ruby',\r\n 'section',\r\n 'table',\r\n 'tbody',\r\n 'thead',\r\n 'tr',\r\n 'tfoot',\r\n 'ul',\r\n 'video',\r\n ];\r\n }\r\n\r\n /**\r\n * Check if passed content includes only inline elements\r\n *\r\n * @param {string|HTMLElement} data - element or html string\r\n * @returns {boolean}\r\n */\r\n public static containsOnlyInlineElements(data: string | HTMLElement): boolean {\r\n let wrapper: HTMLElement;\r\n\r\n if (_.isString(data)) {\r\n wrapper = document.createElement('div');\r\n wrapper.innerHTML = data;\r\n } else {\r\n wrapper = data;\r\n }\r\n\r\n const check = (element: HTMLElement): boolean => {\r\n return !Dom.blockElements.includes(element.tagName.toLowerCase()) &&\r\n Array.from(element.children).every(check);\r\n };\r\n\r\n return Array.from(wrapper.children).every(check);\r\n }\r\n\r\n /**\r\n * Find and return all block elements in the passed parent (including subtree)\r\n *\r\n * @param {HTMLElement} parent - root element\r\n * @returns {HTMLElement[]}\r\n */\r\n public static getDeepestBlockElements(parent: HTMLElement): HTMLElement[] {\r\n if (Dom.containsOnlyInlineElements(parent)) {\r\n return [ parent ];\r\n }\r\n\r\n return Array.from(parent.children).reduce((result, element) => {\r\n return [...result, ...Dom.getDeepestBlockElements(element as HTMLElement)];\r\n }, []);\r\n }\r\n\r\n /**\r\n * Helper for get holder from {string} or return HTMLElement\r\n *\r\n * @param {string | HTMLElement} element - holder's id or holder's HTML Element\r\n * @returns {HTMLElement}\r\n */\r\n public static getHolder(element: string | HTMLElement): HTMLElement {\r\n if (_.isString(element)) {\r\n return document.getElementById(element);\r\n }\r\n\r\n return element;\r\n }\r\n\r\n /**\r\n * Returns true if element is anchor (is A tag)\r\n *\r\n * @param {Element} element - element to check\r\n * @returns {boolean}\r\n */\r\n public static isAnchor(element: Element): element is HTMLAnchorElement {\r\n return element.tagName.toLowerCase() === 'a';\r\n }\r\n\r\n /**\r\n * Return element's offset related to the document\r\n *\r\n * @todo handle case when editor initialized in scrollable popup\r\n * @param el - element to compute offset\r\n */\r\n public static offset(el): { top: number; left: number; right: number; bottom: number } {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n\r\n const top = rect.top + scrollTop;\r\n const left = rect.left + scrollLeft;\r\n\r\n return {\r\n top,\r\n left,\r\n bottom: top + rect.height,\r\n right: left + rect.width,\r\n };\r\n }\r\n\r\n /**\r\n * Find text node and offset by total content offset\r\n *\r\n * @param {Node} root - root node to start search from\r\n * @param {number} totalOffset - offset relative to the root node content\r\n * @returns {{node: Node | null, offset: number}} - node and offset inside node\r\n */\r\n public static getNodeByOffset(root: Node, totalOffset: number): {node: Node | null; offset: number} {\r\n let currentOffset = 0;\r\n let lastTextNode: Node | null = null;\r\n\r\n const walker = document.createTreeWalker(\r\n root,\r\n NodeFilter.SHOW_TEXT,\r\n null\r\n );\r\n\r\n let node: Node | null = walker.nextNode();\r\n\r\n while (node) {\r\n const textContent = node.textContent;\r\n const nodeLength = textContent === null ? 0 : textContent.length;\r\n\r\n lastTextNode = node;\r\n\r\n if (currentOffset + nodeLength >= totalOffset) {\r\n break;\r\n }\r\n\r\n currentOffset += nodeLength;\r\n node = walker.nextNode();\r\n }\r\n\r\n /**\r\n * If no node found or last node is empty, return null\r\n */\r\n if (!lastTextNode) {\r\n return {\r\n node: null,\r\n offset: 0,\r\n };\r\n }\r\n\r\n const textContent = lastTextNode.textContent;\r\n\r\n if (textContent === null || textContent.length === 0) {\r\n return {\r\n node: null,\r\n offset: 0,\r\n };\r\n }\r\n\r\n /**\r\n * Calculate offset inside found node\r\n */\r\n const nodeOffset = Math.min(totalOffset - currentOffset, textContent.length);\r\n\r\n return {\r\n node: lastTextNode,\r\n offset: nodeOffset,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Determine whether a passed text content is a collapsed whitespace.\r\n *\r\n * In HTML, whitespaces at the start and end of elements and outside elements are ignored.\r\n * There are two types of whitespaces in HTML:\r\n * - Visible ( )\r\n * - Invisible (regular trailing spaces, tabs, etc)\r\n *\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace\r\n * @see https://www.w3.org/TR/css-text-3/#white-space-processing\r\n * @param textContent — any string, for ex a textContent of a node\r\n * @returns True if passed text content is whitespace which is collapsed (invisible) in browser\r\n */\r\nexport function isCollapsedWhitespaces(textContent: string): boolean {\r\n /**\r\n * Throughout, whitespace is defined as one of the characters\r\n * \"\\t\" TAB \\u0009\r\n * \"\\n\" LF \\u000A\r\n * \"\\r\" CR \\u000D\r\n * \" \" SPC \\u0020\r\n */\r\n return !/[^\\t\\n\\r ]/.test(textContent);\r\n}\r\n\r\n/**\r\n * Calculates the Y coordinate of the text baseline from the top of the element's margin box,\r\n *\r\n * The calculation formula is as follows:\r\n *\r\n * 1. Calculate the baseline offset:\r\n * - Typically, the baseline is about 80% of the `fontSize` from the top of the text, as this is a common average for many fonts.\r\n *\r\n * 2. Calculate the additional space due to `lineHeight`:\r\n * - If the `lineHeight` is greater than the `fontSize`, the extra space is evenly distributed above and below the text. This extra space is `(lineHeight - fontSize) / 2`.\r\n *\r\n * 3. Calculate the total baseline Y coordinate:\r\n * - Sum of `marginTop`, `borderTopWidth`, `paddingTop`, the extra space due to `lineHeight`, and the baseline offset.\r\n *\r\n * @param element - The element to calculate the baseline for.\r\n * @returns {number} - The Y coordinate of the text baseline from the top of the element's margin box.\r\n */\r\nexport function calculateBaseline(element: Element): number {\r\n const style = window.getComputedStyle(element);\r\n const fontSize = parseFloat(style.fontSize);\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n const lineHeight = parseFloat(style.lineHeight) || fontSize * 1.2; // default line-height if not set\r\n const paddingTop = parseFloat(style.paddingTop);\r\n const borderTopWidth = parseFloat(style.borderTopWidth);\r\n const marginTop = parseFloat(style.marginTop);\r\n\r\n /**\r\n * Typically, the baseline is about 80% of the `fontSize` from the top of the text, as this is a common average for many fonts.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n const baselineOffset = fontSize * 0.8;\r\n\r\n /**\r\n * If the `lineHeight` is greater than the `fontSize`, the extra space is evenly distributed above and below the text. This extra space is `(lineHeight - fontSize) / 2`.\r\n */\r\n const extraLineHeight = (lineHeight - fontSize) / 2;\r\n\r\n /**\r\n * Calculate the total baseline Y coordinate from the top of the margin box\r\n */\r\n const baselineY = marginTop + borderTopWidth + paddingTop + extraLineHeight + baselineOffset;\r\n\r\n return baselineY;\r\n}\r\n\r\n/**\r\n * Toggles the [data-empty] attribute on element depending on its emptiness\r\n * Used to mark empty inputs with a special attribute for placeholders feature\r\n *\r\n * @param element - The element to toggle the [data-empty] attribute on\r\n */\r\nexport function toggleEmptyMark(element: HTMLElement): void {\r\n element.dataset.empty = Dom.isEmpty(element) ? 'true' : 'false';\r\n}\r\n","import defaultDictionary from './locales/en/messages.json';\r\nimport type { I18nDictionary, Dictionary } from '../../../types/configs';\r\nimport type { LeavesDictKeys } from '../../types-internal/i18n-internal-namespace';\r\n\r\n/**\r\n * Type for all available internal dictionary strings\r\n */\r\ntype DictKeys = LeavesDictKeys<typeof defaultDictionary>;\r\n\r\n/**\r\n * This class will responsible for the translation through the language dictionary\r\n */\r\nexport default class I18n {\r\n /**\r\n * Property that stores messages dictionary\r\n */\r\n private static currentDictionary: I18nDictionary = defaultDictionary;\r\n\r\n /**\r\n * Type-safe translation for internal UI texts:\r\n * Perform translation of the string by namespace and a key\r\n *\r\n * @example I18n.ui(I18nInternalNS.ui.blockTunes.toggler, 'Click to tune')\r\n * @param internalNamespace - path to translated string in dictionary\r\n * @param dictKey - dictionary key. Better to use default locale original text\r\n */\r\n public static ui(internalNamespace: string, dictKey: DictKeys): string {\r\n return I18n._t(internalNamespace, dictKey);\r\n }\r\n\r\n /**\r\n * Translate for external strings that is not presented in default dictionary.\r\n * For example, for user-specified tool names\r\n *\r\n * @param namespace - path to translated string in dictionary\r\n * @param dictKey - dictionary key. Better to use default locale original text\r\n */\r\n public static t(namespace: string, dictKey: string): string {\r\n return I18n._t(namespace, dictKey);\r\n }\r\n\r\n /**\r\n * Adjust module for using external dictionary\r\n *\r\n * @param dictionary - new messages list to override default\r\n */\r\n public static setDictionary(dictionary: I18nDictionary): void {\r\n I18n.currentDictionary = dictionary;\r\n }\r\n\r\n /**\r\n * Perform translation both for internal and external namespaces\r\n * If there is no translation found, returns passed key as a translated message\r\n *\r\n * @param namespace - path to translated string in dictionary\r\n * @param dictKey - dictionary key. Better to use default locale original text\r\n */\r\n private static _t(namespace: string, dictKey: string): string {\r\n const section = I18n.getNamespace(namespace);\r\n\r\n /**\r\n * For Console Message to Check Section is defined or not\r\n * if (section === undefined) {\r\n * _.logLabeled('I18n: section %o was not found in current dictionary', 'log', namespace);\r\n * }\r\n */\r\n\r\n if (!section || !section[dictKey]) {\r\n return dictKey;\r\n }\r\n\r\n return section[dictKey] as string;\r\n }\r\n\r\n /**\r\n * Find messages section by namespace path\r\n *\r\n * @param namespace - path to section\r\n */\r\n private static getNamespace(namespace: string): Dictionary {\r\n const parts = namespace.split('.');\r\n\r\n return parts.reduce((section, part) => {\r\n if (!section || !Object.keys(section).length) {\r\n return {};\r\n }\r\n\r\n return section[part];\r\n }, I18n.currentDictionary);\r\n }\r\n}\r\n","/**\r\n * This type of exception will destroy the Editor! Be careful when using it\r\n */\r\nexport class CriticalError extends Error {\r\n}\r\n","import { isEmpty } from '../utils';\r\n\r\n/**\r\n * Event Dispatcher event listener\r\n */\r\ntype Listener<Data> = (data: Data) => void;\r\n\r\n/**\r\n * Mapped type with subscriptions list\r\n *\r\n * event name -> array of callbacks\r\n */\r\ntype Subscriptions<EventMap> = {\r\n [Key in keyof EventMap]: Listener<EventMap[Key]>[];\r\n};\r\n\r\n/**\r\n * Provides methods for working with Event Bus:\r\n * - {Function} on - appends subscriber to the event. If event doesn't exist - creates new one\r\n * - {Function} emit - fires all subscribers with data\r\n * - {Function off - unsubscribes callback\r\n */\r\nexport default class EventsDispatcher<EventMap> {\r\n /**\r\n * All subscribers grouped by event name\r\n * Object with events` names as key and array of callback functions as value\r\n */\r\n private subscribers = <Subscriptions<EventMap>>{};\r\n\r\n /**\r\n * Subscribe any event on callback\r\n *\r\n * @param eventName - event name\r\n * @param callback - subscriber\r\n */\r\n public on<Name extends keyof EventMap>(eventName: Name, callback: Listener<EventMap[Name]>): void {\r\n if (!(eventName in this.subscribers)) {\r\n this.subscribers[eventName] = [];\r\n }\r\n\r\n // group by events\r\n this.subscribers[eventName].push(callback);\r\n }\r\n\r\n /**\r\n * Subscribe any event on callback. Callback will be called once and be removed from subscribers array after call.\r\n *\r\n * @param eventName - event name\r\n * @param callback - subscriber\r\n */\r\n public once<Name extends keyof EventMap>(eventName: Name, callback: Listener<EventMap[Name]>): void {\r\n if (!(eventName in this.subscribers)) {\r\n this.subscribers[eventName] = [];\r\n }\r\n\r\n const wrappedCallback = (data: EventMap[typeof eventName]): void => {\r\n const result = callback(data);\r\n\r\n const indexOfHandler = this.subscribers[eventName].indexOf(wrappedCallback);\r\n\r\n if (indexOfHandler !== -1) {\r\n this.subscribers[eventName].splice(indexOfHandler, 1);\r\n }\r\n\r\n return result;\r\n };\r\n\r\n // group by events\r\n this.subscribers[eventName].push(wrappedCallback);\r\n }\r\n\r\n /**\r\n * Emit callbacks with passed data\r\n *\r\n * @param eventName - event name\r\n * @param data - subscribers get this data when they were fired\r\n */\r\n public emit<Name extends keyof EventMap>(eventName: Name, data?: EventMap[Name]): void {\r\n if (isEmpty(this.subscribers) || !this.subscribers[eventName]) {\r\n return;\r\n }\r\n\r\n this.subscribers[eventName].reduce((previousData, currentHandler) => {\r\n const newData = currentHandler(previousData);\r\n\r\n return newData !== undefined ? newData : previousData;\r\n }, data);\r\n }\r\n\r\n /**\r\n * Unsubscribe callback from event\r\n *\r\n * @param eventName - event name\r\n * @param callback - event handler\r\n */\r\n public off<Name extends keyof EventMap>(eventName: Name, callback: Listener<EventMap[Name]>): void {\r\n if (this.subscribers[eventName] === undefined) {\r\n console.warn(`EventDispatcher .off(): there is no subscribers for event \"${eventName.toString()}\". Probably, .off() called before .on()`);\r\n\r\n return;\r\n }\r\n\r\n for (let i = 0; i < this.subscribers[eventName].length; i++) {\r\n if (this.subscribers[eventName][i] === callback) {\r\n delete this.subscribers[eventName][i];\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Destroyer\r\n * clears subscribers list\r\n */\r\n public destroy(): void {\r\n this.subscribers = {} as Subscriptions<EventMap>;\r\n }\r\n}\r\n","import type Block from './index';\r\nimport type { BlockToolData, ToolConfig, ToolboxConfigEntry } from '../../../types/tools';\r\nimport type { SavedData } from '../../../types/data-formats';\r\nimport type { BlockAPI as BlockAPIInterface } from '../../../types/api';\r\n\r\n/**\r\n * Constructs new BlockAPI object\r\n *\r\n * @class\r\n * @param {Block} block - Block to expose\r\n */\r\nfunction BlockAPI(\r\n block: Block\r\n): void {\r\n const blockAPI: BlockAPIInterface = {\r\n /**\r\n * Block id\r\n *\r\n * @returns {string}\r\n */\r\n get id(): string {\r\n return block.id;\r\n },\r\n /**\r\n * Tool name\r\n *\r\n * @returns {string}\r\n */\r\n get name(): string {\r\n return block.name;\r\n },\r\n\r\n /**\r\n * Tool config passed on Editor's initialization\r\n *\r\n * @returns {ToolConfig}\r\n */\r\n get config(): ToolConfig {\r\n return block.config;\r\n },\r\n\r\n /**\r\n * .ce-block element, that wraps plugin contents\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n get holder(): HTMLElement {\r\n return block.holder;\r\n },\r\n\r\n /**\r\n * True if Block content is empty\r\n *\r\n * @returns {boolean}\r\n */\r\n get isEmpty(): boolean {\r\n return block.isEmpty;\r\n },\r\n\r\n /**\r\n * True if Block is selected with Cross-Block selection\r\n *\r\n * @returns {boolean}\r\n */\r\n get selected(): boolean {\r\n return block.selected;\r\n },\r\n\r\n /**\r\n * Set Block's stretch state\r\n *\r\n * @param {boolean} state — state to set\r\n */\r\n set stretched(state: boolean) {\r\n block.stretched = state;\r\n },\r\n\r\n /**\r\n * True if Block is stretched\r\n *\r\n * @returns {boolean}\r\n */\r\n get stretched(): boolean {\r\n return block.stretched;\r\n },\r\n\r\n /**\r\n * True if Block has inputs to be focused\r\n */\r\n get focusable(): boolean {\r\n return block.focusable;\r\n },\r\n\r\n /**\r\n * Call Tool method with errors handler under-the-hood\r\n *\r\n * @param {string} methodName - method to call\r\n * @param {object} param - object with parameters\r\n * @returns {unknown}\r\n */\r\n call(methodName: string, param?: object): unknown {\r\n return block.call(methodName, param);\r\n },\r\n\r\n /**\r\n * Save Block content\r\n *\r\n * @returns {Promise<void|SavedData>}\r\n */\r\n save(): Promise<void|SavedData> {\r\n return block.save();\r\n },\r\n\r\n /**\r\n * Validate Block data\r\n *\r\n * @param {BlockToolData} data - data to validate\r\n * @returns {Promise<boolean>}\r\n */\r\n validate(data: BlockToolData): Promise<boolean> {\r\n return block.validate(data);\r\n },\r\n\r\n /**\r\n * Allows to say Editor that Block was changed. Used to manually trigger Editor's 'onChange' callback\r\n * Can be useful for block changes invisible for editor core.\r\n */\r\n dispatchChange(): void {\r\n block.dispatchChange();\r\n },\r\n\r\n /**\r\n * Tool could specify several entries to be displayed at the Toolbox (for example, \"Heading 1\", \"Heading 2\", \"Heading 3\")\r\n * This method returns the entry that is related to the Block (depended on the Block data)\r\n */\r\n getActiveToolboxEntry(): Promise<ToolboxConfigEntry | undefined> {\r\n return block.getActiveToolboxEntry();\r\n },\r\n };\r\n\r\n Object.setPrototypeOf(this, blockAPI);\r\n}\r\n\r\nexport default BlockAPI;\r\n","import * as _ from '../utils';\r\n\r\n/**\r\n * Event listener information\r\n *\r\n * @interface ListenerData\r\n */\r\nexport interface ListenerData {\r\n /**\r\n * Listener unique identifier\r\n */\r\n id: string;\r\n\r\n /**\r\n * Element where to listen to dispatched events\r\n */\r\n element: EventTarget;\r\n\r\n /**\r\n * Event to listen\r\n */\r\n eventType: string;\r\n\r\n /**\r\n * Event handler\r\n *\r\n * @param {Event} event - event object\r\n */\r\n handler: (event: Event) => void;\r\n\r\n /**\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener\r\n */\r\n options: boolean | AddEventListenerOptions;\r\n}\r\n\r\n/**\r\n * Editor.js Listeners helper\r\n *\r\n * Decorator for event listeners assignment\r\n *\r\n * @author Codex Team\r\n * @version 2.0.0\r\n */\r\n\r\n/**\r\n * @typedef {Listeners} Listeners\r\n * @property {ListenerData[]} allListeners - listeners store\r\n */\r\nexport default class Listeners {\r\n /**\r\n * Stores all listeners data to find/remove/process it\r\n *\r\n * @type {ListenerData[]}\r\n */\r\n private allListeners: ListenerData[] = [];\r\n\r\n /**\r\n * Assigns event listener on element and returns unique identifier\r\n *\r\n * @param {EventTarget} element - DOM element that needs to be listened\r\n * @param {string} eventType - event type\r\n * @param {Function} handler - method that will be fired on event\r\n * @param {boolean|AddEventListenerOptions} options - useCapture or {capture, passive, once}\r\n */\r\n public on(\r\n element: EventTarget,\r\n eventType: string,\r\n handler: (event: Event) => void,\r\n options: boolean | AddEventListenerOptions = false\r\n ): string {\r\n const id = _.generateId('l');\r\n const assignedEventData = {\r\n id,\r\n element,\r\n eventType,\r\n handler,\r\n options,\r\n };\r\n\r\n const alreadyExist = this.findOne(element, eventType, handler);\r\n\r\n if (alreadyExist) {\r\n return;\r\n }\r\n\r\n this.allListeners.push(assignedEventData);\r\n element.addEventListener(eventType, handler, options);\r\n\r\n return id;\r\n }\r\n\r\n /**\r\n * Removes event listener from element\r\n *\r\n * @param {EventTarget} element - DOM element that we removing listener\r\n * @param {string} eventType - event type\r\n * @param {Function} handler - remove handler, if element listens several handlers on the same event type\r\n * @param {boolean|AddEventListenerOptions} options - useCapture or {capture, passive, once}\r\n */\r\n public off(\r\n element: EventTarget,\r\n eventType: string,\r\n handler?: (event: Event) => void,\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars\r\n options?: boolean | AddEventListenerOptions\r\n ): void {\r\n const existingListeners = this.findAll(element, eventType, handler);\r\n\r\n existingListeners.forEach((listener, i) => {\r\n const index = this.allListeners.indexOf(existingListeners[i]);\r\n\r\n if (index > -1) {\r\n this.allListeners.splice(index, 1);\r\n\r\n listener.element.removeEventListener(listener.eventType, listener.handler, listener.options);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Removes listener by id\r\n *\r\n * @param {string} id - listener identifier\r\n */\r\n public offById(id: string): void {\r\n const listener = this.findById(id);\r\n\r\n if (!listener) {\r\n return;\r\n }\r\n\r\n listener.element.removeEventListener(listener.eventType, listener.handler, listener.options);\r\n }\r\n\r\n /**\r\n * Finds and returns first listener by passed params\r\n *\r\n * @param {EventTarget} element - event target\r\n * @param {string} [eventType] - event type\r\n * @param {Function} [handler] - event handler\r\n * @returns {ListenerData|null}\r\n */\r\n public findOne(element: EventTarget, eventType?: string, handler?: (event: Event) => void): ListenerData {\r\n const foundListeners = this.findAll(element, eventType, handler);\r\n\r\n return foundListeners.length > 0 ? foundListeners[0] : null;\r\n }\r\n\r\n /**\r\n * Return all stored listeners by passed params\r\n *\r\n * @param {EventTarget} element - event target\r\n * @param {string} eventType - event type\r\n * @param {Function} handler - event handler\r\n * @returns {ListenerData[]}\r\n */\r\n public findAll(element: EventTarget, eventType?: string, handler?: (event: Event) => void): ListenerData[] {\r\n let found;\r\n const foundByEventTargets = element ? this.findByEventTarget(element) : [];\r\n\r\n if (element && eventType && handler) {\r\n found = foundByEventTargets.filter((event) => event.eventType === eventType && event.handler === handler);\r\n } else if (element && eventType) {\r\n found = foundByEventTargets.filter((event) => event.eventType === eventType);\r\n } else {\r\n found = foundByEventTargets;\r\n }\r\n\r\n return found;\r\n }\r\n\r\n /**\r\n * Removes all listeners\r\n */\r\n public removeAll(): void {\r\n this.allListeners.map((current) => {\r\n current.element.removeEventListener(current.eventType, current.handler, current.options);\r\n });\r\n\r\n this.allListeners = [];\r\n }\r\n\r\n /**\r\n * Module cleanup on destruction\r\n */\r\n public destroy(): void {\r\n this.removeAll();\r\n }\r\n\r\n /**\r\n * Search method: looks for listener by passed element\r\n *\r\n * @param {EventTarget} element - searching element\r\n * @returns {Array} listeners that found on element\r\n */\r\n private findByEventTarget(element: EventTarget): ListenerData[] {\r\n return this.allListeners.filter((listener) => {\r\n if (listener.element === element) {\r\n return listener;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Search method: looks for listener by passed event type\r\n *\r\n * @param {string} eventType - event type\r\n * @returns {ListenerData[]} listeners that found on element\r\n */\r\n private findByType(eventType: string): ListenerData[] {\r\n return this.allListeners.filter((listener) => {\r\n if (listener.eventType === eventType) {\r\n return listener;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Search method: looks for listener by passed handler\r\n *\r\n * @param {Function} handler - event handler\r\n * @returns {ListenerData[]} listeners that found on element\r\n */\r\n private findByHandler(handler: (event: Event) => void): ListenerData[] {\r\n return this.allListeners.filter((listener) => {\r\n if (listener.handler === handler) {\r\n return listener;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Returns listener data found by id\r\n *\r\n * @param {string} id - listener identifier\r\n * @returns {ListenerData}\r\n */\r\n private findById(id: string): ListenerData {\r\n return this.allListeners.find((listener) => listener.id === id);\r\n }\r\n}\r\n","import type { EditorModules } from '../types-internal/editor-modules';\r\nimport type { EditorConfig } from '../../types';\r\nimport type { ModuleConfig } from '../types-internal/module-config';\r\nimport Listeners from './utils/listeners';\r\nimport type EventsDispatcher from './utils/events';\r\nimport type { EditorEventMap } from './events';\r\n\r\n/**\r\n * The type <T> of the Module generic.\r\n * It describes the structure of nodes used in modules.\r\n */\r\nexport type ModuleNodes = object;\r\n\r\n/**\r\n * @abstract\r\n * @class Module\r\n * @classdesc All modules inherits from this class.\r\n * @typedef {Module} Module\r\n * @property {object} config - Editor user settings\r\n * @property {EditorModules} Editor - List of Editor modules\r\n */\r\nexport default class Module<T extends ModuleNodes = Record<string, HTMLElement>> {\r\n /**\r\n * Each module can provide some UI elements that will be stored in this property\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n public nodes: T = {} as any;\r\n\r\n /**\r\n * Editor modules list\r\n *\r\n * @type {EditorModules}\r\n */\r\n protected Editor: EditorModules;\r\n\r\n /**\r\n * Editor configuration object\r\n *\r\n * @type {EditorConfig}\r\n */\r\n protected config: EditorConfig;\r\n\r\n /**\r\n * Editor event dispatcher class\r\n */\r\n protected eventsDispatcher: EventsDispatcher<EditorEventMap>;\r\n\r\n /**\r\n * Util for bind/unbind DOM event listeners\r\n */\r\n protected listeners: Listeners = new Listeners();\r\n\r\n /**\r\n * This object provides methods to push into set of listeners that being dropped when read-only mode is enabled\r\n */\r\n protected readOnlyMutableListeners = {\r\n /**\r\n * Assigns event listener on DOM element and pushes into special array that might be removed\r\n *\r\n * @param {EventTarget} element - DOM Element\r\n * @param {string} eventType - Event name\r\n * @param {Function} handler - Event handler\r\n * @param {boolean|AddEventListenerOptions} options - Listening options\r\n */\r\n on: (\r\n element: EventTarget,\r\n eventType: string,\r\n handler: (event: Event) => void,\r\n options: boolean | AddEventListenerOptions = false\r\n ): void => {\r\n this.mutableListenerIds.push(\r\n this.listeners.on(element, eventType, handler, options)\r\n );\r\n },\r\n\r\n /**\r\n * Clears all mutable listeners\r\n */\r\n clearAll: (): void => {\r\n for (const id of this.mutableListenerIds) {\r\n this.listeners.offById(id);\r\n }\r\n\r\n this.mutableListenerIds = [];\r\n },\r\n };\r\n\r\n /**\r\n * The set of listener identifiers which will be dropped in read-only mode\r\n */\r\n private mutableListenerIds: string[] = [];\r\n\r\n /**\r\n * @class\r\n * @param options - Module options\r\n * @param options.config - Module config\r\n * @param options.eventsDispatcher - Common event bus\r\n */\r\n constructor({ config, eventsDispatcher }: ModuleConfig) {\r\n if (new.target === Module) {\r\n throw new TypeError('Constructors for abstract class Module are not allowed.');\r\n }\r\n\r\n this.config = config;\r\n this.eventsDispatcher = eventsDispatcher;\r\n }\r\n\r\n /**\r\n * Editor modules setter\r\n *\r\n * @param {EditorModules} Editor - Editor's Modules\r\n */\r\n public set state(Editor: EditorModules) {\r\n this.Editor = Editor;\r\n }\r\n\r\n /**\r\n * Remove memorized nodes\r\n */\r\n public removeAllNodes(): void {\r\n for (const key in this.nodes) {\r\n const node = this.nodes[key];\r\n\r\n if (node instanceof HTMLElement) {\r\n node.remove();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns true if current direction is RTL (Right-To-Left)\r\n */\r\n protected get isRtl(): boolean {\r\n return this.config.i18n.direction === 'rtl';\r\n }\r\n}\r\n","/**\r\n * TextRange interface for IE9-\r\n */\r\nimport * as _ from './utils';\r\nimport $ from './dom';\r\n\r\ninterface TextRange {\r\n boundingTop: number;\r\n boundingLeft: number;\r\n boundingBottom: number;\r\n boundingRight: number;\r\n boundingHeight: number;\r\n boundingWidth: number;\r\n}\r\n\r\n/**\r\n * Interface for object returned by document.selection in IE9-\r\n */\r\ninterface MSSelection {\r\n createRange: () => TextRange;\r\n type: string;\r\n}\r\n\r\n/**\r\n * Extends Document interface for IE9-\r\n */\r\ninterface Document {\r\n selection?: MSSelection;\r\n}\r\n\r\n/**\r\n * Working with selection\r\n *\r\n * @typedef {SelectionUtils} SelectionUtils\r\n */\r\nexport default class SelectionUtils {\r\n /**\r\n * Selection instances\r\n *\r\n * @todo Check if this is still relevant\r\n */\r\n public instance: Selection = null;\r\n public selection: Selection = null;\r\n\r\n /**\r\n * This property can store SelectionUtils's range for restoring later\r\n *\r\n * @type {Range|null}\r\n */\r\n public savedSelectionRange: Range = null;\r\n\r\n /**\r\n * Fake background is active\r\n *\r\n * @returns {boolean}\r\n */\r\n public isFakeBackgroundEnabled = false;\r\n\r\n /**\r\n * Native Document's commands for fake background\r\n */\r\n private readonly commandBackground: string = 'backColor';\r\n private readonly commandRemoveFormat: string = 'removeFormat';\r\n\r\n /**\r\n * Editor styles\r\n *\r\n * @returns {{editorWrapper: string, editorZone: string}}\r\n */\r\n public static get CSS(): { editorWrapper: string; editorZone: string } {\r\n return {\r\n editorWrapper: 'codex-editor',\r\n editorZone: 'codex-editor__redactor',\r\n };\r\n }\r\n\r\n /**\r\n * Returns selected anchor\r\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorNode}\r\n *\r\n * @returns {Node|null}\r\n */\r\n public static get anchorNode(): Node | null {\r\n const selection = window.getSelection();\r\n\r\n return selection ? selection.anchorNode : null;\r\n }\r\n\r\n /**\r\n * Returns selected anchor element\r\n *\r\n * @returns {Element|null}\r\n */\r\n public static get anchorElement(): Element | null {\r\n const selection = window.getSelection();\r\n\r\n if (!selection) {\r\n return null;\r\n }\r\n\r\n const anchorNode = selection.anchorNode;\r\n\r\n if (!anchorNode) {\r\n return null;\r\n }\r\n\r\n if (!$.isElement(anchorNode)) {\r\n return anchorNode.parentElement;\r\n } else {\r\n return anchorNode;\r\n }\r\n }\r\n\r\n /**\r\n * Returns selection offset according to the anchor node\r\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorOffset}\r\n *\r\n * @returns {number|null}\r\n */\r\n public static get anchorOffset(): number | null {\r\n const selection = window.getSelection();\r\n\r\n return selection ? selection.anchorOffset : null;\r\n }\r\n\r\n /**\r\n * Is current selection range collapsed\r\n *\r\n * @returns {boolean|null}\r\n */\r\n public static get isCollapsed(): boolean | null {\r\n const selection = window.getSelection();\r\n\r\n return selection ? selection.isCollapsed : null;\r\n }\r\n\r\n /**\r\n * Check current selection if it is at Editor's zone\r\n *\r\n * @returns {boolean}\r\n */\r\n public static get isAtEditor(): boolean {\r\n return this.isSelectionAtEditor(SelectionUtils.get());\r\n }\r\n\r\n /**\r\n * Check if passed selection is at Editor's zone\r\n *\r\n * @param selection - Selection object to check\r\n */\r\n public static isSelectionAtEditor(selection: Selection): boolean {\r\n if (!selection) {\r\n return false;\r\n }\r\n\r\n /**\r\n * Something selected on document\r\n */\r\n let selectedNode = (selection.anchorNode || selection.focusNode) as HTMLElement;\r\n\r\n if (selectedNode && selectedNode.nodeType === Node.TEXT_NODE) {\r\n selectedNode = selectedNode.parentNode as HTMLElement;\r\n }\r\n\r\n let editorZone = null;\r\n\r\n if (selectedNode && selectedNode instanceof Element) {\r\n editorZone = selectedNode.closest(`.${SelectionUtils.CSS.editorZone}`);\r\n }\r\n\r\n /**\r\n * SelectionUtils is not out of Editor because Editor's wrapper was found\r\n */\r\n return editorZone ? editorZone.nodeType === Node.ELEMENT_NODE : false;\r\n }\r\n\r\n /**\r\n * Check if passed range at Editor zone\r\n *\r\n * @param range - range to check\r\n */\r\n public static isRangeAtEditor(range: Range): boolean {\r\n if (!range) {\r\n return;\r\n }\r\n\r\n let selectedNode = range.startContainer as HTMLElement;\r\n\r\n if (selectedNode && selectedNode.nodeType === Node.TEXT_NODE) {\r\n selectedNode = selectedNode.parentNode as HTMLElement;\r\n }\r\n\r\n let editorZone = null;\r\n\r\n if (selectedNode && selectedNode instanceof Element) {\r\n editorZone = selectedNode.closest(`.${SelectionUtils.CSS.editorZone}`);\r\n }\r\n\r\n /**\r\n * SelectionUtils is not out of Editor because Editor's wrapper was found\r\n */\r\n return editorZone ? editorZone.nodeType === Node.ELEMENT_NODE : false;\r\n }\r\n\r\n /**\r\n * Methods return boolean that true if selection exists on the page\r\n */\r\n public static get isSelectionExists(): boolean {\r\n const selection = SelectionUtils.get();\r\n\r\n return !!selection.anchorNode;\r\n }\r\n\r\n /**\r\n * Return first range\r\n *\r\n * @returns {Range|null}\r\n */\r\n public static get range(): Range | null {\r\n return this.getRangeFromSelection(this.get());\r\n }\r\n\r\n /**\r\n * Returns range from passed Selection object\r\n *\r\n * @param selection - Selection object to get Range from\r\n */\r\n public static getRangeFromSelection(selection: Selection): Range | null {\r\n return selection && selection.rangeCount ? selection.getRangeAt(0) : null;\r\n }\r\n\r\n /**\r\n * Calculates position and size of selected text\r\n *\r\n * @returns {DOMRect | ClientRect}\r\n */\r\n public static get rect(): DOMRect | ClientRect {\r\n let sel: Selection | MSSelection = (document as Document).selection,\r\n range: TextRange | Range;\r\n\r\n let rect = {\r\n x: 0,\r\n y: 0,\r\n width: 0,\r\n height: 0,\r\n } as DOMRect;\r\n\r\n if (sel && sel.type !== 'Control') {\r\n sel = sel as MSSelection;\r\n range = sel.createRange() as TextRange;\r\n rect.x = range.boundingLeft;\r\n rect.y = range.boundingTop;\r\n rect.width = range.boundingWidth;\r\n rect.height = range.boundingHeight;\r\n\r\n return rect;\r\n }\r\n\r\n if (!window.getSelection) {\r\n _.log('Method window.getSelection is not supported', 'warn');\r\n\r\n return rect;\r\n }\r\n\r\n sel = window.getSelection();\r\n\r\n if (sel.rangeCount === null || isNaN(sel.rangeCount)) {\r\n _.log('Method SelectionUtils.rangeCount is not supported', 'warn');\r\n\r\n return rect;\r\n }\r\n\r\n if (sel.rangeCount === 0) {\r\n return rect;\r\n }\r\n\r\n range = sel.getRangeAt(0).cloneRange() as Range;\r\n\r\n if (range.getBoundingClientRect) {\r\n rect = range.getBoundingClientRect() as DOMRect;\r\n }\r\n // Fall back to inserting a temporary element\r\n if (rect.x === 0 && rect.y === 0) {\r\n const span = document.createElement('span');\r\n\r\n if (span.getBoundingClientRect) {\r\n // Ensure span has dimensions and position by\r\n // adding a zero-width space character\r\n span.appendChild(document.createTextNode('\\u200b'));\r\n range.insertNode(span);\r\n rect = span.getBoundingClientRect() as DOMRect;\r\n\r\n const spanParent = span.parentNode;\r\n\r\n spanParent.removeChild(span);\r\n\r\n // Glue any broken text nodes back together\r\n spanParent.normalize();\r\n }\r\n }\r\n\r\n return rect;\r\n }\r\n\r\n /**\r\n * Returns selected text as String\r\n *\r\n * @returns {string}\r\n */\r\n public static get text(): string {\r\n return window.getSelection ? window.getSelection().toString() : '';\r\n }\r\n\r\n /**\r\n * Returns window SelectionUtils\r\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Window/getSelection}\r\n *\r\n * @returns {Selection}\r\n */\r\n public static get(): Selection | null {\r\n return window.getSelection();\r\n }\r\n\r\n /**\r\n * Set focus to contenteditable or native input element\r\n *\r\n * @param element - element where to set focus\r\n * @param offset - offset of cursor\r\n */\r\n public static setCursor(element: HTMLElement, offset = 0): DOMRect {\r\n const range = document.createRange();\r\n const selection = window.getSelection();\r\n\r\n /** if found deepest node is native input */\r\n if ($.isNativeInput(element)) {\r\n if (!$.canSetCaret(element)) {\r\n return;\r\n }\r\n\r\n element.focus();\r\n element.selectionStart = element.selectionEnd = offset;\r\n\r\n return element.getBoundingClientRect();\r\n }\r\n\r\n range.setStart(element, offset);\r\n range.setEnd(element, offset);\r\n\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n\r\n return range.getBoundingClientRect();\r\n }\r\n\r\n /**\r\n * Check if current range exists and belongs to container\r\n *\r\n * @param container - where range should be\r\n */\r\n public static isRangeInsideContainer(container: HTMLElement): boolean {\r\n const range = SelectionUtils.range;\r\n\r\n if (range === null) {\r\n return false;\r\n }\r\n\r\n return container.contains(range.startContainer);\r\n }\r\n\r\n /**\r\n * Adds fake cursor to the current range\r\n */\r\n public static addFakeCursor(): void {\r\n const range = SelectionUtils.range;\r\n\r\n if (range === null) {\r\n return;\r\n }\r\n\r\n const fakeCursor = $.make('span', 'codex-editor__fake-cursor');\r\n\r\n fakeCursor.dataset.mutationFree = 'true';\r\n\r\n range.collapse();\r\n range.insertNode(fakeCursor);\r\n }\r\n\r\n /**\r\n * Check if passed element contains a fake cursor\r\n *\r\n * @param el - where to check\r\n */\r\n public static isFakeCursorInsideContainer(el: HTMLElement): boolean {\r\n return $.find(el, `.codex-editor__fake-cursor`) !== null;\r\n }\r\n\r\n /**\r\n * Removes fake cursor from a container\r\n *\r\n * @param container - container to look for\r\n */\r\n public static removeFakeCursor(container: HTMLElement = document.body): void {\r\n const fakeCursor = $.find(container, `.codex-editor__fake-cursor`);\r\n\r\n if (!fakeCursor) {\r\n return;\r\n }\r\n\r\n fakeCursor.remove();\r\n }\r\n\r\n /**\r\n * Removes fake background\r\n */\r\n public removeFakeBackground(): void {\r\n if (!this.isFakeBackgroundEnabled) {\r\n return;\r\n }\r\n\r\n this.isFakeBackgroundEnabled = false;\r\n document.execCommand(this.commandRemoveFormat);\r\n }\r\n\r\n /**\r\n * Sets fake background\r\n */\r\n public setFakeBackground(): void {\r\n document.execCommand(this.commandBackground, false, '#a8d6ff');\r\n\r\n this.isFakeBackgroundEnabled = true;\r\n }\r\n\r\n /**\r\n * Save SelectionUtils's range\r\n */\r\n public save(): void {\r\n this.savedSelectionRange = SelectionUtils.range;\r\n }\r\n\r\n /**\r\n * Restore saved SelectionUtils's range\r\n */\r\n public restore(): void {\r\n if (!this.savedSelectionRange) {\r\n return;\r\n }\r\n\r\n const sel = window.getSelection();\r\n\r\n sel.removeAllRanges();\r\n sel.addRange(this.savedSelectionRange);\r\n }\r\n\r\n /**\r\n * Clears saved selection\r\n */\r\n public clearSaved(): void {\r\n this.savedSelectionRange = null;\r\n }\r\n\r\n /**\r\n * Collapse current selection\r\n */\r\n public collapseToEnd(): void {\r\n const sel = window.getSelection();\r\n const range = document.createRange();\r\n\r\n range.selectNodeContents(sel.focusNode);\r\n range.collapse(false);\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n }\r\n\r\n /**\r\n * Looks ahead to find passed tag from current selection\r\n *\r\n * @param {string} tagName - tag to found\r\n * @param {string} [className] - tag's class name\r\n * @param {number} [searchDepth] - count of tags that can be included. For better performance.\r\n * @returns {HTMLElement|null}\r\n */\r\n public findParentTag(tagName: string, className?: string, searchDepth = 10): HTMLElement | null {\r\n const selection = window.getSelection();\r\n let parentTag = null;\r\n\r\n /**\r\n * If selection is missing or no anchorNode or focusNode were found then return null\r\n */\r\n if (!selection || !selection.anchorNode || !selection.focusNode) {\r\n return null;\r\n }\r\n\r\n /**\r\n * Define Nodes for start and end of selection\r\n */\r\n const boundNodes = [\r\n /** the Node in which the selection begins */\r\n selection.anchorNode as HTMLElement,\r\n /** the Node in which the selection ends */\r\n selection.focusNode as HTMLElement,\r\n ];\r\n\r\n /**\r\n * For each selection parent Nodes we try to find target tag [with target class name]\r\n * It would be saved in parentTag variable\r\n */\r\n boundNodes.forEach((parent) => {\r\n /** Reset tags limit */\r\n let searchDepthIterable = searchDepth;\r\n\r\n while (searchDepthIterable > 0 && parent.parentNode) {\r\n /**\r\n * Check tag's name\r\n */\r\n if (parent.tagName === tagName) {\r\n /**\r\n * Save the result\r\n */\r\n parentTag = parent;\r\n\r\n /**\r\n * Optional additional check for class-name mismatching\r\n */\r\n if (className && parent.classList && !parent.classList.contains(className)) {\r\n parentTag = null;\r\n }\r\n\r\n /**\r\n * If we have found required tag with class then go out from the cycle\r\n */\r\n if (parentTag) {\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Target tag was not found. Go up to the parent and check it\r\n */\r\n parent = parent.parentNode as HTMLElement;\r\n searchDepthIterable--;\r\n }\r\n });\r\n\r\n /**\r\n * Return found tag or null\r\n */\r\n return parentTag;\r\n }\r\n\r\n /**\r\n * Expands selection range to the passed parent node\r\n *\r\n * @param {HTMLElement} element - element which contents should be selected\r\n */\r\n public expandToTag(element: HTMLElement): void {\r\n const selection = window.getSelection();\r\n\r\n selection.removeAllRanges();\r\n const range = document.createRange();\r\n\r\n range.selectNodeContents(element);\r\n selection.addRange(range);\r\n }\r\n}\r\n","/**\r\n * Check if passed mutation belongs to a passed element\r\n *\r\n * @param mutationRecord - mutation to check\r\n * @param element - element that is expected to contain mutation\r\n */\r\nexport function isMutationBelongsToElement(mutationRecord: MutationRecord, element: Element): boolean {\r\n const { type, target, addedNodes, removedNodes } = mutationRecord;\r\n\r\n /**\r\n * Skip own technical mutations, for example, data-empty attribute changes\r\n */\r\n if (mutationRecord.type === 'attributes' && mutationRecord.attributeName === 'data-empty') {\r\n return false;\r\n }\r\n\r\n /**\r\n * Covers all types of mutations happened to the element or it's descendants with the only one exception - removing/adding the element itself;\r\n */\r\n if (element.contains(target)) {\r\n return true;\r\n }\r\n\r\n /**\r\n * In case of removing/adding the element itself, mutation type will be 'childList' and 'removedNodes'/'addedNodes' will contain the element.\r\n */\r\n if (type === 'childList') {\r\n const elementAddedItself = Array.from(addedNodes).some(node => node === element);\r\n\r\n if (elementAddedItself) {\r\n return true;\r\n }\r\n\r\n const elementRemovedItself = Array.from(removedNodes).some(node => node === element);\r\n\r\n if (elementRemovedItself) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n","/**\r\n * Fired when blocks wrapper (.codex-editor-redactor) dom changed\r\n */\r\nexport const RedactorDomChanged = 'redactor dom changed';\r\n\r\n/**\r\n * Payload that will be passed with the event\r\n */\r\nexport interface RedactorDomChangedPayload {\r\n /**\r\n * Mutations happened with blocks wrapper\r\n */\r\n mutations: MutationRecord[];\r\n}\r\n","import type { BlockMutationEvent } from '../../../types/events/block';\r\n\r\n/**\r\n * Fired when some block state has changed\r\n */\r\nexport const BlockChanged = 'block changed';\r\n\r\n/**\r\n * Payload that will be passed with the event\r\n */\r\nexport interface BlockChangedPayload {\r\n /**\r\n * CustomEvent describing a block change\r\n */\r\n event: BlockMutationEvent;\r\n}\r\n","/**\r\n * Fired before we're adding/removing a fake cursor.\r\n *\r\n * Allows to disable mutation observer to skip this block change\r\n */\r\nexport const FakeCursorAboutToBeToggled = 'fake cursor is about to be toggled';\r\n\r\n/**\r\n * Payload that will be passed with the event\r\n */\r\nexport interface FakeCursorAboutToBeToggledPayload {\r\n /**\r\n * true - when added a cursor\r\n * false - when removed\r\n */\r\n state: boolean;\r\n}\r\n","/**\r\n * Fired after we've added/removed a fake cursor.\r\n *\r\n * Allows to enable mutation observer which was disabled before setting\r\n */\r\nexport const FakeCursorHaveBeenSet = 'fake cursor have been set';\r\n\r\n/**\r\n * Payload that will be passed with the event\r\n */\r\nexport interface FakeCursorHaveBeenSetPayload {\r\n /**\r\n * true - when added a cursor\r\n * false - when removed\r\n */\r\n state: boolean;\r\n}\r\n","/**\r\n * Fired when editor mobile layout toggled\r\n */\r\nexport const EditorMobileLayoutToggled = 'editor mobile layout toggled';\r\n\r\n/**\r\n * Payload that will be passed with the event\r\n */\r\nexport interface EditorMobileLayoutToggledPayload {\r\n /**\r\n * True, if mobile layout enabled\r\n */\r\n isEnabled: boolean;\r\n}\r\n\r\n","import type BlockToolAdapter from '../tools/block';\r\nimport { isFunction, isString } from '../utils';\r\n\r\n/**\r\n * Check if tool has valid conversion config for export or import.\r\n *\r\n * @param tool - tool to check\r\n * @param direction - export for tool to merge from, import for tool to merge to\r\n */\r\nexport function isToolConvertable(tool: BlockToolAdapter, direction: 'export' | 'import'): boolean {\r\n if (!tool.conversionConfig) {\r\n return false;\r\n }\r\n\r\n const conversionProp = tool.conversionConfig[direction];\r\n\r\n return isFunction(conversionProp) || isString(conversionProp);\r\n}\r\n","import type { BlockAPI, ToolConfig } from '../../../types';\r\nimport type { ConversionConfig } from '../../../types/configs/conversion-config';\r\nimport type { SavedData } from '../../../types/data-formats';\r\nimport type { BlockToolData } from '../../../types/tools/block-tool-data';\r\nimport type Block from '../block';\r\nimport type BlockToolAdapter from '../tools/block';\r\nimport { isFunction, isString, log, equals, isEmpty } from '../utils';\r\nimport { isToolConvertable } from './tools';\r\n\r\n\r\n/**\r\n * Check if block has valid conversion config for export or import.\r\n *\r\n * @param block - block to check\r\n * @param direction - export for block to merge from, import for block to merge to\r\n */\r\nexport function isBlockConvertable(block: Block, direction: 'export' | 'import'): boolean {\r\n return isToolConvertable(block.tool, direction);\r\n}\r\n\r\n/**\r\n * Checks that all the properties of the first block data exist in second block data with the same values.\r\n *\r\n * Example:\r\n *\r\n * data1 = { level: 1 }\r\n *\r\n * data2 = {\r\n * text: \"Heading text\",\r\n * level: 1\r\n * }\r\n *\r\n * isSameBlockData(data1, data2) => true\r\n *\r\n * @param data1 – first block data\r\n * @param data2 – second block data\r\n */\r\nexport function isSameBlockData(data1: BlockToolData, data2: BlockToolData): boolean {\r\n return Object.entries(data1).some((([propName, propValue]) => {\r\n return data2[propName] && equals(data2[propName], propValue);\r\n }));\r\n}\r\n\r\n/**\r\n * Returns list of tools you can convert specified block to\r\n *\r\n * @param block - block to get conversion items for\r\n * @param allBlockTools - all block tools available in the editor\r\n */\r\nexport async function getConvertibleToolsForBlock(block: BlockAPI, allBlockTools: BlockToolAdapter[]): Promise<BlockToolAdapter[]> {\r\n const savedData = await block.save() as SavedData;\r\n const blockData = savedData.data;\r\n\r\n /**\r\n * Checking that the block's tool has an «export» rule\r\n */\r\n const blockTool = allBlockTools.find((tool) => tool.name === block.name);\r\n\r\n if (blockTool !== undefined && !isToolConvertable(blockTool, 'export')) {\r\n return [];\r\n }\r\n\r\n return allBlockTools.reduce((result, tool) => {\r\n /**\r\n * Skip tools without «import» rule specified\r\n */\r\n if (!isToolConvertable(tool, 'import')) {\r\n return result;\r\n }\r\n\r\n /**\r\n * Skip tools that does not specify toolbox\r\n */\r\n if (tool.toolbox === undefined) {\r\n return result;\r\n }\r\n\r\n /** Filter out invalid toolbox entries */\r\n const actualToolboxItems = tool.toolbox.filter((toolboxItem) => {\r\n /**\r\n * Skip items that don't pass 'toolbox' property or do not have an icon\r\n */\r\n if (isEmpty(toolboxItem) || toolboxItem.icon === undefined) {\r\n return false;\r\n }\r\n\r\n if (toolboxItem.data !== undefined) {\r\n /**\r\n * When a tool has several toolbox entries, we need to make sure we do not add\r\n * toolbox item with the same data to the resulting array. This helps exclude duplicates\r\n */\r\n if (isSameBlockData(toolboxItem.data, blockData)) {\r\n return false;\r\n }\r\n } else if (tool.name === block.name) {\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n\r\n result.push({\r\n ...tool,\r\n toolbox: actualToolboxItems,\r\n } as BlockToolAdapter);\r\n\r\n return result;\r\n }, [] as BlockToolAdapter[]);\r\n}\r\n\r\n\r\n/**\r\n * Check if two blocks could be merged.\r\n *\r\n * We can merge two blocks if:\r\n * - they have the same type\r\n * - they have a merge function (.mergeable = true)\r\n * - If they have valid conversions config\r\n *\r\n * @param targetBlock - block to merge to\r\n * @param blockToMerge - block to merge from\r\n */\r\nexport function areBlocksMergeable(targetBlock: Block, blockToMerge: Block): boolean {\r\n /**\r\n * If target block has not 'merge' method, we can't merge blocks.\r\n *\r\n * Technically we can (through the conversion) but it will lead a target block delete and recreation, which is unexpected behavior.\r\n */\r\n if (!targetBlock.mergeable) {\r\n return false;\r\n }\r\n\r\n /**\r\n * Tool knows how to merge own data format\r\n */\r\n if (targetBlock.name === blockToMerge.name) {\r\n return true;\r\n }\r\n\r\n /**\r\n * We can merge blocks if they have valid conversion config\r\n */\r\n return isBlockConvertable(blockToMerge, 'export') && isBlockConvertable(targetBlock, 'import');\r\n}\r\n\r\n/**\r\n * Using conversionConfig, convert block data to string.\r\n *\r\n * @param blockData - block data to convert\r\n * @param conversionConfig - tool's conversion config\r\n */\r\nexport function convertBlockDataToString(blockData: BlockToolData, conversionConfig?: ConversionConfig ): string {\r\n const exportProp = conversionConfig?.export;\r\n\r\n if (isFunction(exportProp)) {\r\n return exportProp(blockData);\r\n } else if (isString(exportProp)) {\r\n return blockData[exportProp];\r\n } else {\r\n /**\r\n * Tool developer provides 'export' property, but it is not correct. Warn him.\r\n */\r\n if (exportProp !== undefined) {\r\n log('Conversion «export» property must be a string or function. ' +\r\n 'String means key of saved data object to export. Function should export processed string to export.');\r\n }\r\n\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Using conversionConfig, convert string to block data.\r\n *\r\n * @param stringToImport - string to convert\r\n * @param conversionConfig - tool's conversion config\r\n * @param targetToolConfig - target tool config, used in conversionConfig.import method\r\n */\r\nexport function convertStringToBlockData(stringToImport: string, conversionConfig?: ConversionConfig, targetToolConfig?: ToolConfig): BlockToolData {\r\n const importProp = conversionConfig?.import;\r\n\r\n if (isFunction(importProp)) {\r\n return importProp(stringToImport, targetToolConfig);\r\n } else if (isString(importProp)) {\r\n return {\r\n [importProp]: stringToImport,\r\n };\r\n } else {\r\n /**\r\n * Tool developer provides 'import' property, but it is not correct. Warn him.\r\n */\r\n if (importProp !== undefined) {\r\n log('Conversion «import» property must be a string or function. ' +\r\n 'String means key of tool data to import. Function accepts a imported string and return composed tool data.');\r\n }\r\n\r\n return {};\r\n }\r\n}\r\n\r\n","/**\r\n * Popover item types\r\n */\r\nexport enum PopoverItemType {\r\n /** Regular item with icon, title and other properties */\r\n Default = 'default',\r\n\r\n /** Gray line used to separate items from each other */\r\n Separator = 'separator',\r\n\r\n /** Item with custom html content */\r\n Html = 'html'\r\n}\r\n","import type {\r\n BlockAPI as BlockAPIInterface,\r\n BlockTool as IBlockTool,\r\n BlockToolData,\r\n BlockTune as IBlockTune,\r\n SanitizerConfig,\r\n ToolConfig,\r\n ToolboxConfigEntry,\r\n PopoverItemParams\r\n} from '../../../types';\r\n\r\nimport type { SavedData } from '../../../types/data-formats';\r\nimport $, { toggleEmptyMark } from '../dom';\r\nimport * as _ from '../utils';\r\nimport type ApiModules from '../modules/api';\r\nimport BlockAPI from './api';\r\nimport SelectionUtils from '../selection';\r\nimport type BlockToolAdapter from '../tools/block';\r\n\r\nimport type BlockTuneAdapter from '../tools/tune';\r\nimport type { BlockTuneData } from '../../../types/block-tunes/block-tune-data';\r\nimport type ToolsCollection from '../tools/collection';\r\nimport EventsDispatcher from '../utils/events';\r\nimport type { TunesMenuConfigItem } from '../../../types/tools';\r\nimport { isMutationBelongsToElement } from '../utils/mutations';\r\nimport type { EditorEventMap } from '../events';\r\nimport { FakeCursorAboutToBeToggled, FakeCursorHaveBeenSet, RedactorDomChanged } from '../events';\r\nimport type { RedactorDomChangedPayload } from '../events/RedactorDomChanged';\r\nimport { convertBlockDataToString, isSameBlockData } from '../utils/blocks';\r\nimport { PopoverItemType } from '../../../types/utils/popover/popover-item-type';\r\n\r\n/**\r\n * Interface describes Block class constructor argument\r\n */\r\ninterface BlockConstructorOptions {\r\n /**\r\n * Block's id. Should be passed for existed block, and omitted for a new one.\r\n */\r\n id?: string;\r\n\r\n /**\r\n * Initial Block data\r\n */\r\n data: BlockToolData;\r\n\r\n /**\r\n * Tool object\r\n */\r\n tool: BlockToolAdapter;\r\n\r\n /**\r\n * Editor's API methods\r\n */\r\n api: ApiModules;\r\n\r\n /**\r\n * This flag indicates that the Block should be constructed in the read-only mode.\r\n */\r\n readOnly: boolean;\r\n\r\n /**\r\n * Tunes data for current Block\r\n */\r\n tunesData: { [name: string]: BlockTuneData };\r\n}\r\n\r\n/**\r\n * @class Block\r\n * @classdesc This class describes editor`s block, including block`s HTMLElement, data and tool\r\n * @property {BlockTool} tool — current block tool (Paragraph, for example)\r\n * @property {object} CSS — block`s css classes\r\n */\r\n\r\n/**\r\n * Available Block Tool API methods\r\n */\r\nexport enum BlockToolAPI {\r\n /**\r\n * @todo remove method in 3.0.0\r\n * @deprecated — use 'rendered' hook instead\r\n */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n APPEND_CALLBACK = 'appendCallback',\r\n RENDERED = 'rendered',\r\n MOVED = 'moved',\r\n UPDATED = 'updated',\r\n REMOVED = 'removed',\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n ON_PASTE = 'onPaste',\r\n}\r\n\r\n/**\r\n * Names of events used in Block\r\n */\r\ninterface BlockEvents {\r\n 'didMutated': Block,\r\n}\r\n\r\n/**\r\n * @classdesc Abstract Block class that contains Block information, Tool name and Tool class instance\r\n * @property {BlockTool} tool - Tool instance\r\n * @property {HTMLElement} holder - Div element that wraps block content with Tool's content. Has `ce-block` CSS class\r\n * @property {HTMLElement} pluginsContent - HTML content that returns by Tool's render function\r\n */\r\nexport default class Block extends EventsDispatcher<BlockEvents> {\r\n /**\r\n * CSS classes for the Block\r\n *\r\n * @returns {{wrapper: string, content: string}}\r\n */\r\n public static get CSS(): { [name: string]: string } {\r\n return {\r\n wrapper: 'ce-block',\r\n wrapperStretched: 'ce-block--stretched',\r\n content: 'ce-block__content',\r\n selected: 'ce-block--selected',\r\n dropTarget: 'ce-block--drop-target',\r\n };\r\n }\r\n\r\n /**\r\n * Block unique identifier\r\n */\r\n public id: string;\r\n\r\n /**\r\n * Block Tool`s name\r\n */\r\n public readonly name: string;\r\n\r\n /**\r\n * Instance of the Tool Block represents\r\n */\r\n public readonly tool: BlockToolAdapter;\r\n\r\n /**\r\n * User Tool configuration\r\n */\r\n public readonly settings: ToolConfig;\r\n\r\n /**\r\n * Wrapper for Block`s content\r\n */\r\n public readonly holder: HTMLDivElement;\r\n\r\n /**\r\n * Tunes used by Tool\r\n */\r\n public readonly tunes: ToolsCollection<BlockTuneAdapter>;\r\n\r\n /**\r\n * Tool's user configuration\r\n */\r\n public readonly config: ToolConfig;\r\n\r\n /**\r\n * Cached inputs\r\n */\r\n private cachedInputs: HTMLElement[] = [];\r\n\r\n /**\r\n * We'll store a reference to the tool's rendered element to access it later\r\n */\r\n private toolRenderedElement: HTMLElement | null = null;\r\n\r\n /**\r\n * Tool class instance\r\n */\r\n private readonly toolInstance: IBlockTool;\r\n\r\n /**\r\n * User provided Block Tunes instances\r\n */\r\n private readonly tunesInstances: Map<string, IBlockTune> = new Map();\r\n\r\n /**\r\n * Editor provided Block Tunes instances\r\n */\r\n private readonly defaultTunesInstances: Map<string, IBlockTune> = new Map();\r\n\r\n /**\r\n * If there is saved data for Tune which is not available at the moment,\r\n * we will store it here and provide back on save so data is not lost\r\n */\r\n private unavailableTunesData: { [name: string]: BlockTuneData } = {};\r\n\r\n /**\r\n * Focused input index\r\n *\r\n * @type {number}\r\n */\r\n private inputIndex = 0;\r\n\r\n /**\r\n * Common editor event bus\r\n */\r\n private readonly editorEventBus: EventsDispatcher<EditorEventMap> | null = null;\r\n\r\n /**\r\n * Link to editor dom change callback. Used to remove listener on remove\r\n */\r\n private redactorDomChangedCallback: (payload: RedactorDomChangedPayload) => void;\r\n\r\n /**\r\n * Current block API interface\r\n */\r\n private readonly blockAPI: BlockAPIInterface;\r\n\r\n /**\r\n * @param options - block constructor options\r\n * @param [options.id] - block's id. Will be generated if omitted.\r\n * @param options.data - Tool's initial data\r\n * @param options.tool — block's tool\r\n * @param options.api - Editor API module for pass it to the Block Tunes\r\n * @param options.readOnly - Read-Only flag\r\n * @param [eventBus] - Editor common event bus. Allows to subscribe on some Editor events. Could be omitted when \"virtual\" Block is created. See BlocksAPI@composeBlockData.\r\n */\r\n constructor({\r\n id = _.generateBlockId(),\r\n data,\r\n tool,\r\n readOnly,\r\n tunesData,\r\n }: BlockConstructorOptions, eventBus?: EventsDispatcher<EditorEventMap>) {\r\n super();\r\n this.name = tool.name;\r\n this.id = id;\r\n this.settings = tool.settings;\r\n this.config = tool.settings.config || {};\r\n this.editorEventBus = eventBus || null;\r\n this.blockAPI = new BlockAPI(this);\r\n\r\n this.tool = tool;\r\n this.toolInstance = tool.create(data, this.blockAPI, readOnly);\r\n\r\n /**\r\n * @type {BlockTuneAdapter[]}\r\n */\r\n this.tunes = tool.tunes;\r\n\r\n this.composeTunes(tunesData);\r\n\r\n this.holder = this.compose();\r\n\r\n /**\r\n * Bind block events in RIC for optimizing of constructing process time\r\n */\r\n window.requestIdleCallback(() => {\r\n /**\r\n * Start watching block mutations\r\n */\r\n this.watchBlockMutations();\r\n\r\n /**\r\n * Mutation observer doesn't track changes in \"<input>\" and \"<textarea>\"\r\n * so we need to track focus events to update current input and clear cache.\r\n */\r\n this.addInputEvents();\r\n\r\n /**\r\n * We mark inputs with [data-empty] attribute\r\n * It can be useful for developers, for example for correct placeholder behavior\r\n */\r\n this.toggleInputsEmptyMark();\r\n });\r\n }\r\n\r\n /**\r\n * Find and return all editable elements (contenteditable and native inputs) in the Tool HTML\r\n */\r\n public get inputs(): HTMLElement[] {\r\n /**\r\n * Return from cache if existed\r\n */\r\n if (this.cachedInputs.length !== 0) {\r\n return this.cachedInputs;\r\n }\r\n\r\n const inputs = $.findAllInputs(this.holder);\r\n\r\n /**\r\n * If inputs amount was changed we need to check if input index is bigger then inputs array length\r\n */\r\n if (this.inputIndex > inputs.length - 1) {\r\n this.inputIndex = inputs.length - 1;\r\n }\r\n\r\n /**\r\n * Cache inputs\r\n */\r\n this.cachedInputs = inputs;\r\n\r\n return inputs;\r\n }\r\n\r\n /**\r\n * Return current Tool`s input\r\n * If Block doesn't contain inputs, return undefined\r\n */\r\n public get currentInput(): HTMLElement | undefined {\r\n return this.inputs[this.inputIndex];\r\n }\r\n\r\n /**\r\n * Set input index to the passed element\r\n *\r\n * @param element - HTML Element to set as current input\r\n */\r\n public set currentInput(element: HTMLElement) {\r\n const index = this.inputs.findIndex((input) => input === element || input.contains(element));\r\n\r\n if (index !== -1) {\r\n this.inputIndex = index;\r\n }\r\n }\r\n\r\n /**\r\n * Return first Tool`s input\r\n * If Block doesn't contain inputs, return undefined\r\n */\r\n public get firstInput(): HTMLElement | undefined {\r\n return this.inputs[0];\r\n }\r\n\r\n /**\r\n * Return first Tool`s input\r\n * If Block doesn't contain inputs, return undefined\r\n */\r\n public get lastInput(): HTMLElement | undefined {\r\n const inputs = this.inputs;\r\n\r\n return inputs[inputs.length - 1];\r\n }\r\n\r\n /**\r\n * Return next Tool`s input or undefined if it doesn't exist\r\n * If Block doesn't contain inputs, return undefined\r\n */\r\n public get nextInput(): HTMLElement | undefined {\r\n return this.inputs[this.inputIndex + 1];\r\n }\r\n\r\n /**\r\n * Return previous Tool`s input or undefined if it doesn't exist\r\n * If Block doesn't contain inputs, return undefined\r\n */\r\n public get previousInput(): HTMLElement | undefined {\r\n return this.inputs[this.inputIndex - 1];\r\n }\r\n\r\n /**\r\n * Get Block's JSON data\r\n *\r\n * @returns {object}\r\n */\r\n public get data(): Promise<BlockToolData> {\r\n return this.save().then((savedObject) => {\r\n if (savedObject && !_.isEmpty(savedObject.data)) {\r\n return savedObject.data;\r\n } else {\r\n return {};\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Returns tool's sanitizer config\r\n *\r\n * @returns {object}\r\n */\r\n public get sanitize(): SanitizerConfig {\r\n return this.tool.sanitizeConfig;\r\n }\r\n\r\n /**\r\n * is block mergeable\r\n * We plugin have merge function then we call it mergeable\r\n *\r\n * @returns {boolean}\r\n */\r\n public get mergeable(): boolean {\r\n return _.isFunction(this.toolInstance.merge);\r\n }\r\n\r\n /**\r\n * If Block contains inputs, it is focusable\r\n */\r\n public get focusable(): boolean {\r\n return this.inputs.length !== 0;\r\n }\r\n\r\n /**\r\n * Check block for emptiness\r\n *\r\n * @returns {boolean}\r\n */\r\n public get isEmpty(): boolean {\r\n const emptyText = $.isEmpty(this.pluginsContent, '/');\r\n const emptyMedia = !this.hasMedia;\r\n\r\n return emptyText && emptyMedia;\r\n }\r\n\r\n /**\r\n * Check if block has a media content such as images, iframe and other\r\n *\r\n * @returns {boolean}\r\n */\r\n public get hasMedia(): boolean {\r\n /**\r\n * This tags represents media-content\r\n *\r\n * @type {string[]}\r\n */\r\n const mediaTags = [\r\n 'img',\r\n 'iframe',\r\n 'video',\r\n 'audio',\r\n 'source',\r\n 'input',\r\n 'textarea',\r\n 'twitterwidget',\r\n ];\r\n\r\n return !!this.holder.querySelector(mediaTags.join(','));\r\n }\r\n\r\n /**\r\n * Set selected state\r\n * We don't need to mark Block as Selected when it is empty\r\n *\r\n * @param {boolean} state - 'true' to select, 'false' to remove selection\r\n */\r\n public set selected(state: boolean) {\r\n this.holder.classList.toggle(Block.CSS.selected, state);\r\n\r\n const fakeCursorWillBeAdded = state === true && SelectionUtils.isRangeInsideContainer(this.holder);\r\n const fakeCursorWillBeRemoved = state === false && SelectionUtils.isFakeCursorInsideContainer(this.holder);\r\n\r\n if (fakeCursorWillBeAdded || fakeCursorWillBeRemoved) {\r\n this.editorEventBus?.emit(FakeCursorAboutToBeToggled, { state }); // mutex\r\n\r\n if (fakeCursorWillBeAdded) {\r\n SelectionUtils.addFakeCursor();\r\n } else {\r\n SelectionUtils.removeFakeCursor(this.holder);\r\n }\r\n\r\n this.editorEventBus?.emit(FakeCursorHaveBeenSet, { state });\r\n }\r\n }\r\n\r\n /**\r\n * Returns True if it is Selected\r\n *\r\n * @returns {boolean}\r\n */\r\n public get selected(): boolean {\r\n return this.holder.classList.contains(Block.CSS.selected);\r\n }\r\n\r\n /**\r\n * Set stretched state\r\n *\r\n * @param {boolean} state - 'true' to enable, 'false' to disable stretched state\r\n */\r\n public set stretched(state: boolean) {\r\n this.holder.classList.toggle(Block.CSS.wrapperStretched, state);\r\n }\r\n\r\n /**\r\n * Return Block's stretched state\r\n *\r\n * @returns {boolean}\r\n */\r\n public get stretched(): boolean {\r\n return this.holder.classList.contains(Block.CSS.wrapperStretched);\r\n }\r\n\r\n /**\r\n * Toggle drop target state\r\n *\r\n * @param {boolean} state - 'true' if block is drop target, false otherwise\r\n */\r\n public set dropTarget(state) {\r\n this.holder.classList.toggle(Block.CSS.dropTarget, state);\r\n }\r\n\r\n /**\r\n * Returns Plugins content\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n public get pluginsContent(): HTMLElement {\r\n return this.toolRenderedElement;\r\n }\r\n\r\n /**\r\n * Calls Tool's method\r\n *\r\n * Method checks tool property {MethodName}. Fires method with passes params If it is instance of Function\r\n *\r\n * @param {string} methodName - method to call\r\n * @param {object} params - method argument\r\n */\r\n public call(methodName: string, params?: object): void {\r\n /**\r\n * call Tool's method with the instance context\r\n */\r\n if (_.isFunction(this.toolInstance[methodName])) {\r\n if (methodName === BlockToolAPI.APPEND_CALLBACK) {\r\n _.log(\r\n '`appendCallback` hook is deprecated and will be removed in the next major release. ' +\r\n 'Use `rendered` hook instead',\r\n 'warn'\r\n );\r\n }\r\n\r\n try {\r\n // eslint-disable-next-line no-useless-call\r\n this.toolInstance[methodName].call(this.toolInstance, params);\r\n } catch (e) {\r\n _.log(`Error during '${methodName}' call: ${e.message}`, 'error');\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Call plugins merge method\r\n *\r\n * @param {BlockToolData} data - data to merge\r\n */\r\n public async mergeWith(data: BlockToolData): Promise<void> {\r\n await this.toolInstance.merge(data);\r\n }\r\n\r\n /**\r\n * Extracts data from Block\r\n * Groups Tool's save processing time\r\n *\r\n * @returns {object}\r\n */\r\n public async save(): Promise<undefined | SavedData> {\r\n const extractedBlock = await this.toolInstance.save(this.pluginsContent as HTMLElement);\r\n const tunesData: { [name: string]: BlockTuneData } = this.unavailableTunesData;\r\n\r\n [\r\n ...this.tunesInstances.entries(),\r\n ...this.defaultTunesInstances.entries(),\r\n ]\r\n .forEach(([name, tune]) => {\r\n if (_.isFunction(tune.save)) {\r\n try {\r\n tunesData[name] = tune.save();\r\n } catch (e) {\r\n _.log(`Tune ${tune.constructor.name} save method throws an Error %o`, 'warn', e);\r\n }\r\n }\r\n });\r\n\r\n /**\r\n * Measuring execution time\r\n */\r\n const measuringStart = window.performance.now();\r\n let measuringEnd;\r\n\r\n return Promise.resolve(extractedBlock)\r\n .then((finishedExtraction) => {\r\n /** measure promise execution */\r\n measuringEnd = window.performance.now();\r\n\r\n return {\r\n id: this.id,\r\n tool: this.name,\r\n data: finishedExtraction,\r\n tunes: tunesData,\r\n time: measuringEnd - measuringStart,\r\n };\r\n })\r\n .catch((error) => {\r\n _.log(`Saving process for ${this.name} tool failed due to the ${error}`, 'log', 'red');\r\n });\r\n }\r\n\r\n /**\r\n * Uses Tool's validation method to check the correctness of output data\r\n * Tool's validation method is optional\r\n *\r\n * @description Method returns true|false whether data passed the validation or not\r\n * @param {BlockToolData} data - data to validate\r\n * @returns {Promise<boolean>} valid\r\n */\r\n public async validate(data: BlockToolData): Promise<boolean> {\r\n let isValid = true;\r\n\r\n if (this.toolInstance.validate instanceof Function) {\r\n isValid = await this.toolInstance.validate(data);\r\n }\r\n\r\n return isValid;\r\n }\r\n\r\n /**\r\n * Returns data to render in Block Tunes menu.\r\n * Splits block tunes into 2 groups: block specific tunes and common tunes\r\n */\r\n public getTunes(): {\r\n toolTunes: PopoverItemParams[];\r\n commonTunes: PopoverItemParams[];\r\n } {\r\n const toolTunesPopoverParams: TunesMenuConfigItem[] = [];\r\n const commonTunesPopoverParams: TunesMenuConfigItem[] = [];\r\n\r\n /** Tool's tunes: may be defined as return value of optional renderSettings method */\r\n const tunesDefinedInTool = typeof this.toolInstance.renderSettings === 'function' ? this.toolInstance.renderSettings() : [];\r\n\r\n if ($.isElement(tunesDefinedInTool)) {\r\n toolTunesPopoverParams.push({\r\n type: PopoverItemType.Html,\r\n element: tunesDefinedInTool,\r\n });\r\n } else if (Array.isArray(tunesDefinedInTool)) {\r\n toolTunesPopoverParams.push(...tunesDefinedInTool);\r\n } else {\r\n toolTunesPopoverParams.push(tunesDefinedInTool);\r\n }\r\n\r\n /** Common tunes: combination of default tunes (move up, move down, delete) and third-party tunes connected via tunes api */\r\n const commonTunes = [\r\n ...this.tunesInstances.values(),\r\n ...this.defaultTunesInstances.values(),\r\n ].map(tuneInstance => tuneInstance.render());\r\n\r\n /** Separate custom html from Popover items params for common tunes */\r\n commonTunes.forEach(tuneConfig => {\r\n if ($.isElement(tuneConfig)) {\r\n commonTunesPopoverParams.push({\r\n type: PopoverItemType.Html,\r\n element: tuneConfig,\r\n });\r\n } else if (Array.isArray(tuneConfig)) {\r\n commonTunesPopoverParams.push(...tuneConfig);\r\n } else {\r\n commonTunesPopoverParams.push(tuneConfig);\r\n }\r\n });\r\n\r\n return {\r\n toolTunes: toolTunesPopoverParams,\r\n commonTunes: commonTunesPopoverParams,\r\n };\r\n }\r\n\r\n /**\r\n * Update current input index with selection anchor node\r\n */\r\n public updateCurrentInput(): void {\r\n /**\r\n * If activeElement is native input, anchorNode points to its parent.\r\n * So if it is native input use it instead of anchorNode\r\n *\r\n * If anchorNode is undefined, also use activeElement\r\n */\r\n this.currentInput = $.isNativeInput(document.activeElement) || !SelectionUtils.anchorNode\r\n ? document.activeElement\r\n : SelectionUtils.anchorNode;\r\n }\r\n\r\n /**\r\n * Allows to say Editor that Block was changed. Used to manually trigger Editor's 'onChange' callback\r\n * Can be useful for block changes invisible for editor core.\r\n */\r\n public dispatchChange(): void {\r\n this.didMutated();\r\n }\r\n\r\n /**\r\n * Call Tool instance destroy method\r\n */\r\n public destroy(): void {\r\n this.unwatchBlockMutations();\r\n this.removeInputEvents();\r\n\r\n super.destroy();\r\n\r\n if (_.isFunction(this.toolInstance.destroy)) {\r\n this.toolInstance.destroy();\r\n }\r\n }\r\n\r\n /**\r\n * Tool could specify several entries to be displayed at the Toolbox (for example, \"Heading 1\", \"Heading 2\", \"Heading 3\")\r\n * This method returns the entry that is related to the Block (depended on the Block data)\r\n */\r\n public async getActiveToolboxEntry(): Promise<ToolboxConfigEntry | undefined> {\r\n const toolboxSettings = this.tool.toolbox;\r\n\r\n /**\r\n * If Tool specifies just the single entry, treat it like an active\r\n */\r\n if (toolboxSettings.length === 1) {\r\n return Promise.resolve(this.tool.toolbox[0]);\r\n }\r\n\r\n /**\r\n * If we have several entries with their own data overrides,\r\n * find those who matches some current data property\r\n *\r\n * Example:\r\n * Tools' toolbox: [\r\n * {title: \"Heading 1\", data: {level: 1} },\r\n * {title: \"Heading 2\", data: {level: 2} }\r\n * ]\r\n *\r\n * the Block data: {\r\n * text: \"Heading text\",\r\n * level: 2\r\n * }\r\n *\r\n * that means that for the current block, the second toolbox item (matched by \"{level: 2}\") is active\r\n */\r\n const blockData = await this.data;\r\n const toolboxItems = toolboxSettings;\r\n\r\n return toolboxItems?.find((item) => {\r\n return isSameBlockData(item.data, blockData);\r\n });\r\n }\r\n\r\n /**\r\n * Exports Block data as string using conversion config\r\n */\r\n public async exportDataAsString(): Promise<string> {\r\n const blockData = await this.data;\r\n\r\n return convertBlockDataToString(blockData, this.tool.conversionConfig);\r\n }\r\n\r\n /**\r\n * Make default Block wrappers and put Tool`s content there\r\n *\r\n * @returns {HTMLDivElement}\r\n */\r\n private compose(): HTMLDivElement {\r\n const wrapper = $.make('div', Block.CSS.wrapper) as HTMLDivElement,\r\n contentNode = $.make('div', Block.CSS.content),\r\n pluginsContent = this.toolInstance.render();\r\n\r\n if (import.meta.env.MODE === 'test') {\r\n wrapper.setAttribute('data-cy', 'block-wrapper');\r\n }\r\n\r\n /**\r\n * Export id to the DOM three\r\n * Useful for standalone modules development. For example, allows to identify Block by some child node. Or scroll to a particular Block by id.\r\n */\r\n wrapper.dataset.id = this.id;\r\n\r\n /**\r\n * Saving a reference to plugin's content element for guaranteed accessing it later\r\n */\r\n this.toolRenderedElement = pluginsContent;\r\n\r\n contentNode.appendChild(this.toolRenderedElement);\r\n\r\n /**\r\n * Block Tunes might wrap Block's content node to provide any UI changes\r\n *\r\n * <tune2wrapper>\r\n * <tune1wrapper>\r\n * <blockContent />\r\n * </tune1wrapper>\r\n * </tune2wrapper>\r\n */\r\n let wrappedContentNode: HTMLElement = contentNode;\r\n\r\n [...this.tunesInstances.values(), ...this.defaultTunesInstances.values()]\r\n .forEach((tune) => {\r\n if (_.isFunction(tune.wrap)) {\r\n try {\r\n wrappedContentNode = tune.wrap(wrappedContentNode);\r\n } catch (e) {\r\n _.log(`Tune ${tune.constructor.name} wrap method throws an Error %o`, 'warn', e);\r\n }\r\n }\r\n });\r\n\r\n wrapper.appendChild(wrappedContentNode);\r\n\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * Instantiate Block Tunes\r\n *\r\n * @param tunesData - current Block tunes data\r\n * @private\r\n */\r\n private composeTunes(tunesData: { [name: string]: BlockTuneData }): void {\r\n Array.from(this.tunes.values()).forEach((tune) => {\r\n const collection = tune.isInternal ? this.defaultTunesInstances : this.tunesInstances;\r\n\r\n collection.set(tune.name, tune.create(tunesData[tune.name], this.blockAPI));\r\n });\r\n\r\n /**\r\n * Check if there is some data for not available tunes\r\n */\r\n Object.entries(tunesData).forEach(([name, data]) => {\r\n if (!this.tunesInstances.has(name)) {\r\n this.unavailableTunesData[name] = data;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Is fired when text input or contentEditable is focused\r\n */\r\n private handleFocus = (): void => {\r\n /**\r\n * Drop inputs cache to query the new ones\r\n */\r\n this.dropInputsCache();\r\n\r\n /**\r\n * Update current input\r\n */\r\n this.updateCurrentInput();\r\n };\r\n\r\n /**\r\n * Adds focus event listeners to all inputs and contenteditable\r\n */\r\n private addInputEvents(): void {\r\n this.inputs.forEach(input => {\r\n input.addEventListener('focus', this.handleFocus);\r\n\r\n /**\r\n * If input is native input add oninput listener to observe changes\r\n */\r\n if ($.isNativeInput(input)) {\r\n input.addEventListener('input', this.didMutated as EventListener);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * removes focus event listeners from all inputs and contenteditable\r\n */\r\n private removeInputEvents(): void {\r\n this.inputs.forEach(input => {\r\n input.removeEventListener('focus', this.handleFocus);\r\n\r\n if ($.isNativeInput(input)) {\r\n input.removeEventListener('input', this.didMutated as EventListener);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Is fired when DOM mutation has been happened\r\n *\r\n * @param mutationsOrInputEvent - actual changes\r\n * - MutationRecord[] - any DOM change\r\n * - InputEvent — <input> change\r\n * - undefined — manual triggering of block.dispatchChange()\r\n */\r\n private readonly didMutated = (mutationsOrInputEvent: MutationRecord[] | InputEvent = undefined): void => {\r\n /**\r\n * Block API have dispatchChange() method. In this case, mutations list will be undefined.\r\n */\r\n const isManuallyDispatched = mutationsOrInputEvent === undefined;\r\n\r\n /**\r\n * True if didMutated has been called as \"input\" event handler\r\n */\r\n const isInputEventHandler = mutationsOrInputEvent instanceof InputEvent;\r\n\r\n /**\r\n * If tool updates its own root element, we need to renew it in our memory\r\n */\r\n if (!isManuallyDispatched && !isInputEventHandler) {\r\n this.detectToolRootChange(mutationsOrInputEvent);\r\n }\r\n\r\n /**\r\n * We won't fire a Block mutation event if mutation contain only nodes marked with 'data-mutation-free' attributes\r\n */\r\n let shouldFireUpdate;\r\n\r\n if (isManuallyDispatched) {\r\n shouldFireUpdate = true;\r\n } else if (isInputEventHandler) {\r\n shouldFireUpdate = true;\r\n } else {\r\n /**\r\n * Update from 2023, Feb 17:\r\n * Changed mutationsOrInputEvent.some() to mutationsOrInputEvent.every()\r\n * since there could be a real mutations same-time with mutation-free changes,\r\n * for example when Block Tune change: block is changing along with FakeCursor (mutation-free) removing\r\n * — we should fire 'didMutated' event in that case\r\n */\r\n const everyRecordIsMutationFree = mutationsOrInputEvent.length > 0 && mutationsOrInputEvent.every((record) => {\r\n const { addedNodes, removedNodes, target } = record;\r\n const changedNodes = [\r\n ...Array.from(addedNodes),\r\n ...Array.from(removedNodes),\r\n target,\r\n ];\r\n\r\n return changedNodes.some((node) => {\r\n if (!$.isElement(node)) {\r\n /**\r\n * \"characterData\" mutation record has Text node as a target, so we need to get parent element to check it for mutation-free attribute\r\n */\r\n node = node.parentElement;\r\n }\r\n\r\n return node && (node as HTMLElement).closest('[data-mutation-free=\"true\"]') !== null;\r\n });\r\n });\r\n\r\n shouldFireUpdate = !everyRecordIsMutationFree;\r\n }\r\n\r\n /**\r\n * In case some mutation free elements are added or removed, do not trigger didMutated event\r\n */\r\n if (!shouldFireUpdate) {\r\n return;\r\n }\r\n\r\n this.dropInputsCache();\r\n\r\n /**\r\n * Update current input\r\n */\r\n this.updateCurrentInput();\r\n\r\n /**\r\n * We mark inputs with 'data-empty' attribute, so new inputs should be marked as well\r\n */\r\n this.toggleInputsEmptyMark();\r\n\r\n this.call(BlockToolAPI.UPDATED);\r\n\r\n /**\r\n * Emit a Block Event with current Block instance.\r\n * Block Manager subscribed to these events\r\n */\r\n this.emit('didMutated', this);\r\n };\r\n\r\n /**\r\n * Listen common editor Dom Changed event and detect mutations related to the Block\r\n */\r\n private watchBlockMutations(): void {\r\n /**\r\n * Save callback to a property to remove it on Block destroy\r\n *\r\n * @param payload - event payload\r\n */\r\n this.redactorDomChangedCallback = (payload) => {\r\n const { mutations } = payload;\r\n\r\n const mutationBelongsToBlock = mutations.some(record => isMutationBelongsToElement(record, this.toolRenderedElement));\r\n\r\n if (mutationBelongsToBlock) {\r\n this.didMutated(mutations);\r\n }\r\n };\r\n\r\n this.editorEventBus?.on(RedactorDomChanged, this.redactorDomChangedCallback);\r\n }\r\n\r\n /**\r\n * Remove redactor dom change event listener\r\n */\r\n private unwatchBlockMutations(): void {\r\n this.editorEventBus?.off(RedactorDomChanged, this.redactorDomChangedCallback);\r\n }\r\n\r\n /**\r\n * Sometimes Tool can replace own main element, for example H2 -> H4 or UL -> OL\r\n * We need to detect such changes and update a link to tools main element with the new one\r\n *\r\n * @param mutations - records of block content mutations\r\n */\r\n private detectToolRootChange(mutations: MutationRecord[]): void {\r\n mutations.forEach(record => {\r\n const toolRootHasBeenUpdated = Array.from(record.removedNodes).includes(this.toolRenderedElement);\r\n\r\n if (toolRootHasBeenUpdated) {\r\n const newToolElement = record.addedNodes[record.addedNodes.length - 1];\r\n\r\n this.toolRenderedElement = newToolElement as HTMLElement;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Clears inputs cached value\r\n */\r\n private dropInputsCache(): void {\r\n this.cachedInputs = [];\r\n }\r\n\r\n /**\r\n * Mark inputs with 'data-empty' attribute with the empty state\r\n */\r\n private toggleInputsEmptyMark(): void {\r\n this.inputs.forEach(toggleEmptyMark);\r\n }\r\n}\r\n","import type { BlockAPI as BlockAPIInterface, Blocks } from '../../../../types/api';\r\nimport type { BlockToolData, OutputBlockData, OutputData, ToolConfig } from '../../../../types';\r\nimport * as _ from '../../utils';\r\nimport BlockAPI from '../../block/api';\r\nimport Module from '../../__module';\r\nimport Block from '../../block';\r\nimport { capitalize } from '../../utils';\r\nimport type { BlockTuneData } from '../../../../types/block-tunes/block-tune-data';\r\n\r\n/**\r\n * @class BlocksAPI\r\n * provides with methods working with Block\r\n */\r\nexport default class BlocksAPI extends Module {\r\n /**\r\n * Available methods\r\n *\r\n * @returns {Blocks}\r\n */\r\n public get methods(): Blocks {\r\n return {\r\n clear: (): Promise<void> => this.clear(),\r\n render: (data: OutputData): Promise<void> => this.render(data),\r\n renderFromHTML: (data: string): Promise<void> => this.renderFromHTML(data),\r\n delete: (index?: number): void => this.delete(index),\r\n swap: (fromIndex: number, toIndex: number): void => this.swap(fromIndex, toIndex),\r\n move: (toIndex: number, fromIndex?: number): void => this.move(toIndex, fromIndex),\r\n getBlockByIndex: (index: number): BlockAPIInterface | undefined => this.getBlockByIndex(index),\r\n getById: (id: string): BlockAPIInterface | null => this.getById(id),\r\n getCurrentBlockIndex: (): number => this.getCurrentBlockIndex(),\r\n getBlockIndex: (id: string): number => this.getBlockIndex(id),\r\n getBlocksCount: (): number => this.getBlocksCount(),\r\n getBlockByElement: (element: HTMLElement) => this.getBlockByElement(element),\r\n stretchBlock: (index: number, status = true): void => this.stretchBlock(index, status),\r\n insertNewBlock: (): void => this.insertNewBlock(),\r\n insert: this.insert,\r\n insertMany: this.insertMany,\r\n update: this.update,\r\n composeBlockData: this.composeBlockData,\r\n convert: this.convert,\r\n };\r\n }\r\n\r\n /**\r\n * Returns Blocks count\r\n *\r\n * @returns {number}\r\n */\r\n public getBlocksCount(): number {\r\n return this.Editor.BlockManager.blocks.length;\r\n }\r\n\r\n /**\r\n * Returns current block index\r\n *\r\n * @returns {number}\r\n */\r\n public getCurrentBlockIndex(): number {\r\n return this.Editor.BlockManager.currentBlockIndex;\r\n }\r\n\r\n /**\r\n * Returns the index of Block by id;\r\n *\r\n * @param id - block id\r\n */\r\n public getBlockIndex(id: string): number | undefined {\r\n const block = this.Editor.BlockManager.getBlockById(id);\r\n\r\n if (!block) {\r\n _.logLabeled('There is no block with id `' + id + '`', 'warn');\r\n\r\n return;\r\n }\r\n\r\n return this.Editor.BlockManager.getBlockIndex(block);\r\n }\r\n\r\n /**\r\n * Returns BlockAPI object by Block index\r\n *\r\n * @param {number} index - index to get\r\n */\r\n public getBlockByIndex(index: number): BlockAPIInterface | undefined {\r\n const block = this.Editor.BlockManager.getBlockByIndex(index);\r\n\r\n if (block === undefined) {\r\n _.logLabeled('There is no block at index `' + index + '`', 'warn');\r\n\r\n return;\r\n }\r\n\r\n return new BlockAPI(block);\r\n }\r\n\r\n /**\r\n * Returns BlockAPI object by Block id\r\n *\r\n * @param id - id of block to get\r\n */\r\n public getById(id: string): BlockAPIInterface | null {\r\n const block = this.Editor.BlockManager.getBlockById(id);\r\n\r\n if (block === undefined) {\r\n _.logLabeled('There is no block with id `' + id + '`', 'warn');\r\n\r\n return null;\r\n }\r\n\r\n return new BlockAPI(block);\r\n }\r\n\r\n /**\r\n * Get Block API object by any child html element\r\n *\r\n * @param element - html element to get Block by\r\n */\r\n public getBlockByElement(element: HTMLElement): BlockAPIInterface | undefined {\r\n const block = this.Editor.BlockManager.getBlock(element);\r\n\r\n if (block === undefined) {\r\n _.logLabeled('There is no block corresponding to element `' + element + '`', 'warn');\r\n\r\n return;\r\n }\r\n\r\n return new BlockAPI(block);\r\n }\r\n\r\n /**\r\n * Call Block Manager method that swap Blocks\r\n *\r\n * @param {number} fromIndex - position of first Block\r\n * @param {number} toIndex - position of second Block\r\n * @deprecated — use 'move' instead\r\n */\r\n public swap(fromIndex: number, toIndex: number): void {\r\n _.log(\r\n '`blocks.swap()` method is deprecated and will be removed in the next major release. ' +\r\n 'Use `block.move()` method instead',\r\n 'info'\r\n );\r\n\r\n this.Editor.BlockManager.swap(fromIndex, toIndex);\r\n }\r\n\r\n /**\r\n * Move block from one index to another\r\n *\r\n * @param {number} toIndex - index to move to\r\n * @param {number} fromIndex - index to move from\r\n */\r\n public move(toIndex: number, fromIndex?: number): void {\r\n this.Editor.BlockManager.move(toIndex, fromIndex);\r\n }\r\n\r\n /**\r\n * Deletes Block\r\n *\r\n * @param {number} blockIndex - index of Block to delete\r\n */\r\n public delete(blockIndex: number = this.Editor.BlockManager.currentBlockIndex): void {\r\n try {\r\n const block = this.Editor.BlockManager.getBlockByIndex(blockIndex);\r\n\r\n this.Editor.BlockManager.removeBlock(block);\r\n } catch (e) {\r\n _.logLabeled(e, 'warn');\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * in case of last block deletion\r\n * Insert the new default empty block\r\n */\r\n if (this.Editor.BlockManager.blocks.length === 0) {\r\n this.Editor.BlockManager.insert();\r\n }\r\n\r\n /**\r\n * After Block deletion currentBlock is updated\r\n */\r\n if (this.Editor.BlockManager.currentBlock) {\r\n this.Editor.Caret.setToBlock(this.Editor.BlockManager.currentBlock, this.Editor.Caret.positions.END);\r\n }\r\n\r\n this.Editor.Toolbar.close();\r\n }\r\n\r\n /**\r\n * Clear Editor's area\r\n */\r\n public async clear(): Promise<void> {\r\n await this.Editor.BlockManager.clear(true);\r\n this.Editor.InlineToolbar.close();\r\n }\r\n\r\n /**\r\n * Fills Editor with Blocks data\r\n *\r\n * @param {OutputData} data — Saved Editor data\r\n */\r\n public async render(data: OutputData): Promise<void> {\r\n if (data === undefined || data.blocks === undefined) {\r\n throw new Error('Incorrect data passed to the render() method');\r\n }\r\n\r\n /**\r\n * Semantic meaning of the \"render\" method: \"Display the new document over the existing one that stays unchanged\"\r\n * So we need to disable modifications observer temporarily\r\n */\r\n this.Editor.ModificationsObserver.disable();\r\n\r\n await this.Editor.BlockManager.clear();\r\n await this.Editor.Renderer.render(data.blocks);\r\n\r\n this.Editor.ModificationsObserver.enable();\r\n }\r\n\r\n /**\r\n * Render passed HTML string\r\n *\r\n * @param {string} data - HTML string to render\r\n * @returns {Promise<void>}\r\n */\r\n public async renderFromHTML(data: string): Promise<void> {\r\n await this.Editor.BlockManager.clear();\r\n\r\n return this.Editor.Paste.processText(data, true);\r\n }\r\n\r\n /**\r\n * Stretch Block's content\r\n *\r\n * @param {number} index - index of Block to stretch\r\n * @param {boolean} status - true to enable, false to disable\r\n * @deprecated Use BlockAPI interface to stretch Blocks\r\n */\r\n public stretchBlock(index: number, status = true): void {\r\n _.deprecationAssert(\r\n true,\r\n 'blocks.stretchBlock()',\r\n 'BlockAPI'\r\n );\r\n\r\n const block = this.Editor.BlockManager.getBlockByIndex(index);\r\n\r\n if (!block) {\r\n return;\r\n }\r\n\r\n block.stretched = status;\r\n }\r\n\r\n /**\r\n * Insert new Block and returns it's API\r\n *\r\n * @param {string} type — Tool name\r\n * @param {BlockToolData} data — Tool data to insert\r\n * @param {ToolConfig} config — Tool config\r\n * @param {number?} index — index where to insert new Block\r\n * @param {boolean?} needToFocus - flag to focus inserted Block\r\n * @param replace - pass true to replace the Block existed under passed index\r\n * @param {string} id — An optional id for the new block. If omitted then the new id will be generated\r\n */\r\n public insert = (\r\n type: string = this.config.defaultBlock,\r\n data: BlockToolData = {},\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars\r\n config: ToolConfig = {},\r\n index?: number,\r\n needToFocus?: boolean,\r\n replace?: boolean,\r\n id?: string\r\n ): BlockAPIInterface => {\r\n const insertedBlock = this.Editor.BlockManager.insert({\r\n id,\r\n tool: type,\r\n data,\r\n index,\r\n needToFocus,\r\n replace,\r\n });\r\n\r\n return new BlockAPI(insertedBlock);\r\n };\r\n\r\n /**\r\n * Creates data of an empty block with a passed type.\r\n *\r\n * @param toolName - block tool name\r\n */\r\n public composeBlockData = async (toolName: string): Promise<BlockToolData> => {\r\n const tool = this.Editor.Tools.blockTools.get(toolName);\r\n const block = new Block({\r\n tool,\r\n api: this.Editor.API,\r\n readOnly: true,\r\n data: {},\r\n tunesData: {},\r\n });\r\n\r\n return block.data;\r\n };\r\n\r\n /**\r\n * Insert new Block\r\n * After set caret to this Block\r\n *\r\n * @todo remove in 3.0.0\r\n * @deprecated with insert() method\r\n */\r\n public insertNewBlock(): void {\r\n _.log('Method blocks.insertNewBlock() is deprecated and it will be removed in the next major release. ' +\r\n 'Use blocks.insert() instead.', 'warn');\r\n this.insert();\r\n }\r\n\r\n /**\r\n * Updates block data by id\r\n *\r\n * @param id - id of the block to update\r\n * @param data - (optional) the new data\r\n * @param tunes - (optional) tune data\r\n */\r\n public update = async (id: string, data?: Partial<BlockToolData>, tunes?: {[name: string]: BlockTuneData}): Promise<BlockAPIInterface> => {\r\n const { BlockManager } = this.Editor;\r\n const block = BlockManager.getBlockById(id);\r\n\r\n if (block === undefined) {\r\n throw new Error(`Block with id \"${id}\" not found`);\r\n }\r\n\r\n const updatedBlock = await BlockManager.update(block, data, tunes);\r\n\r\n // we cast to any because our BlockAPI has no \"new\" signature\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return new (BlockAPI as any)(updatedBlock);\r\n };\r\n\r\n /**\r\n * Converts block to another type. Both blocks should provide the conversionConfig.\r\n *\r\n * @param id - id of the existing block to convert. Should provide 'conversionConfig.export' method\r\n * @param newType - new block type. Should provide 'conversionConfig.import' method\r\n * @param dataOverrides - optional data overrides for the new block\r\n * @throws Error if conversion is not possible\r\n */\r\n private convert = async (id: string, newType: string, dataOverrides?: BlockToolData): Promise<BlockAPIInterface> => {\r\n const { BlockManager, Tools } = this.Editor;\r\n const blockToConvert = BlockManager.getBlockById(id);\r\n\r\n if (!blockToConvert) {\r\n throw new Error(`Block with id \"${id}\" not found`);\r\n }\r\n\r\n const originalBlockTool = Tools.blockTools.get(blockToConvert.name);\r\n const targetBlockTool = Tools.blockTools.get(newType);\r\n\r\n if (!targetBlockTool) {\r\n throw new Error(`Block Tool with type \"${newType}\" not found`);\r\n }\r\n\r\n const originalBlockConvertable = originalBlockTool?.conversionConfig?.export !== undefined;\r\n const targetBlockConvertable = targetBlockTool.conversionConfig?.import !== undefined;\r\n\r\n if (originalBlockConvertable && targetBlockConvertable) {\r\n const newBlock = await BlockManager.convert(blockToConvert, newType, dataOverrides);\r\n\r\n return new BlockAPI(newBlock);\r\n } else {\r\n const unsupportedBlockTypes = [\r\n !originalBlockConvertable ? capitalize(blockToConvert.name) : false,\r\n !targetBlockConvertable ? capitalize(newType) : false,\r\n ].filter(Boolean).join(' and ');\r\n\r\n throw new Error(`Conversion from \"${blockToConvert.name}\" to \"${newType}\" is not possible. ${unsupportedBlockTypes} tool(s) should provide a \"conversionConfig\"`);\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Inserts several Blocks to a specified index\r\n *\r\n * @param blocks - blocks data to insert\r\n * @param index - index to insert the blocks at\r\n */\r\n private insertMany = (\r\n blocks: OutputBlockData[],\r\n index: number = this.Editor.BlockManager.blocks.length - 1\r\n ): BlockAPIInterface[] => {\r\n this.validateIndex(index);\r\n\r\n const blocksToInsert = blocks.map(({ id, type, data }) => {\r\n return this.Editor.BlockManager.composeBlock({\r\n id,\r\n tool: type || (this.config.defaultBlock as string),\r\n data,\r\n });\r\n });\r\n\r\n this.Editor.BlockManager.insertMany(blocksToInsert, index);\r\n\r\n // we cast to any because our BlockAPI has no \"new\" signature\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return blocksToInsert.map((block) => new (BlockAPI as any)(block));\r\n };\r\n\r\n /**\r\n * Validated block index and throws an error if it's invalid\r\n *\r\n * @param index - index to validate\r\n */\r\n private validateIndex(index: unknown): void {\r\n if (typeof index !== 'number') {\r\n throw new Error('Index should be a number');\r\n }\r\n\r\n if (index < 0) {\r\n throw new Error(`Index should be greater than or equal to 0`);\r\n }\r\n\r\n if (index === null) {\r\n throw new Error(`Index should be greater than or equal to 0`);\r\n }\r\n }\r\n}\r\n","import type { BlockAPI } from '../../../types/api/block';\r\nimport type { EditorModules } from '../../types-internal/editor-modules';\r\nimport type Block from '../block';\r\n\r\n/**\r\n * Returns Block instance by passed Block index or Block id\r\n *\r\n * @param attribute - either BlockAPI or Block id or Block index\r\n * @param editor - Editor instance\r\n */\r\nexport function resolveBlock(attribute: BlockAPI | BlockAPI['id'] | number, editor: EditorModules): Block | undefined {\r\n if (typeof attribute === 'number') {\r\n return editor.BlockManager.getBlockByIndex(attribute);\r\n }\r\n\r\n if (typeof attribute === 'string') {\r\n return editor.BlockManager.getBlockById(attribute);\r\n }\r\n\r\n return editor.BlockManager.getBlockById(attribute.id);\r\n}\r\n","import type { BlockAPI, Caret } from '../../../../types/api';\r\nimport Module from '../../__module';\r\nimport { resolveBlock } from '../../utils/api';\r\n\r\n/**\r\n * @class CaretAPI\r\n * provides with methods to work with caret\r\n */\r\nexport default class CaretAPI extends Module {\r\n /**\r\n * Available methods\r\n *\r\n * @returns {Caret}\r\n */\r\n public get methods(): Caret {\r\n return {\r\n setToFirstBlock: this.setToFirstBlock,\r\n setToLastBlock: this.setToLastBlock,\r\n setToPreviousBlock: this.setToPreviousBlock,\r\n setToNextBlock: this.setToNextBlock,\r\n setToBlock: this.setToBlock,\r\n focus: this.focus,\r\n };\r\n }\r\n\r\n /**\r\n * Sets caret to the first Block\r\n *\r\n * @param {string} position - position where to set caret\r\n * @param {number} offset - caret offset\r\n * @returns {boolean}\r\n */\r\n private setToFirstBlock = (position: string = this.Editor.Caret.positions.DEFAULT, offset = 0): boolean => {\r\n if (!this.Editor.BlockManager.firstBlock) {\r\n return false;\r\n }\r\n\r\n this.Editor.Caret.setToBlock(this.Editor.BlockManager.firstBlock, position, offset);\r\n\r\n return true;\r\n };\r\n\r\n /**\r\n * Sets caret to the last Block\r\n *\r\n * @param {string} position - position where to set caret\r\n * @param {number} offset - caret offset\r\n * @returns {boolean}\r\n */\r\n private setToLastBlock = (position: string = this.Editor.Caret.positions.DEFAULT, offset = 0): boolean => {\r\n if (!this.Editor.BlockManager.lastBlock) {\r\n return false;\r\n }\r\n\r\n this.Editor.Caret.setToBlock(this.Editor.BlockManager.lastBlock, position, offset);\r\n\r\n return true;\r\n };\r\n\r\n /**\r\n * Sets caret to the previous Block\r\n *\r\n * @param {string} position - position where to set caret\r\n * @param {number} offset - caret offset\r\n * @returns {boolean}\r\n */\r\n private setToPreviousBlock = (\r\n position: string = this.Editor.Caret.positions.DEFAULT,\r\n offset = 0\r\n ): boolean => {\r\n if (!this.Editor.BlockManager.previousBlock) {\r\n return false;\r\n }\r\n\r\n this.Editor.Caret.setToBlock(this.Editor.BlockManager.previousBlock, position, offset);\r\n\r\n return true;\r\n };\r\n\r\n /**\r\n * Sets caret to the next Block\r\n *\r\n * @param {string} position - position where to set caret\r\n * @param {number} offset - caret offset\r\n * @returns {boolean}\r\n */\r\n private setToNextBlock = (position: string = this.Editor.Caret.positions.DEFAULT, offset = 0): boolean => {\r\n if (!this.Editor.BlockManager.nextBlock) {\r\n return false;\r\n }\r\n\r\n this.Editor.Caret.setToBlock(this.Editor.BlockManager.nextBlock, position, offset);\r\n\r\n return true;\r\n };\r\n\r\n /**\r\n * Sets caret to the Block by passed index\r\n *\r\n * @param blockOrIdOrIndex - either BlockAPI or Block id or Block index\r\n * @param position - position where to set caret\r\n * @param offset - caret offset\r\n * @returns {boolean}\r\n */\r\n private setToBlock = (\r\n blockOrIdOrIndex: BlockAPI | BlockAPI['id'] | number,\r\n position: string = this.Editor.Caret.positions.DEFAULT,\r\n offset = 0\r\n ): boolean => {\r\n const block = resolveBlock(blockOrIdOrIndex, this.Editor);\r\n\r\n if (block === undefined) {\r\n return false;\r\n }\r\n\r\n this.Editor.Caret.setToBlock(block, position, offset);\r\n\r\n return true;\r\n };\r\n\r\n /**\r\n * Sets caret to the Editor\r\n *\r\n * @param {boolean} atEnd - if true, set Caret to the end of the Editor\r\n * @returns {boolean}\r\n */\r\n private focus = (atEnd = false): boolean => {\r\n if (atEnd) {\r\n return this.setToLastBlock(this.Editor.Caret.positions.END);\r\n }\r\n\r\n return this.setToFirstBlock(this.Editor.Caret.positions.START);\r\n };\r\n}\r\n","import Module from '../../__module';\r\nimport type { Events } from '../../../../types/api';\r\n\r\n/**\r\n * @class EventsAPI\r\n * provides with methods working with Toolbar\r\n */\r\nexport default class EventsAPI extends Module {\r\n /**\r\n * Available methods\r\n *\r\n * @returns {Events}\r\n */\r\n public get methods(): Events {\r\n return {\r\n emit: (eventName: string, data: object): void => this.emit(eventName, data),\r\n off: (eventName: string, callback: () => void): void => this.off(eventName, callback),\r\n on: (eventName: string, callback: () => void): void => this.on(eventName, callback),\r\n };\r\n }\r\n\r\n /**\r\n * Subscribe on Events\r\n *\r\n * @param {string} eventName - event name to subscribe\r\n * @param {Function} callback - event handler\r\n */\r\n public on(eventName, callback): void {\r\n this.eventsDispatcher.on(eventName, callback);\r\n }\r\n\r\n /**\r\n * Emit event with data\r\n *\r\n * @param {string} eventName - event to emit\r\n * @param {object} data - event's data\r\n */\r\n public emit(eventName, data): void {\r\n this.eventsDispatcher.emit(eventName, data);\r\n }\r\n\r\n /**\r\n * Unsubscribe from Event\r\n *\r\n * @param {string} eventName - event to unsubscribe\r\n * @param {Function} callback - event handler\r\n */\r\n public off(eventName, callback): void {\r\n this.eventsDispatcher.off(eventName, callback);\r\n }\r\n}\r\n","import type { I18n } from '../../../../types/api';\r\nimport I18nInternal from '../../i18n';\r\nimport { logLabeled } from '../../utils';\r\nimport Module from '../../__module';\r\n\r\n/**\r\n * Provides methods for working with i18n\r\n */\r\nexport default class I18nAPI extends Module {\r\n /**\r\n * Return namespace section for tool or block tune\r\n *\r\n * @param toolName - tool name\r\n * @param isTune - is tool a block tune\r\n */\r\n private static getNamespace(toolName, isTune): string {\r\n if (isTune) {\r\n return `blockTunes.${toolName}`;\r\n }\r\n\r\n return `tools.${toolName}`;\r\n }\r\n\r\n /**\r\n * Return I18n API methods with global dictionary access\r\n */\r\n public get methods(): I18n {\r\n return {\r\n t: (): string | undefined => {\r\n logLabeled('I18n.t() method can be accessed only from Tools', 'warn');\r\n\r\n return undefined;\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Return I18n API methods with tool namespaced dictionary\r\n *\r\n * @param toolName - tool name\r\n * @param isTune - is tool a block tune\r\n */\r\n public getMethodsForTool(toolName: string, isTune: boolean): I18n {\r\n return Object.assign(\r\n this.methods,\r\n {\r\n t: (dictKey: string): string => {\r\n return I18nInternal.t(I18nAPI.getNamespace(toolName, isTune), dictKey);\r\n },\r\n });\r\n }\r\n}\r\n","/**\r\n * @module API\r\n * @copyright <CodeX> 2018\r\n *\r\n * Each block has an Editor API instance to use provided public methods\r\n * if you cant to read more about how API works, please see docs\r\n */\r\nimport Module from '../../__module';\r\nimport type { API as APIInterfaces } from '../../../../types';\r\n\r\n/**\r\n * @class API\r\n */\r\nexport default class API extends Module {\r\n /**\r\n * Editor.js Core API modules\r\n */\r\n public get methods(): APIInterfaces {\r\n return {\r\n blocks: this.Editor.BlocksAPI.methods,\r\n caret: this.Editor.CaretAPI.methods,\r\n tools: this.Editor.ToolsAPI.methods,\r\n events: this.Editor.EventsAPI.methods,\r\n listeners: this.Editor.ListenersAPI.methods,\r\n notifier: this.Editor.NotifierAPI.methods,\r\n sanitizer: this.Editor.SanitizerAPI.methods,\r\n saver: this.Editor.SaverAPI.methods,\r\n selection: this.Editor.SelectionAPI.methods,\r\n styles: this.Editor.StylesAPI.classes,\r\n toolbar: this.Editor.ToolbarAPI.methods,\r\n inlineToolbar: this.Editor.InlineToolbarAPI.methods,\r\n tooltip: this.Editor.TooltipAPI.methods,\r\n i18n: this.Editor.I18nAPI.methods,\r\n readOnly: this.Editor.ReadOnlyAPI.methods,\r\n ui: this.Editor.UiAPI.methods,\r\n };\r\n }\r\n\r\n /**\r\n * Returns Editor.js Core API methods for passed tool\r\n *\r\n * @param toolName - tool name\r\n * @param isTune - is tool a block tune\r\n */\r\n public getMethodsForTool(toolName: string, isTune: boolean): APIInterfaces {\r\n return Object.assign(\r\n this.methods,\r\n {\r\n i18n: this.Editor.I18nAPI.getMethodsForTool(toolName, isTune),\r\n }\r\n ) as APIInterfaces;\r\n }\r\n}\r\n","import type { InlineToolbar } from '../../../../types/api/inline-toolbar';\r\nimport Module from '../../__module';\r\n\r\n/**\r\n * @class InlineToolbarAPI\r\n * Provides methods for working with the Inline Toolbar\r\n */\r\nexport default class InlineToolbarAPI extends Module {\r\n /**\r\n * Available methods\r\n *\r\n * @returns {InlineToolbar}\r\n */\r\n public get methods(): InlineToolbar {\r\n return {\r\n close: (): void => this.close(),\r\n open: (): void => this.open(),\r\n };\r\n }\r\n\r\n /**\r\n * Open Inline Toolbar\r\n */\r\n public open(): void {\r\n this.Editor.InlineToolbar.tryToShow();\r\n }\r\n\r\n /**\r\n * Close Inline Toolbar\r\n */\r\n public close(): void {\r\n this.Editor.InlineToolbar.close();\r\n }\r\n}\r\n","import type { Listeners } from '../../../../types/api';\r\nimport Module from '../../__module';\r\n\r\n/**\r\n * @class ListenersAPI\r\n * Provides with methods working with DOM Listener\r\n */\r\nexport default class ListenersAPI extends Module {\r\n /**\r\n * Available methods\r\n *\r\n * @returns {Listeners}\r\n */\r\n public get methods(): Listeners {\r\n return {\r\n on: (element: HTMLElement, eventType, handler, useCapture): string => this.on(element, eventType, handler, useCapture),\r\n off: (element, eventType, handler, useCapture): void => this.off(element, eventType, handler, useCapture),\r\n offById: (id): void => this.offById(id),\r\n };\r\n }\r\n\r\n /**\r\n * Ads a DOM event listener. Return it's id.\r\n *\r\n * @param {HTMLElement} element - Element to set handler to\r\n * @param {string} eventType - event type\r\n * @param {() => void} handler - event handler\r\n * @param {boolean} useCapture - capture event or not\r\n */\r\n public on(element: HTMLElement, eventType: string, handler: () => void, useCapture?: boolean): string {\r\n return this.listeners.on(element, eventType, handler, useCapture);\r\n }\r\n\r\n /**\r\n * Removes DOM listener from element\r\n *\r\n * @param {Element} element - Element to remove handler from\r\n * @param eventType - event type\r\n * @param handler - event handler\r\n * @param {boolean} useCapture - capture event or not\r\n */\r\n public off(element: Element, eventType: string, handler: () => void, useCapture?: boolean): void {\r\n this.listeners.off(element, eventType, handler, useCapture);\r\n }\r\n\r\n /**\r\n * Removes DOM listener by the listener id\r\n *\r\n * @param id - id of the listener to remove\r\n */\r\n public offById(id: string): void {\r\n this.listeners.offById(id);\r\n }\r\n}\r\n","!function(t,e){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define([],e):\"object\"==typeof exports?exports.notifier=e():t.notifier=e()}(window,function(){return function(t){var e={};function n(o){if(e[o])return e[o].exports;var r=e[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:o})},n.r=function(t){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(t,\"__esModule\",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&\"object\"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,\"default\",{enumerable:!0,value:t}),2&e&&\"string\"!=typeof t)for(var r in t)n.d(o,r,function(e){return t[e]}.bind(null,r));return o},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,\"a\",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p=\"/\",n(n.s=0)}([function(t,e,n){\"use strict\";n(1),\n/*!\n * Codex JavaScript Notification module\n * https://github.com/codex-team/js-notifier\n */\nt.exports=function(){var t=n(6),e=\"cdx-notify--bounce-in\",o=null;return{show:function(n){if(n.message){!function(){if(o)return!0;o=t.getWrapper(),document.body.appendChild(o)}();var r=null,i=n.time||8e3;switch(n.type){case\"confirm\":r=t.confirm(n);break;case\"prompt\":r=t.prompt(n);break;default:r=t.alert(n),window.setTimeout(function(){r.remove()},i)}o.appendChild(r),r.classList.add(e)}}}}()},function(t,e,n){var o=n(2);\"string\"==typeof o&&(o=[[t.i,o,\"\"]]);var r={hmr:!0,transform:void 0,insertInto:void 0};n(4)(o,r);o.locals&&(t.exports=o.locals)},function(t,e,n){(t.exports=n(3)(!1)).push([t.i,'.cdx-notify--error{background:#fffbfb!important}.cdx-notify--error::before{background:#fb5d5d!important}.cdx-notify__input{max-width:130px;padding:5px 10px;background:#f7f7f7;border:0;border-radius:3px;font-size:13px;color:#656b7c;outline:0}.cdx-notify__input:-ms-input-placeholder{color:#656b7c}.cdx-notify__input::placeholder{color:#656b7c}.cdx-notify__input:focus:-ms-input-placeholder{color:rgba(101,107,124,.3)}.cdx-notify__input:focus::placeholder{color:rgba(101,107,124,.3)}.cdx-notify__button{border:none;border-radius:3px;font-size:13px;padding:5px 10px;cursor:pointer}.cdx-notify__button:last-child{margin-left:10px}.cdx-notify__button--cancel{background:#f2f5f7;box-shadow:0 2px 1px 0 rgba(16,19,29,0);color:#656b7c}.cdx-notify__button--cancel:hover{background:#eee}.cdx-notify__button--confirm{background:#34c992;box-shadow:0 1px 1px 0 rgba(18,49,35,.05);color:#fff}.cdx-notify__button--confirm:hover{background:#33b082}.cdx-notify__btns-wrapper{display:-ms-flexbox;display:flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;margin-top:5px}.cdx-notify__cross{position:absolute;top:5px;right:5px;width:10px;height:10px;padding:5px;opacity:.54;cursor:pointer}.cdx-notify__cross::after,.cdx-notify__cross::before{content:\\'\\';position:absolute;left:9px;top:5px;height:12px;width:2px;background:#575d67}.cdx-notify__cross::before{transform:rotate(-45deg)}.cdx-notify__cross::after{transform:rotate(45deg)}.cdx-notify__cross:hover{opacity:1}.cdx-notifies{position:fixed;z-index:2;bottom:20px;left:20px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Oxygen,Ubuntu,Cantarell,\"Fira Sans\",\"Droid Sans\",\"Helvetica Neue\",sans-serif}.cdx-notify{position:relative;width:220px;margin-top:15px;padding:13px 16px;background:#fff;box-shadow:0 11px 17px 0 rgba(23,32,61,.13);border-radius:5px;font-size:14px;line-height:1.4em;word-wrap:break-word}.cdx-notify::before{content:\\'\\';position:absolute;display:block;top:0;left:0;width:3px;height:calc(100% - 6px);margin:3px;border-radius:5px;background:0 0}@keyframes bounceIn{0%{opacity:0;transform:scale(.3)}50%{opacity:1;transform:scale(1.05)}70%{transform:scale(.9)}100%{transform:scale(1)}}.cdx-notify--bounce-in{animation-name:bounceIn;animation-duration:.6s;animation-iteration-count:1}.cdx-notify--success{background:#fafffe!important}.cdx-notify--success::before{background:#41ffb1!important}',\"\"])},function(t,e){t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var n=function(t,e){var n=t[1]||\"\",o=t[3];if(!o)return n;if(e&&\"function\"==typeof btoa){var r=(a=o,\"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,\"+btoa(unescape(encodeURIComponent(JSON.stringify(a))))+\" */\"),i=o.sources.map(function(t){return\"/*# sourceURL=\"+o.sourceRoot+t+\" */\"});return[n].concat(i).concat([r]).join(\"\\n\")}var a;return[n].join(\"\\n\")}(e,t);return e[2]?\"@media \"+e[2]+\"{\"+n+\"}\":n}).join(\"\")},e.i=function(t,n){\"string\"==typeof t&&(t=[[null,t,\"\"]]);for(var o={},r=0;r<this.length;r++){var i=this[r][0];\"number\"==typeof i&&(o[i]=!0)}for(r=0;r<t.length;r++){var a=t[r];\"number\"==typeof a[0]&&o[a[0]]||(n&&!a[2]?a[2]=n:n&&(a[2]=\"(\"+a[2]+\") and (\"+n+\")\"),e.push(a))}},e}},function(t,e,n){var o,r,i={},a=(o=function(){return window&&document&&document.all&&!window.atob},function(){return void 0===r&&(r=o.apply(this,arguments)),r}),c=function(t){var e={};return function(t){if(\"function\"==typeof t)return t();if(void 0===e[t]){var n=function(t){return document.querySelector(t)}.call(this,t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(t){n=null}e[t]=n}return e[t]}}(),s=null,f=0,d=[],u=n(5);function l(t,e){for(var n=0;n<t.length;n++){var o=t[n],r=i[o.id];if(r){r.refs++;for(var a=0;a<r.parts.length;a++)r.parts[a](o.parts[a]);for(;a<o.parts.length;a++)r.parts.push(h(o.parts[a],e))}else{var c=[];for(a=0;a<o.parts.length;a++)c.push(h(o.parts[a],e));i[o.id]={id:o.id,refs:1,parts:c}}}}function p(t,e){for(var n=[],o={},r=0;r<t.length;r++){var i=t[r],a=e.base?i[0]+e.base:i[0],c={css:i[1],media:i[2],sourceMap:i[3]};o[a]?o[a].parts.push(c):n.push(o[a]={id:a,parts:[c]})}return n}function b(t,e){var n=c(t.insertInto);if(!n)throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.\");var o=d[d.length-1];if(\"top\"===t.insertAt)o?o.nextSibling?n.insertBefore(e,o.nextSibling):n.appendChild(e):n.insertBefore(e,n.firstChild),d.push(e);else if(\"bottom\"===t.insertAt)n.appendChild(e);else{if(\"object\"!=typeof t.insertAt||!t.insertAt.before)throw new Error(\"[Style Loader]\\n\\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\\n Must be 'top', 'bottom', or Object.\\n (https://github.com/webpack-contrib/style-loader#insertat)\\n\");var r=c(t.insertInto+\" \"+t.insertAt.before);n.insertBefore(e,r)}}function m(t){if(null===t.parentNode)return!1;t.parentNode.removeChild(t);var e=d.indexOf(t);e>=0&&d.splice(e,1)}function x(t){var e=document.createElement(\"style\");return void 0===t.attrs.type&&(t.attrs.type=\"text/css\"),y(e,t.attrs),b(t,e),e}function y(t,e){Object.keys(e).forEach(function(n){t.setAttribute(n,e[n])})}function h(t,e){var n,o,r,i;if(e.transform&&t.css){if(!(i=e.transform(t.css)))return function(){};t.css=i}if(e.singleton){var a=f++;n=s||(s=x(e)),o=_.bind(null,n,a,!1),r=_.bind(null,n,a,!0)}else t.sourceMap&&\"function\"==typeof URL&&\"function\"==typeof URL.createObjectURL&&\"function\"==typeof URL.revokeObjectURL&&\"function\"==typeof Blob&&\"function\"==typeof btoa?(n=function(t){var e=document.createElement(\"link\");return void 0===t.attrs.type&&(t.attrs.type=\"text/css\"),t.attrs.rel=\"stylesheet\",y(e,t.attrs),b(t,e),e}(e),o=function(t,e,n){var o=n.css,r=n.sourceMap,i=void 0===e.convertToAbsoluteUrls&&r;(e.convertToAbsoluteUrls||i)&&(o=u(o));r&&(o+=\"\\n/*# sourceMappingURL=data:application/json;base64,\"+btoa(unescape(encodeURIComponent(JSON.stringify(r))))+\" */\");var a=new Blob([o],{type:\"text/css\"}),c=t.href;t.href=URL.createObjectURL(a),c&&URL.revokeObjectURL(c)}.bind(null,n,e),r=function(){m(n),n.href&&URL.revokeObjectURL(n.href)}):(n=x(e),o=function(t,e){var n=e.css,o=e.media;o&&t.setAttribute(\"media\",o);if(t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}.bind(null,n),r=function(){m(n)});return o(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;o(t=e)}else r()}}t.exports=function(t,e){if(\"undefined\"!=typeof DEBUG&&DEBUG&&\"object\"!=typeof document)throw new Error(\"The style-loader cannot be used in a non-browser environment\");(e=e||{}).attrs=\"object\"==typeof e.attrs?e.attrs:{},e.singleton||\"boolean\"==typeof e.singleton||(e.singleton=a()),e.insertInto||(e.insertInto=\"head\"),e.insertAt||(e.insertAt=\"bottom\");var n=p(t,e);return l(n,e),function(t){for(var o=[],r=0;r<n.length;r++){var a=n[r];(c=i[a.id]).refs--,o.push(c)}t&&l(p(t,e),e);for(r=0;r<o.length;r++){var c;if(0===(c=o[r]).refs){for(var s=0;s<c.parts.length;s++)c.parts[s]();delete i[c.id]}}}};var v,g=(v=[],function(t,e){return v[t]=e,v.filter(Boolean).join(\"\\n\")});function _(t,e,n,o){var r=n?\"\":o.css;if(t.styleSheet)t.styleSheet.cssText=g(e,r);else{var i=document.createTextNode(r),a=t.childNodes;a[e]&&t.removeChild(a[e]),a.length?t.insertBefore(i,a[e]):t.appendChild(i)}}},function(t,e){t.exports=function(t){var e=\"undefined\"!=typeof window&&window.location;if(!e)throw new Error(\"fixUrls requires window.location\");if(!t||\"string\"!=typeof t)return t;var n=e.protocol+\"//\"+e.host,o=n+e.pathname.replace(/\\/[^\\/]*$/,\"/\");return t.replace(/url\\s*\\(((?:[^)(]|\\((?:[^)(]+|\\([^)(]*\\))*\\))*)\\)/gi,function(t,e){var r,i=e.trim().replace(/^\"(.*)\"$/,function(t,e){return e}).replace(/^'(.*)'$/,function(t,e){return e});return/^(#|data:|http:\\/\\/|https:\\/\\/|file:\\/\\/\\/|\\s*$)/i.test(i)?t:(r=0===i.indexOf(\"//\")?i:0===i.indexOf(\"/\")?n+i:o+i.replace(/^\\.\\//,\"\"),\"url(\"+JSON.stringify(r)+\")\")})}},function(t,e,n){\"use strict\";var o,r,i,a,c,s,f,d,u;t.exports=(o=\"cdx-notifies\",r=\"cdx-notify\",i=\"cdx-notify__cross\",a=\"cdx-notify__button--confirm\",c=\"cdx-notify__button--cancel\",s=\"cdx-notify__input\",f=\"cdx-notify__button\",d=\"cdx-notify__btns-wrapper\",{alert:u=function(t){var e=document.createElement(\"DIV\"),n=document.createElement(\"DIV\"),o=t.message,a=t.style;return e.classList.add(r),a&&e.classList.add(r+\"--\"+a),e.innerHTML=o,n.classList.add(i),n.addEventListener(\"click\",e.remove.bind(e)),e.appendChild(n),e},confirm:function(t){var e=u(t),n=document.createElement(\"div\"),o=document.createElement(\"button\"),r=document.createElement(\"button\"),s=e.querySelector(\".\"+i),l=t.cancelHandler,p=t.okHandler;return n.classList.add(d),o.innerHTML=t.okText||\"Confirm\",r.innerHTML=t.cancelText||\"Cancel\",o.classList.add(f),r.classList.add(f),o.classList.add(a),r.classList.add(c),l&&\"function\"==typeof l&&(r.addEventListener(\"click\",l),s.addEventListener(\"click\",l)),p&&\"function\"==typeof p&&o.addEventListener(\"click\",p),o.addEventListener(\"click\",e.remove.bind(e)),r.addEventListener(\"click\",e.remove.bind(e)),n.appendChild(o),n.appendChild(r),e.appendChild(n),e},prompt:function(t){var e=u(t),n=document.createElement(\"div\"),o=document.createElement(\"button\"),r=document.createElement(\"input\"),c=e.querySelector(\".\"+i),l=t.cancelHandler,p=t.okHandler;return n.classList.add(d),o.innerHTML=t.okText||\"Ok\",o.classList.add(f),o.classList.add(a),r.classList.add(s),t.placeholder&&r.setAttribute(\"placeholder\",t.placeholder),t.default&&(r.value=t.default),t.inputType&&(r.type=t.inputType),l&&\"function\"==typeof l&&c.addEventListener(\"click\",l),p&&\"function\"==typeof p&&o.addEventListener(\"click\",function(){p(r.value)}),o.addEventListener(\"click\",e.remove.bind(e)),n.appendChild(r),n.appendChild(o),e.appendChild(n),e},getWrapper:function(){var t=document.createElement(\"DIV\");return t.classList.add(o),t}})}])});","/**\r\n * Use external package module for notifications\r\n *\r\n * @see https://github.com/codex-team/js-notifier\r\n */\r\nimport type { ConfirmNotifierOptions, NotifierOptions, PromptNotifierOptions } from 'codex-notifier';\r\nimport notifier from 'codex-notifier';\r\n\r\n/**\r\n * Util for showing notifications\r\n */\r\nexport default class Notifier {\r\n /**\r\n * Show web notification\r\n *\r\n * @param {NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions} options - notification options\r\n */\r\n public show(options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions): void {\r\n notifier.show(options);\r\n }\r\n}\r\n","import type { Notifier as INotifier } from '../../../../types/api';\r\nimport Notifier from '../../utils/notifier';\r\nimport type { ConfirmNotifierOptions, NotifierOptions, PromptNotifierOptions } from 'codex-notifier';\r\nimport Module from '../../__module';\r\nimport type { ModuleConfig } from '../../../types-internal/module-config';\r\n\r\n/**\r\n *\r\n */\r\nexport default class NotifierAPI extends Module {\r\n /**\r\n * Notifier utility Instance\r\n */\r\n private notifier: Notifier;\r\n\r\n /**\r\n * @param moduleConfiguration - Module Configuration\r\n * @param moduleConfiguration.config - Editor's config\r\n * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher\r\n */\r\n constructor({ config, eventsDispatcher }: ModuleConfig) {\r\n super({\r\n config,\r\n eventsDispatcher,\r\n });\r\n\r\n this.notifier = new Notifier();\r\n }\r\n\r\n /**\r\n * Available methods\r\n */\r\n public get methods(): INotifier {\r\n return {\r\n show: (options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions): void => this.show(options),\r\n };\r\n }\r\n\r\n /**\r\n * Show notification\r\n *\r\n * @param {NotifierOptions} options - message option\r\n */\r\n public show(options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions): void {\r\n return this.notifier.show(options);\r\n }\r\n}\r\n","import type { ReadOnly } from '../../../../types/api';\r\nimport Module from '../../__module';\r\n\r\n/**\r\n * @class ReadOnlyAPI\r\n * @classdesc ReadOnly API\r\n */\r\nexport default class ReadOnlyAPI extends Module {\r\n /**\r\n * Available methods\r\n */\r\n public get methods(): ReadOnly {\r\n const getIsEnabled = (): boolean => this.isEnabled;\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n return {\r\n toggle: (state): Promise<boolean> => this.toggle(state),\r\n get isEnabled(): boolean {\r\n return getIsEnabled();\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Set or toggle read-only state\r\n *\r\n * @param {boolean|undefined} state - set or toggle state\r\n * @returns {boolean} current value\r\n */\r\n public toggle(state?: boolean): Promise<boolean> {\r\n return this.Editor.ReadOnly.toggle(state);\r\n }\r\n\r\n /**\r\n * Returns current read-only state\r\n */\r\n public get isEnabled(): boolean {\r\n return this.Editor.ReadOnly.isEnabled;\r\n }\r\n}\r\n","(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define('html-janitor', factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.HTMLJanitor = factory();\n }\n}(this, function () {\n\n /**\n * @param {Object} config.tags Dictionary of allowed tags.\n * @param {boolean} config.keepNestedBlockElements Default false.\n */\n function HTMLJanitor(config) {\n\n var tagDefinitions = config['tags'];\n var tags = Object.keys(tagDefinitions);\n\n var validConfigValues = tags\n .map(function(k) { return typeof tagDefinitions[k]; })\n .every(function(type) { return type === 'object' || type === 'boolean' || type === 'function'; });\n\n if(!validConfigValues) {\n throw new Error(\"The configuration was invalid\");\n }\n\n this.config = config;\n }\n\n // TODO: not exhaustive?\n var blockElementNames = ['P', 'LI', 'TD', 'TH', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'PRE'];\n function isBlockElement(node) {\n return blockElementNames.indexOf(node.nodeName) !== -1;\n }\n\n var inlineElementNames = ['A', 'B', 'STRONG', 'I', 'EM', 'SUB', 'SUP', 'U', 'STRIKE'];\n function isInlineElement(node) {\n return inlineElementNames.indexOf(node.nodeName) !== -1;\n }\n\n HTMLJanitor.prototype.clean = function (html) {\n const sandbox = document.implementation.createHTMLDocument();\n const root = sandbox.createElement(\"div\");\n root.innerHTML = html;\n\n this._sanitize(sandbox, root);\n\n return root.innerHTML;\n };\n\n HTMLJanitor.prototype._sanitize = function (document, parentNode) {\n var treeWalker = createTreeWalker(document, parentNode);\n var node = treeWalker.firstChild();\n\n if (!node) { return; }\n\n do {\n if (node.nodeType === Node.TEXT_NODE) {\n // If this text node is just whitespace and the previous or next element\n // sibling is a block element, remove it\n // N.B.: This heuristic could change. Very specific to a bug with\n // `contenteditable` in Firefox: http://jsbin.com/EyuKase/1/edit?js,output\n // FIXME: make this an option?\n if (node.data.trim() === ''\n && ((node.previousElementSibling && isBlockElement(node.previousElementSibling))\n || (node.nextElementSibling && isBlockElement(node.nextElementSibling)))) {\n parentNode.removeChild(node);\n this._sanitize(document, parentNode);\n break;\n } else {\n continue;\n }\n }\n\n // Remove all comments\n if (node.nodeType === Node.COMMENT_NODE) {\n parentNode.removeChild(node);\n this._sanitize(document, parentNode);\n break;\n }\n\n var isInline = isInlineElement(node);\n var containsBlockElement;\n if (isInline) {\n containsBlockElement = Array.prototype.some.call(node.childNodes, isBlockElement);\n }\n\n // Block elements should not be nested (e.g. <li><p>...); if\n // they are, we want to unwrap the inner block element.\n var isNotTopContainer = !! parentNode.parentNode;\n var isNestedBlockElement =\n isBlockElement(parentNode) &&\n isBlockElement(node) &&\n isNotTopContainer;\n\n var nodeName = node.nodeName.toLowerCase();\n\n var allowedAttrs = getAllowedAttrs(this.config, nodeName, node);\n\n var isInvalid = isInline && containsBlockElement;\n\n // Drop tag entirely according to the whitelist *and* if the markup\n // is invalid.\n if (isInvalid || shouldRejectNode(node, allowedAttrs)\n || (!this.config.keepNestedBlockElements && isNestedBlockElement)) {\n // Do not keep the inner text of SCRIPT/STYLE elements.\n if (! (node.nodeName === 'SCRIPT' || node.nodeName === 'STYLE')) {\n while (node.childNodes.length > 0) {\n parentNode.insertBefore(node.childNodes[0], node);\n }\n }\n parentNode.removeChild(node);\n\n this._sanitize(document, parentNode);\n break;\n }\n\n // Sanitize attributes\n for (var a = 0; a < node.attributes.length; a += 1) {\n var attr = node.attributes[a];\n\n if (shouldRejectAttr(attr, allowedAttrs, node)) {\n node.removeAttribute(attr.name);\n // Shift the array to continue looping.\n a = a - 1;\n }\n }\n\n // Sanitize children\n this._sanitize(document, node);\n\n } while ((node = treeWalker.nextSibling()));\n };\n\n function createTreeWalker(document, node) {\n return document.createTreeWalker(node,\n NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT,\n null, false);\n }\n\n function getAllowedAttrs(config, nodeName, node){\n if (typeof config.tags[nodeName] === 'function') {\n return config.tags[nodeName](node);\n } else {\n return config.tags[nodeName];\n }\n }\n\n function shouldRejectNode(node, allowedAttrs){\n if (typeof allowedAttrs === 'undefined') {\n return true;\n } else if (typeof allowedAttrs === 'boolean') {\n return !allowedAttrs;\n }\n\n return false;\n }\n\n function shouldRejectAttr(attr, allowedAttrs, node){\n var attrName = attr.name.toLowerCase();\n\n if (allowedAttrs === true){\n return false;\n } else if (typeof allowedAttrs[attrName] === 'function'){\n return !allowedAttrs[attrName](attr.value, node);\n } else if (typeof allowedAttrs[attrName] === 'undefined'){\n return true;\n } else if (allowedAttrs[attrName] === false) {\n return true;\n } else if (typeof allowedAttrs[attrName] === 'string') {\n return (allowedAttrs[attrName] !== attr.value);\n }\n\n return false;\n }\n\n return HTMLJanitor;\n\n}));\n","/* eslint-disable @typescript-eslint/no-use-before-define */\r\n/**\r\n * CodeX Sanitizer\r\n *\r\n * Clears HTML from taint tags\r\n *\r\n * @version 2.0.0\r\n * @example\r\n *\r\n * clean(yourTaintString, yourConfig);\r\n *\r\n * {@link SanitizerConfig}\r\n */\r\n\r\nimport * as _ from '../utils';\r\n\r\n/**\r\n * @typedef {object} SanitizerConfig\r\n * @property {object} tags - define tags restrictions\r\n * @example\r\n *\r\n * tags : {\r\n * p: true,\r\n * a: {\r\n * href: true,\r\n * rel: \"nofollow\",\r\n * target: \"_blank\"\r\n * }\r\n * }\r\n */\r\n\r\nimport HTMLJanitor from 'html-janitor';\r\nimport type { BlockToolData, SanitizerConfig } from '../../../types';\r\nimport type { SavedData } from '../../../types/data-formats';\r\n\r\n/**\r\n * Sanitize Blocks\r\n *\r\n * Enumerate blocks and clean data\r\n *\r\n * @param blocksData - blocks' data to sanitize\r\n * @param sanitizeConfig — sanitize config to use or function to get config for Tool\r\n */\r\nexport function sanitizeBlocks(\r\n blocksData: Array<Pick<SavedData, 'data' | 'tool'>>,\r\n sanitizeConfig: SanitizerConfig | ((toolName: string) => SanitizerConfig)\r\n): Array<Pick<SavedData, 'data' | 'tool'>> {\r\n return blocksData.map((block) => {\r\n const toolConfig = _.isFunction(sanitizeConfig) ? sanitizeConfig(block.tool) : sanitizeConfig;\r\n\r\n if (_.isEmpty(toolConfig)) {\r\n return block;\r\n }\r\n\r\n block.data = deepSanitize(block.data, toolConfig) as BlockToolData;\r\n\r\n return block;\r\n });\r\n}\r\n/**\r\n * Cleans string from unwanted tags\r\n * Method allows to use default config\r\n *\r\n * @param {string} taintString - taint string\r\n * @param {SanitizerConfig} customConfig - allowed tags\r\n * @returns {string} clean HTML\r\n */\r\nexport function clean(taintString: string, customConfig: SanitizerConfig = {} as SanitizerConfig): string {\r\n const sanitizerConfig = {\r\n tags: customConfig,\r\n };\r\n\r\n /**\r\n * API client can use custom config to manage sanitize process\r\n */\r\n const sanitizerInstance = new HTMLJanitor(sanitizerConfig);\r\n\r\n return sanitizerInstance.clean(taintString);\r\n}\r\n\r\n/**\r\n * Method recursively reduces Block's data and cleans with passed rules\r\n *\r\n * @param {BlockToolData|object|*} dataToSanitize - taint string or object/array that contains taint string\r\n * @param {SanitizerConfig} rules - object with sanitizer rules\r\n */\r\nfunction deepSanitize(dataToSanitize: object | string, rules: SanitizerConfig): object | string {\r\n /**\r\n * BlockData It may contain 3 types:\r\n * - Array\r\n * - Object\r\n * - Primitive\r\n */\r\n if (Array.isArray(dataToSanitize)) {\r\n /**\r\n * Array: call sanitize for each item\r\n */\r\n return cleanArray(dataToSanitize, rules);\r\n } else if (_.isObject(dataToSanitize)) {\r\n /**\r\n * Objects: just clean object deeper.\r\n */\r\n return cleanObject(dataToSanitize, rules);\r\n } else {\r\n /**\r\n * Primitives (number|string|boolean): clean this item\r\n *\r\n * Clean only strings\r\n */\r\n if (_.isString(dataToSanitize)) {\r\n return cleanOneItem(dataToSanitize, rules);\r\n }\r\n\r\n return dataToSanitize;\r\n }\r\n}\r\n\r\n/**\r\n * Clean array\r\n *\r\n * @param {Array} array - [1, 2, {}, []]\r\n * @param {SanitizerConfig} ruleForItem - sanitizer config for array\r\n */\r\nfunction cleanArray(array: Array<object | string>, ruleForItem: SanitizerConfig): Array<object | string> {\r\n return array.map((arrayItem) => deepSanitize(arrayItem, ruleForItem));\r\n}\r\n\r\n/**\r\n * Clean object\r\n *\r\n * @param {object} object - {level: 0, text: 'adada', items: [1,2,3]}}\r\n * @param {object} rules - { b: true } or true|false\r\n * @returns {object}\r\n */\r\nfunction cleanObject(object: object, rules: SanitizerConfig|{[field: string]: SanitizerConfig}): object {\r\n const cleanData = {};\r\n\r\n for (const fieldName in object) {\r\n if (!Object.prototype.hasOwnProperty.call(object, fieldName)) {\r\n continue;\r\n }\r\n\r\n const currentIterationItem = object[fieldName];\r\n\r\n /**\r\n * Get object from config by field name\r\n * - if it is a HTML Janitor rule, call with this rule\r\n * - otherwise, call with parent's config\r\n */\r\n const ruleForItem = isRule(rules[fieldName] as SanitizerConfig) ? rules[fieldName] : rules;\r\n\r\n cleanData[fieldName] = deepSanitize(currentIterationItem, ruleForItem as SanitizerConfig);\r\n }\r\n\r\n return cleanData;\r\n}\r\n\r\n/**\r\n * Clean primitive value\r\n *\r\n * @param {string} taintString - string to clean\r\n * @param {SanitizerConfig|boolean} rule - sanitizer rule\r\n * @returns {string}\r\n */\r\nfunction cleanOneItem(taintString: string, rule: SanitizerConfig|boolean): string {\r\n if (_.isObject(rule)) {\r\n return clean(taintString, rule);\r\n } else if (rule === false) {\r\n return clean(taintString, {} as SanitizerConfig);\r\n } else {\r\n return taintString;\r\n }\r\n}\r\n\r\n/**\r\n * Check if passed item is a HTML Janitor rule:\r\n * { a : true }, {}, false, true, function(){} — correct rules\r\n * undefined, null, 0, 1, 2 — not a rules\r\n *\r\n * @param {SanitizerConfig} config - config to check\r\n */\r\nfunction isRule(config: SanitizerConfig): boolean {\r\n return _.isObject(config) || _.isBoolean(config) || _.isFunction(config);\r\n}\r\n","import type { Sanitizer as ISanitizer } from '../../../../types/api';\r\nimport type { SanitizerConfig } from '../../../../types/configs';\r\nimport Module from '../../__module';\r\nimport { clean } from '../../utils/sanitizer';\r\n\r\n/**\r\n * @class SanitizerAPI\r\n * Provides Editor.js Sanitizer that allows developers to clean their HTML\r\n */\r\nexport default class SanitizerAPI extends Module {\r\n /**\r\n * Available methods\r\n *\r\n * @returns {SanitizerConfig}\r\n */\r\n public get methods(): ISanitizer {\r\n return {\r\n clean: (taintString, config): string => this.clean(taintString, config),\r\n };\r\n }\r\n\r\n /**\r\n * Perform sanitizing of a string\r\n *\r\n * @param {string} taintString - what to sanitize\r\n * @param {SanitizerConfig} config - sanitizer config\r\n * @returns {string}\r\n */\r\n public clean(taintString: string, config: SanitizerConfig): string {\r\n return clean(taintString, config);\r\n }\r\n}\r\n","import type { Saver } from '../../../../types/api';\r\nimport type { OutputData } from '../../../../types';\r\nimport * as _ from '../../utils';\r\nimport Module from '../../__module';\r\n\r\n/**\r\n * @class SaverAPI\r\n * provides with methods to save data\r\n */\r\nexport default class SaverAPI extends Module {\r\n /**\r\n * Available methods\r\n *\r\n * @returns {Saver}\r\n */\r\n public get methods(): Saver {\r\n return {\r\n save: (): Promise<OutputData> => this.save(),\r\n };\r\n }\r\n\r\n /**\r\n * Return Editor's data\r\n *\r\n * @returns {OutputData}\r\n */\r\n public save(): Promise<OutputData> {\r\n const errorText = 'Editor\\'s content can not be saved in read-only mode';\r\n\r\n if (this.Editor.ReadOnly.isEnabled) {\r\n _.logLabeled(errorText, 'warn');\r\n\r\n return Promise.reject(new Error(errorText));\r\n }\r\n\r\n return this.Editor.Saver.save();\r\n }\r\n}\r\n","import SelectionUtils from '../../selection';\r\nimport type { Selection as SelectionAPIInterface } from '../../../../types/api';\r\nimport Module from '../../__module';\r\n\r\n/**\r\n * @class SelectionAPI\r\n * Provides with methods working with SelectionUtils\r\n */\r\nexport default class SelectionAPI extends Module {\r\n /**\r\n * Global SelectionUtils instance\r\n */\r\n private selectionUtils = new SelectionUtils();\r\n\r\n /**\r\n * Available methods\r\n *\r\n * @returns {SelectionAPIInterface}\r\n */\r\n public get methods(): SelectionAPIInterface {\r\n return {\r\n findParentTag: (tagName: string, className?: string): HTMLElement | null => this.findParentTag(tagName, className),\r\n expandToTag: (node: HTMLElement): void => this.expandToTag(node),\r\n save: () => this.selectionUtils.save(),\r\n restore: () => this.selectionUtils.restore(),\r\n setFakeBackground: () => this.selectionUtils.setFakeBackground(),\r\n removeFakeBackground: () => this.selectionUtils.removeFakeBackground(),\r\n };\r\n }\r\n\r\n /**\r\n * Looks ahead from selection and find passed tag with class name\r\n *\r\n * @param {string} tagName - tag to find\r\n * @param {string} className - tag's class name\r\n * @returns {HTMLElement|null}\r\n */\r\n public findParentTag(tagName: string, className?: string): HTMLElement | null {\r\n return this.selectionUtils.findParentTag(tagName, className);\r\n }\r\n\r\n /**\r\n * Expand selection to passed tag\r\n *\r\n * @param {HTMLElement} node - tag that should contain selection\r\n */\r\n public expandToTag(node: HTMLElement): void {\r\n this.selectionUtils.expandToTag(node);\r\n }\r\n}\r\n","import type { Tools as ToolsAPIInterface } from '../../../../types/api';\r\nimport Module from '../../__module';\r\n\r\n/**\r\n * Provides methods for accessing installed Editor tools\r\n */\r\nexport default class ToolsAPI extends Module {\r\n /**\r\n * Available methods\r\n */\r\n public get methods(): ToolsAPIInterface {\r\n return {\r\n getBlockTools: () => Array.from(this.Editor.Tools.blockTools.values()),\r\n };\r\n }\r\n}\r\n","import type { Styles } from '../../../../types/api';\r\nimport Module from '../../__module';\r\n\r\n/**\r\n *\r\n */\r\nexport default class StylesAPI extends Module {\r\n /**\r\n * Exported classes\r\n */\r\n public get classes(): Styles {\r\n return {\r\n /**\r\n * Base Block styles\r\n */\r\n block: 'cdx-block',\r\n\r\n /**\r\n * Inline Tools styles\r\n */\r\n inlineToolButton: 'ce-inline-tool',\r\n inlineToolButtonActive: 'ce-inline-tool--active',\r\n\r\n /**\r\n * UI elements\r\n */\r\n input: 'cdx-input',\r\n loader: 'cdx-loader',\r\n button: 'cdx-button',\r\n\r\n /**\r\n * Settings styles\r\n */\r\n settingsButton: 'cdx-settings-button',\r\n settingsButtonActive: 'cdx-settings-button--active',\r\n };\r\n }\r\n}\r\n","import type { Toolbar } from '../../../../types/api';\r\nimport Module from '../../__module';\r\nimport * as _ from '../../utils';\r\n/**\r\n * @class ToolbarAPI\r\n * Provides methods for working with the Toolbar\r\n */\r\nexport default class ToolbarAPI extends Module {\r\n /**\r\n * Available methods\r\n *\r\n * @returns {Toolbar}\r\n */\r\n public get methods(): Toolbar {\r\n return {\r\n close: (): void => this.close(),\r\n open: (): void => this.open(),\r\n toggleBlockSettings: (openingState?: boolean): void => this.toggleBlockSettings(openingState),\r\n toggleToolbox: (openingState?: boolean): void => this.toggleToolbox(openingState),\r\n };\r\n }\r\n\r\n /**\r\n * Open toolbar\r\n */\r\n public open(): void {\r\n this.Editor.Toolbar.moveAndOpen();\r\n }\r\n\r\n /**\r\n * Close toolbar and all included elements\r\n */\r\n public close(): void {\r\n this.Editor.Toolbar.close();\r\n }\r\n\r\n /**\r\n * Toggles Block Setting of the current block\r\n *\r\n * @param {boolean} openingState — opening state of Block Setting\r\n */\r\n public toggleBlockSettings(openingState?: boolean): void {\r\n if (this.Editor.BlockManager.currentBlockIndex === -1) {\r\n _.logLabeled('Could\\'t toggle the Toolbar because there is no block selected ', 'warn');\r\n\r\n return;\r\n }\r\n\r\n /** Check that opening state is set or not */\r\n const canOpenBlockSettings = openingState ?? !this.Editor.BlockSettings.opened;\r\n\r\n if (canOpenBlockSettings) {\r\n this.Editor.Toolbar.moveAndOpen();\r\n this.Editor.BlockSettings.open();\r\n } else {\r\n this.Editor.BlockSettings.close();\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Open toolbox\r\n *\r\n * @param {boolean} openingState - Opening state of toolbox\r\n */\r\n public toggleToolbox(openingState: boolean): void {\r\n if (this.Editor.BlockManager.currentBlockIndex === -1) {\r\n _.logLabeled('Could\\'t toggle the Toolbox because there is no block selected ', 'warn');\r\n\r\n return;\r\n }\r\n\r\n const canOpenToolbox = openingState ?? !this.Editor.Toolbar.toolbox.opened;\r\n\r\n if (canOpenToolbox) {\r\n this.Editor.Toolbar.moveAndOpen();\r\n this.Editor.Toolbar.toolbox.open();\r\n } else {\r\n this.Editor.Toolbar.toolbox.close();\r\n }\r\n }\r\n}\r\n","/*!\n * CodeX.Tooltips\n * \n * @version 1.0.5\n * \n * @licence MIT\n * @author CodeX <https://codex.so>\n * \n * \n */\n!function(t,e){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define([],e):\"object\"==typeof exports?exports.Tooltip=e():t.Tooltip=e()}(window,(function(){return function(t){var e={};function o(i){if(e[i])return e[i].exports;var n=e[i]={i:i,l:!1,exports:{}};return t[i].call(n.exports,n,n.exports,o),n.l=!0,n.exports}return o.m=t,o.c=e,o.d=function(t,e,i){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},o.r=function(t){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(t,\"__esModule\",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&\"object\"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(o.r(i),Object.defineProperty(i,\"default\",{enumerable:!0,value:t}),2&e&&\"string\"!=typeof t)for(var n in t)o.d(i,n,function(e){return t[e]}.bind(null,n));return i},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,\"a\",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p=\"\",o(o.s=0)}([function(t,e,o){t.exports=o(1)},function(t,e,o){\"use strict\";o.r(e),o.d(e,\"default\",(function(){return i}));class i{constructor(){this.nodes={wrapper:null,content:null},this.showed=!1,this.offsetTop=10,this.offsetLeft=10,this.offsetRight=10,this.hidingDelay=0,this.handleWindowScroll=()=>{this.showed&&this.hide(!0)},this.loadStyles(),this.prepare(),window.addEventListener(\"scroll\",this.handleWindowScroll,{passive:!0})}get CSS(){return{tooltip:\"ct\",tooltipContent:\"ct__content\",tooltipShown:\"ct--shown\",placement:{left:\"ct--left\",bottom:\"ct--bottom\",right:\"ct--right\",top:\"ct--top\"}}}show(t,e,o){this.nodes.wrapper||this.prepare(),this.hidingTimeout&&clearTimeout(this.hidingTimeout);const i=Object.assign({placement:\"bottom\",marginTop:0,marginLeft:0,marginRight:0,marginBottom:0,delay:70,hidingDelay:0},o);if(i.hidingDelay&&(this.hidingDelay=i.hidingDelay),this.nodes.content.innerHTML=\"\",\"string\"==typeof e)this.nodes.content.appendChild(document.createTextNode(e));else{if(!(e instanceof Node))throw Error(\"[CodeX Tooltip] Wrong type of «content» passed. It should be an instance of Node or String. But \"+typeof e+\" given.\");this.nodes.content.appendChild(e)}switch(this.nodes.wrapper.classList.remove(...Object.values(this.CSS.placement)),i.placement){case\"top\":this.placeTop(t,i);break;case\"left\":this.placeLeft(t,i);break;case\"right\":this.placeRight(t,i);break;case\"bottom\":default:this.placeBottom(t,i)}i&&i.delay?this.showingTimeout=setTimeout(()=>{this.nodes.wrapper.classList.add(this.CSS.tooltipShown),this.showed=!0},i.delay):(this.nodes.wrapper.classList.add(this.CSS.tooltipShown),this.showed=!0)}hide(t=!1){if(this.hidingDelay&&!t)return this.hidingTimeout&&clearTimeout(this.hidingTimeout),void(this.hidingTimeout=setTimeout(()=>{this.hide(!0)},this.hidingDelay));this.nodes.wrapper.classList.remove(this.CSS.tooltipShown),this.showed=!1,this.showingTimeout&&clearTimeout(this.showingTimeout)}onHover(t,e,o){t.addEventListener(\"mouseenter\",()=>{this.show(t,e,o)}),t.addEventListener(\"mouseleave\",()=>{this.hide()})}destroy(){this.nodes.wrapper.remove(),window.removeEventListener(\"scroll\",this.handleWindowScroll)}prepare(){this.nodes.wrapper=this.make(\"div\",this.CSS.tooltip),this.nodes.content=this.make(\"div\",this.CSS.tooltipContent),this.append(this.nodes.wrapper,this.nodes.content),this.append(document.body,this.nodes.wrapper)}loadStyles(){const t=\"codex-tooltips-style\";if(document.getElementById(t))return;const e=o(2),i=this.make(\"style\",null,{textContent:e.toString(),id:t});this.prepend(document.head,i)}placeBottom(t,e){const o=t.getBoundingClientRect(),i=o.left+t.clientWidth/2-this.nodes.wrapper.offsetWidth/2,n=o.bottom+window.pageYOffset+this.offsetTop+e.marginTop;this.applyPlacement(\"bottom\",i,n)}placeTop(t,e){const o=t.getBoundingClientRect(),i=o.left+t.clientWidth/2-this.nodes.wrapper.offsetWidth/2,n=o.top+window.pageYOffset-this.nodes.wrapper.clientHeight-this.offsetTop;this.applyPlacement(\"top\",i,n)}placeLeft(t,e){const o=t.getBoundingClientRect(),i=o.left-this.nodes.wrapper.offsetWidth-this.offsetLeft-e.marginLeft,n=o.top+window.pageYOffset+t.clientHeight/2-this.nodes.wrapper.offsetHeight/2;this.applyPlacement(\"left\",i,n)}placeRight(t,e){const o=t.getBoundingClientRect(),i=o.right+this.offsetRight+e.marginRight,n=o.top+window.pageYOffset+t.clientHeight/2-this.nodes.wrapper.offsetHeight/2;this.applyPlacement(\"right\",i,n)}applyPlacement(t,e,o){this.nodes.wrapper.classList.add(this.CSS.placement[t]),this.nodes.wrapper.style.left=e+\"px\",this.nodes.wrapper.style.top=o+\"px\"}make(t,e=null,o={}){const i=document.createElement(t);Array.isArray(e)?i.classList.add(...e):e&&i.classList.add(e);for(const t in o)o.hasOwnProperty(t)&&(i[t]=o[t]);return i}append(t,e){Array.isArray(e)?e.forEach(e=>t.appendChild(e)):t.appendChild(e)}prepend(t,e){Array.isArray(e)?(e=e.reverse()).forEach(e=>t.prepend(e)):t.prepend(e)}}},function(t,e){t.exports='.ct{z-index:999;opacity:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;-webkit-transition:opacity 50ms ease-in,-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,transform 70ms cubic-bezier(.215,.61,.355,1),-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);will-change:opacity,top,left;-webkit-box-shadow:0 8px 12px 0 rgba(29,32,43,.17),0 4px 5px -3px rgba(5,6,12,.49);box-shadow:0 8px 12px 0 rgba(29,32,43,.17),0 4px 5px -3px rgba(5,6,12,.49);border-radius:9px}.ct,.ct:before{position:absolute;top:0;left:0}.ct:before{content:\"\";bottom:0;right:0;background-color:#1d202b;z-index:-1;border-radius:4px}@supports(-webkit-mask-box-image:url(\"\")){.ct:before{border-radius:0;-webkit-mask-box-image:url(\\'data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\"><path d=\"M10.71 0h2.58c3.02 0 4.64.42 6.1 1.2a8.18 8.18 0 013.4 3.4C23.6 6.07 24 7.7 24 10.71v2.58c0 3.02-.42 4.64-1.2 6.1a8.18 8.18 0 01-3.4 3.4c-1.47.8-3.1 1.21-6.11 1.21H10.7c-3.02 0-4.64-.42-6.1-1.2a8.18 8.18 0 01-3.4-3.4C.4 17.93 0 16.3 0 13.29V10.7c0-3.02.42-4.64 1.2-6.1a8.18 8.18 0 013.4-3.4C6.07.4 7.7 0 10.71 0z\"/></svg>\\') 48% 41% 37.9% 53.3%}}@media (--mobile){.ct{display:none}}.ct__content{padding:6px 10px;color:#cdd1e0;font-size:12px;text-align:center;letter-spacing:.02em;line-height:1em}.ct:after{content:\"\";width:8px;height:8px;position:absolute;background-color:#1d202b;z-index:-1}.ct--bottom{-webkit-transform:translateY(5px);transform:translateY(5px)}.ct--bottom:after{top:-3px;left:50%;-webkit-transform:translateX(-50%) rotate(-45deg);transform:translateX(-50%) rotate(-45deg)}.ct--top{-webkit-transform:translateY(-5px);transform:translateY(-5px)}.ct--top:after{top:auto;bottom:-3px;left:50%;-webkit-transform:translateX(-50%) rotate(-45deg);transform:translateX(-50%) rotate(-45deg)}.ct--left{-webkit-transform:translateX(-5px);transform:translateX(-5px)}.ct--left:after{top:50%;left:auto;right:0;-webkit-transform:translate(41.6%,-50%) rotate(-45deg);transform:translate(41.6%,-50%) rotate(-45deg)}.ct--right{-webkit-transform:translateX(5px);transform:translateX(5px)}.ct--right:after{top:50%;left:0;-webkit-transform:translate(-41.6%,-50%) rotate(-45deg);transform:translate(-41.6%,-50%) rotate(-45deg)}.ct--shown{opacity:1;-webkit-transform:none;transform:none}'}]).default}));","/* eslint-disable jsdoc/no-undefined-types */\r\n/**\r\n * Use external module CodeX Tooltip\r\n */\r\nimport CodeXTooltips from 'codex-tooltip';\r\nimport type { TooltipOptions, TooltipContent } from 'codex-tooltip/types';\r\n\r\n/**\r\n * Tooltips lib: CodeX Tooltips\r\n *\r\n * @see https://github.com/codex-team/codex.tooltips\r\n */\r\nlet lib: null | CodeXTooltips = null;\r\n\r\n/**\r\n * If library is needed, but it is not initialized yet, this function will initialize it\r\n *\r\n * For example, if editor was destroyed and then initialized again\r\n */\r\nfunction prepare(): void {\r\n if (lib) {\r\n return;\r\n }\r\n\r\n lib = new CodeXTooltips();\r\n}\r\n\r\n/**\r\n * Shows tooltip on element with passed HTML content\r\n *\r\n * @param {HTMLElement} element - any HTML element in DOM\r\n * @param content - tooltip's content\r\n * @param options - showing settings\r\n */\r\nexport function show(element: HTMLElement, content: TooltipContent, options?: TooltipOptions): void {\r\n prepare();\r\n\r\n lib?.show(element, content, options);\r\n}\r\n\r\n/**\r\n * Hides tooltip\r\n *\r\n * @param skipHidingDelay — pass true to immediately hide the tooltip\r\n */\r\nexport function hide(skipHidingDelay = false): void {\r\n prepare();\r\n\r\n lib?.hide(skipHidingDelay);\r\n}\r\n\r\n/**\r\n * Binds 'mouseenter' and 'mouseleave' events that shows/hides the Tooltip\r\n *\r\n * @param {HTMLElement} element - any HTML element in DOM\r\n * @param content - tooltip's content\r\n * @param options - showing settings\r\n */\r\nexport function onHover(element: HTMLElement, content: TooltipContent, options?: TooltipOptions): void {\r\n prepare();\r\n\r\n lib?.onHover(element, content, options);\r\n}\r\n\r\n/**\r\n * Release the library\r\n */\r\nexport function destroy(): void {\r\n lib?.destroy();\r\n lib = null;\r\n}\r\n","import type { Tooltip as ITooltip } from '../../../../types/api';\r\nimport type { TooltipOptions, TooltipContent } from 'codex-tooltip/types';\r\nimport Module from '../../__module';\r\nimport type { ModuleConfig } from '../../../types-internal/module-config';\r\nimport * as tooltip from '../../utils/tooltip';\r\n/**\r\n * @class TooltipAPI\r\n * @classdesc Tooltip API\r\n */\r\nexport default class TooltipAPI extends Module {\r\n /**\r\n * @class\r\n * @param moduleConfiguration - Module Configuration\r\n * @param moduleConfiguration.config - Editor's config\r\n * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher\r\n */\r\n constructor({ config, eventsDispatcher }: ModuleConfig) {\r\n super({\r\n config,\r\n eventsDispatcher,\r\n });\r\n }\r\n\r\n /**\r\n * Available methods\r\n */\r\n public get methods(): ITooltip {\r\n return {\r\n show: (element: HTMLElement,\r\n content: TooltipContent,\r\n options?: TooltipOptions\r\n ): void => this.show(element, content, options),\r\n hide: (): void => this.hide(),\r\n onHover: (element: HTMLElement,\r\n content: TooltipContent,\r\n options?: TooltipOptions\r\n ): void => this.onHover(element, content, options),\r\n };\r\n }\r\n\r\n /**\r\n * Method show tooltip on element with passed HTML content\r\n *\r\n * @param {HTMLElement} element - element on which tooltip should be shown\r\n * @param {TooltipContent} content - tooltip content\r\n * @param {TooltipOptions} options - tooltip options\r\n */\r\n public show(element: HTMLElement, content: TooltipContent, options?: TooltipOptions): void {\r\n tooltip.show(element, content, options);\r\n }\r\n\r\n /**\r\n * Method hides tooltip on HTML page\r\n */\r\n public hide(): void {\r\n tooltip.hide();\r\n }\r\n\r\n /**\r\n * Decorator for showing Tooltip by mouseenter/mouseleave\r\n *\r\n * @param {HTMLElement} element - element on which tooltip should be shown\r\n * @param {TooltipContent} content - tooltip content\r\n * @param {TooltipOptions} options - tooltip options\r\n */\r\n public onHover(element: HTMLElement, content: TooltipContent, options?: TooltipOptions): void {\r\n tooltip.onHover(element, content, options);\r\n }\r\n}\r\n","import Module from '../../__module';\r\nimport type { Ui, UiNodes } from '../../../../types/api';\r\n\r\n/**\r\n * API module allowing to access some Editor UI elements\r\n */\r\nexport default class UiAPI extends Module {\r\n /**\r\n * Available methods / getters\r\n */\r\n public get methods(): Ui {\r\n return {\r\n nodes: this.editorNodes,\r\n /**\r\n * There can be added some UI methods, like toggleThinMode() etc\r\n */\r\n };\r\n }\r\n\r\n /**\r\n * Exported classes\r\n */\r\n private get editorNodes(): UiNodes {\r\n return {\r\n /**\r\n * Top-level editor instance wrapper\r\n */\r\n wrapper: this.Editor.UI.nodes.wrapper,\r\n\r\n /**\r\n * Element that holds all the Blocks\r\n */\r\n redactor: this.Editor.UI.nodes.redactor,\r\n };\r\n }\r\n}\r\n","import defaultDictionary from './locales/en/messages.json';\r\nimport type { DictNamespaces } from '../../types-internal/i18n-internal-namespace';\r\nimport { isObject, isString } from '../utils';\r\n\r\n/**\r\n * Evaluate messages dictionary and return object for namespace chaining\r\n *\r\n * @param dict - Messages dictionary\r\n * @param [keyPath] - subsection path (used in recursive call)\r\n */\r\nfunction getNamespaces(dict: object, keyPath?: string): DictNamespaces<typeof defaultDictionary> {\r\n const result = {};\r\n\r\n Object.entries(dict).forEach(([key, section]) => {\r\n if (isObject(section)) {\r\n const newPath = keyPath ? `${keyPath}.${key}` : key;\r\n\r\n /**\r\n * Check current section values, if all of them are strings, so there is the last section\r\n */\r\n const isLastSection = Object.values(section).every((sectionValue) => {\r\n return isString(sectionValue);\r\n });\r\n\r\n /**\r\n * In last section, we substitute namespace path instead of object with translates\r\n *\r\n * ui.toolbar.toolbox – \"ui.toolbar.toolbox\"\r\n * instead of\r\n * ui.toolbar.toolbox – {\"Add\": \"\"}\r\n */\r\n if (isLastSection) {\r\n result[key] = newPath;\r\n } else {\r\n result[key] = getNamespaces(section, newPath);\r\n }\r\n\r\n return;\r\n }\r\n\r\n result[key] = section;\r\n });\r\n\r\n return result as DictNamespaces<typeof defaultDictionary>;\r\n}\r\n\r\n/**\r\n * Type safe access to the internal messages dictionary sections\r\n *\r\n * @example I18n.ui(I18nInternalNS.ui.blockTunes.toggler, 'Click to tune');\r\n */\r\nexport const I18nInternalNS = getNamespaces(defaultDictionary);\r\n","/**\r\n * Resolves aliases in specified object according to passed aliases info\r\n *\r\n * @example resolveAliases(obj, { label: 'title' })\r\n * here 'label' is alias for 'title'\r\n * @param obj - object with aliases to be resolved\r\n * @param aliases - object with aliases info where key is an alias property name and value is an aliased property name\r\n */\r\nexport function resolveAliases<ObjectType>(obj: ObjectType, aliases: { [alias: string]: string }): ObjectType {\r\n const result = {} as ObjectType;\r\n\r\n Object.keys(obj).forEach(property => {\r\n const aliasedProperty = aliases[property];\r\n\r\n if (aliasedProperty !== undefined) {\r\n result[aliasedProperty] = obj[property];\r\n } else {\r\n result[property] = obj[property];\r\n }\r\n });\r\n\r\n return result;\r\n}\r\n","import Dom from './dom';\r\nimport * as _ from './utils';\r\nimport SelectionUtils from './selection';\r\n\r\n/**\r\n * Iterator above passed Elements list.\r\n * Each next or previous action adds provides CSS-class and sets cursor to this item\r\n */\r\nexport default class DomIterator {\r\n /**\r\n * This is a static property that defines iteration directions\r\n *\r\n * @type {{RIGHT: string, LEFT: string}}\r\n */\r\n public static directions = {\r\n RIGHT: 'right',\r\n LEFT: 'left',\r\n };\r\n\r\n /**\r\n * User-provided CSS-class name for focused button\r\n */\r\n private focusedCssClass: string;\r\n\r\n /**\r\n * Focused button index.\r\n * Default is -1 which means nothing is active\r\n *\r\n * @type {number}\r\n */\r\n private cursor = -1;\r\n\r\n /**\r\n * Items to flip\r\n */\r\n private items: HTMLElement[] = [];\r\n\r\n /**\r\n * @param {HTMLElement[]} nodeList — the list of iterable HTML-items\r\n * @param {string} focusedCssClass - user-provided CSS-class that will be set in flipping process\r\n */\r\n constructor(\r\n nodeList: HTMLElement[],\r\n focusedCssClass: string\r\n ) {\r\n this.items = nodeList || [];\r\n this.focusedCssClass = focusedCssClass;\r\n }\r\n\r\n /**\r\n * Returns Focused button Node\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n public get currentItem(): HTMLElement {\r\n if (this.cursor === -1) {\r\n return null;\r\n }\r\n\r\n return this.items[this.cursor];\r\n }\r\n\r\n /**\r\n * Sets cursor to specified position\r\n *\r\n * @param cursorPosition - new cursor position\r\n */\r\n public setCursor(cursorPosition: number): void {\r\n if (cursorPosition < this.items.length && cursorPosition >= -1) {\r\n this.dropCursor();\r\n this.cursor = cursorPosition;\r\n this.items[this.cursor].classList.add(this.focusedCssClass);\r\n }\r\n }\r\n\r\n /**\r\n * Sets items. Can be used when iterable items changed dynamically\r\n *\r\n * @param {HTMLElement[]} nodeList - nodes to iterate\r\n */\r\n public setItems(nodeList: HTMLElement[]): void {\r\n this.items = nodeList;\r\n }\r\n\r\n /**\r\n * Sets cursor next to the current\r\n */\r\n public next(): void {\r\n this.cursor = this.leafNodesAndReturnIndex(DomIterator.directions.RIGHT);\r\n }\r\n\r\n /**\r\n * Sets cursor before current\r\n */\r\n public previous(): void {\r\n this.cursor = this.leafNodesAndReturnIndex(DomIterator.directions.LEFT);\r\n }\r\n\r\n /**\r\n * Sets cursor to the default position and removes CSS-class from previously focused item\r\n */\r\n public dropCursor(): void {\r\n if (this.cursor === -1) {\r\n return;\r\n }\r\n\r\n this.items[this.cursor].classList.remove(this.focusedCssClass);\r\n this.cursor = -1;\r\n }\r\n\r\n /**\r\n * Leafs nodes inside the target list from active element\r\n *\r\n * @param {string} direction - leaf direction. Can be 'left' or 'right'\r\n * @returns {number} index of focused node\r\n */\r\n private leafNodesAndReturnIndex(direction: string): number {\r\n /**\r\n * if items are empty then there is nothing to leaf\r\n */\r\n if (this.items.length === 0) {\r\n return this.cursor;\r\n }\r\n\r\n let focusedButtonIndex = this.cursor;\r\n\r\n /**\r\n * If activeButtonIndex === -1 then we have no chosen Tool in Toolbox\r\n */\r\n if (focusedButtonIndex === -1) {\r\n /**\r\n * Normalize \"previous\" Tool index depending on direction.\r\n * We need to do this to highlight \"first\" Tool correctly\r\n *\r\n * Order of Tools: [0] [1] ... [n - 1]\r\n * [0 = n] because of: n % n = 0 % n\r\n *\r\n * Direction 'right': for [0] the [n - 1] is a previous index\r\n * [n - 1] -> [0]\r\n *\r\n * Direction 'left': for [n - 1] the [0] is a previous index\r\n * [n - 1] <- [0]\r\n *\r\n * @type {number}\r\n */\r\n focusedButtonIndex = direction === DomIterator.directions.RIGHT ? -1 : 0;\r\n } else {\r\n /**\r\n * If we have chosen Tool then remove highlighting\r\n */\r\n this.items[focusedButtonIndex].classList.remove(this.focusedCssClass);\r\n }\r\n\r\n /**\r\n * Count index for next Tool\r\n */\r\n if (direction === DomIterator.directions.RIGHT) {\r\n /**\r\n * If we go right then choose next (+1) Tool\r\n *\r\n * @type {number}\r\n */\r\n focusedButtonIndex = (focusedButtonIndex + 1) % this.items.length;\r\n } else {\r\n /**\r\n * If we go left then choose previous (-1) Tool\r\n * Before counting module we need to add length before because of \"The JavaScript Modulo Bug\"\r\n *\r\n * @type {number}\r\n */\r\n focusedButtonIndex = (this.items.length + focusedButtonIndex - 1) % this.items.length;\r\n }\r\n\r\n if (Dom.canSetCaret(this.items[focusedButtonIndex])) {\r\n /**\r\n * Focus input with micro-delay to ensure DOM is updated\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n _.delay(() => SelectionUtils.setCursor(this.items[focusedButtonIndex]), 50)();\r\n }\r\n\r\n /**\r\n * Highlight new chosen Tool\r\n */\r\n this.items[focusedButtonIndex].classList.add(this.focusedCssClass);\r\n\r\n /**\r\n * Return focused button's index\r\n */\r\n return focusedButtonIndex;\r\n }\r\n}\r\n","import DomIterator from './domIterator';\r\nimport * as _ from './utils';\r\n\r\n/**\r\n * Flipper construction options\r\n *\r\n * @interface FlipperOptions\r\n */\r\nexport interface FlipperOptions {\r\n /**\r\n * CSS-modifier for focused item\r\n */\r\n focusedItemClass?: string;\r\n\r\n /**\r\n * If flipping items are the same for all Block (for ex. Toolbox), ypu can pass it on constructing\r\n */\r\n items?: HTMLElement[];\r\n\r\n /**\r\n * Optional callback for button click\r\n */\r\n activateCallback?: (item: HTMLElement) => void;\r\n\r\n /**\r\n * List of keys allowed for handling.\r\n * Can include codes of the following keys:\r\n * - Tab\r\n * - Enter\r\n * - Arrow up\r\n * - Arrow down\r\n * - Arrow right\r\n * - Arrow left\r\n * If not specified all keys are enabled\r\n */\r\n allowedKeys?: number[];\r\n}\r\n\r\n/**\r\n * Flipper is a component that iterates passed items array by TAB or Arrows and clicks it by ENTER\r\n */\r\nexport default class Flipper {\r\n /**\r\n * True if flipper is currently activated\r\n */\r\n public get isActivated(): boolean {\r\n return this.activated;\r\n }\r\n\r\n /**\r\n * Instance of flipper iterator\r\n */\r\n private readonly iterator: DomIterator | null = null;\r\n\r\n /**\r\n * Flag that defines activation status\r\n */\r\n private activated = false;\r\n\r\n /**\r\n * List codes of the keys allowed for handling\r\n */\r\n private readonly allowedKeys: number[];\r\n\r\n /**\r\n * Call back for button click/enter\r\n */\r\n private readonly activateCallback: (item: HTMLElement) => void;\r\n\r\n /**\r\n * Contains list of callbacks to be executed on each flip\r\n */\r\n private flipCallbacks: Array<() => void> = [];\r\n\r\n /**\r\n * @param options - different constructing settings\r\n */\r\n constructor(options: FlipperOptions) {\r\n this.iterator = new DomIterator(options.items, options.focusedItemClass);\r\n this.activateCallback = options.activateCallback;\r\n this.allowedKeys = options.allowedKeys || Flipper.usedKeys;\r\n }\r\n\r\n /**\r\n * Array of keys (codes) that is handled by Flipper\r\n * Used to:\r\n * - preventDefault only for this keys, not all keydowns (@see constructor)\r\n * - to skip external behaviours only for these keys, when filler is activated (@see BlockEvents@arrowRightAndDown)\r\n */\r\n public static get usedKeys(): number[] {\r\n return [\r\n _.keyCodes.TAB,\r\n _.keyCodes.LEFT,\r\n _.keyCodes.RIGHT,\r\n _.keyCodes.ENTER,\r\n _.keyCodes.UP,\r\n _.keyCodes.DOWN,\r\n ];\r\n }\r\n\r\n /**\r\n * Active tab/arrows handling by flipper\r\n *\r\n * @param items - Some modules (like, InlineToolbar, BlockSettings) might refresh buttons dynamically\r\n * @param cursorPosition - index of the item that should be focused once flipper is activated\r\n */\r\n public activate(items?: HTMLElement[], cursorPosition?: number): void {\r\n this.activated = true;\r\n if (items) {\r\n this.iterator.setItems(items);\r\n }\r\n\r\n if (cursorPosition !== undefined) {\r\n this.iterator.setCursor(cursorPosition);\r\n }\r\n\r\n /**\r\n * Listening all keydowns on document and react on TAB/Enter press\r\n * TAB will leaf iterator items\r\n * ENTER will click the focused item\r\n *\r\n * Note: the event should be handled in capturing mode on following reasons:\r\n * - prevents plugins inner keydown handlers from being called while keyboard navigation\r\n * - otherwise this handler will be called at the moment it is attached which causes false flipper firing (see https://techread.me/js-addeventlistener-fires-for-past-events/)\r\n */\r\n document.addEventListener('keydown', this.onKeyDown, true);\r\n }\r\n\r\n /**\r\n * Disable tab/arrows handling by flipper\r\n */\r\n public deactivate(): void {\r\n this.activated = false;\r\n this.dropCursor();\r\n\r\n document.removeEventListener('keydown', this.onKeyDown);\r\n }\r\n\r\n /**\r\n * Focus first item\r\n */\r\n public focusFirst(): void {\r\n this.dropCursor();\r\n this.flipRight();\r\n }\r\n\r\n /**\r\n * Focuses previous flipper iterator item\r\n */\r\n public flipLeft(): void {\r\n this.iterator.previous();\r\n this.flipCallback();\r\n }\r\n\r\n /**\r\n * Focuses next flipper iterator item\r\n */\r\n public flipRight(): void {\r\n this.iterator.next();\r\n this.flipCallback();\r\n }\r\n\r\n /**\r\n * Return true if some button is focused\r\n */\r\n public hasFocus(): boolean {\r\n return !!this.iterator.currentItem;\r\n }\r\n\r\n /**\r\n * Registeres function that should be executed on each navigation action\r\n *\r\n * @param cb - function to execute\r\n */\r\n public onFlip(cb: () => void): void {\r\n this.flipCallbacks.push(cb);\r\n }\r\n\r\n /**\r\n * Unregisteres function that is executed on each navigation action\r\n *\r\n * @param cb - function to stop executing\r\n */\r\n public removeOnFlip(cb: () => void): void {\r\n this.flipCallbacks = this.flipCallbacks.filter(fn => fn !== cb);\r\n }\r\n\r\n /**\r\n * Drops flipper's iterator cursor\r\n *\r\n * @see DomIterator#dropCursor\r\n */\r\n private dropCursor(): void {\r\n this.iterator.dropCursor();\r\n }\r\n\r\n /**\r\n * KeyDown event handler\r\n *\r\n * @param event - keydown event\r\n */\r\n private onKeyDown = (event: KeyboardEvent): void => {\r\n const isReady = this.isEventReadyForHandling(event);\r\n\r\n if (!isReady) {\r\n return;\r\n }\r\n\r\n const isShiftKey = event.shiftKey;\r\n\r\n /**\r\n * If shift key is pressed, do nothing\r\n * Allows to select next/prev lines of text using keyboard\r\n */\r\n if (isShiftKey === true) {\r\n return;\r\n }\r\n\r\n /**\r\n * Prevent only used keys default behaviour\r\n * (allows to navigate by ARROW DOWN, for example)\r\n */\r\n if (Flipper.usedKeys.includes(event.keyCode)) {\r\n event.preventDefault();\r\n }\r\n\r\n switch (event.keyCode) {\r\n case _.keyCodes.TAB:\r\n this.handleTabPress(event);\r\n break;\r\n case _.keyCodes.LEFT:\r\n case _.keyCodes.UP:\r\n this.flipLeft();\r\n break;\r\n case _.keyCodes.RIGHT:\r\n case _.keyCodes.DOWN:\r\n this.flipRight();\r\n break;\r\n case _.keyCodes.ENTER:\r\n this.handleEnterPress(event);\r\n break;\r\n }\r\n };\r\n\r\n /**\r\n * This function is fired before handling flipper keycodes\r\n * The result of this function defines if it is need to be handled or not\r\n *\r\n * @param {KeyboardEvent} event - keydown keyboard event\r\n * @returns {boolean}\r\n */\r\n private isEventReadyForHandling(event: KeyboardEvent): boolean {\r\n return this.activated && this.allowedKeys.includes(event.keyCode);\r\n }\r\n\r\n /**\r\n * When flipper is activated tab press will leaf the items\r\n *\r\n * @param {KeyboardEvent} event - tab keydown event\r\n */\r\n private handleTabPress(event: KeyboardEvent): void {\r\n /** this property defines leaf direction */\r\n const shiftKey = event.shiftKey,\r\n direction = shiftKey ? DomIterator.directions.LEFT : DomIterator.directions.RIGHT;\r\n\r\n switch (direction) {\r\n case DomIterator.directions.RIGHT:\r\n this.flipRight();\r\n break;\r\n case DomIterator.directions.LEFT:\r\n this.flipLeft();\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Enter press will click current item if flipper is activated\r\n *\r\n * @param {KeyboardEvent} event - enter keydown event\r\n */\r\n private handleEnterPress(event: KeyboardEvent): void {\r\n if (!this.activated) {\r\n return;\r\n }\r\n\r\n if (this.iterator.currentItem) {\r\n /**\r\n * Stop Enter propagation only if flipper is ready to select focused item\r\n */\r\n event.stopPropagation();\r\n event.preventDefault();\r\n this.iterator.currentItem.click();\r\n }\r\n\r\n if (_.isFunction(this.activateCallback)) {\r\n this.activateCallback(this.iterator.currentItem);\r\n }\r\n }\r\n\r\n /**\r\n * Fired after flipping in any direction\r\n */\r\n private flipCallback(): void {\r\n if (this.iterator.currentItem) {\r\n this.iterator.currentItem.scrollIntoViewIfNeeded();\r\n }\r\n\r\n this.flipCallbacks.forEach(cb => cb());\r\n }\r\n}\r\n","const o = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 17V10.2135C19 10.1287 18.9011 10.0824 18.836 10.1367L16 12.5\"/></svg>', t = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 11C16 10 19 9.5 19 12C19 13.9771 16.0684 13.9997 16.0012 16.8981C15.9999 16.9533 16.0448 17 16.1 17L19.3 17\"/></svg>', r = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 11C16 10.5 16.8323 10 17.6 10C18.3677 10 19.5 10.311 19.5 11.5C19.5 12.5315 18.7474 12.9022 18.548 12.9823C18.5378 12.9864 18.5395 13.0047 18.5503 13.0063C18.8115 13.0456 20 13.3065 20 14.8C20 16 19.5 17 17.8 17C17.8 17 16 17 16 16.3\"/></svg>', e = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 10L15.2834 14.8511C15.246 14.9178 15.294 15 15.3704 15C16.8489 15 18.7561 15 20.2 15M19 17C19 15.7187 19 14.8813 19 13.6\"/></svg>', n = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 15.9C16 15.9 16.3768 17 17.8 17C19.5 17 20 15.6199 20 14.7C20 12.7323 17.6745 12.0486 16.1635 12.9894C16.094 13.0327 16 12.9846 16 12.9027V10.1C16 10.0448 16.0448 10 16.1 10H19.8\"/></svg>', s = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7L6 12M6 17L6 12M6 12L12 12M12 7V12M12 17L12 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19.5 10C16.5 10.5 16 13.3285 16 15M16 15V15C16 16.1046 16.8954 17 18 17H18.3246C19.3251 17 20.3191 16.3492 20.2522 15.3509C20.0612 12.4958 16 12.6611 16 15Z\"/></svg>', i = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 19V19C9.13623 19 8.20435 19 7.46927 18.6955C6.48915 18.2895 5.71046 17.5108 5.30448 16.5307C5 15.7956 5 14.8638 5 13V12C5 9.19108 5 7.78661 5.67412 6.77772C5.96596 6.34096 6.34096 5.96596 6.77772 5.67412C7.78661 5 9.19108 5 12 5H13.5C14.8956 5 15.5933 5 16.1611 5.17224C17.4395 5.56004 18.44 6.56046 18.8278 7.83886C19 8.40666 19 9.10444 19 10.5V10.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 13V16M16 19V16M19 16H16M16 16H13\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6.5 17.5L17.5 6.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.9919 10.5H19.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.9919 19H11.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13L13 5\"/></svg>', h = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.9919 9.5H19.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.5 5H14.5096\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.625 5H15C17.2091 5 19 6.79086 19 9V9.375\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M9.375 5L9 5C6.79086 5 5 6.79086 5 9V9.375\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.3725 5H9.38207\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 9.5H5.00957\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M9.375 19H9C6.79086 19 5 17.2091 5 15V14.625\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.3725 19H9.38207\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 14.55H5.00957\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 13V16M16 19V16M19 16H16M16 16H13\"/></svg>', l = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 7L6 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 17H6\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16 12L8 12\"/></svg>', w = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 7L6 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 17H6\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M18 12L6 12\"/></svg>', d = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17 7L5 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17 17H5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M13 12L5 12\"/></svg>', k = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 7L7 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 17H7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19 12L11 12\"/></svg>', c = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9 12L9 7.1C9 7.04477 9.04477 7 9.1 7H10.4C11.5 7 14 7.1 14 9.5C14 9.5 14 12 11 12M9 12V16.8C9 16.9105 9.08954 17 9.2 17H12.5C14 17 15 16 15 14.5C15 11.7046 11 12 11 12M9 12H11\"/></svg>', C = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 8L5 12L9 16\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 8L19 12L15 16\"/></svg>', g = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 12L10.4884 15.8372C10.5677 15.9245 10.705 15.9245 10.7844 15.8372L17 9\"/></svg>', u = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9.2 12L11.0586 13.8586C11.1367 13.9367 11.2633 13.9367 11.3414 13.8586L14.7 10.5\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>', p = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 10L11.8586 14.8586C11.9367 14.9367 12.0633 14.9367 12.1414 14.8586L17 10\"/></svg>', a = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.5 17.5L9.64142 12.6414C9.56331 12.5633 9.56331 12.4367 9.64142 12.3586L14.5 7.5\"/></svg>', v = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9.58284 17.5L14.4414 12.6414C14.5195 12.5633 14.5195 12.4367 14.4414 12.3586L9.58284 7.5\"/></svg>', M = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 15L11.8586 10.1414C11.9367 10.0633 12.0633 10.0633 12.1414 10.1414L17 15\"/></svg>', x = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.42857 7H7.71429C7.25963 7 6.82359 7.15804 6.5021 7.43934C6.18061 7.72064 6 8.10218 6 8.5V17.5C6 17.8978 6.18061 18.2794 6.5021 18.5607C6.82359 18.842 7.25963 19 7.71429 19H16.2857C16.7404 19 17.1764 18.842 17.4979 18.5607C17.8194 18.2794 18 17.8978 18 17.5V8.5C18 8.10218 17.8194 7.72064 17.4979 7.43934C17.1764 7.15804 16.7404 7 16.2857 7H14.5714\"/><rect width=\"5.15789\" height=\"3.36842\" x=\"9.42105\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"1.5\"/></svg>', L = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 9L10 12M10 12L7 15M10 12H4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17 9L14 12M14 12L17 15M14 12H20\"/></svg>', H = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5.24296 11.4075C5.23167 10.6253 5.52446 9.8395 6.12132 9.24264L9.65686 5.70711C10.0474 5.31658 10.6809 5.31693 11.0714 5.70745L16.0205 10.6565C16.2268 10.8629 16.3243 11.1371 16.3126 11.4075M5.24296 11.4075C5.25382 12.1607 5.54661 12.9106 6.12132 13.4853L8 15.364M5.24296 11.4075H11.9565M16.3126 11.4075C16.3022 11.6487 16.205 11.8869 16.0208 12.0711L12.4853 15.6066C11.3137 16.7782 9.41421 16.7782 8.24264 15.6066L8 15.364M16.3126 11.4075H11.9565M8 15.364L11.9565 11.4075\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M20 17.4615C20 18.3112 19.3284 19 18.5 19C17.6716 19 17 18.3112 17 17.4615C17 16.6119 17.9 15.6154 18.5 15C19.1 15.6154 20 16.6119 20 17.4615Z\"/></svg>', m = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17.25 8.5H10.25C9.2835 8.5 8.5 9.2835 8.5 10.25V17.25C8.5 18.2165 9.2835 19 10.25 19H17.25C18.2165 19 19 18.2165 19 17.25V10.25C19 9.2835 18.2165 8.5 17.25 8.5Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15.5 8.5V6.75C15.5 6.28587 15.3156 5.84075 14.9874 5.51256C14.6592 5.18437 14.2141 5 13.75 5H6.75C6.28587 5 5.84075 5.18437 5.51256 5.51256C5.18437 5.84075 5 6.28587 5 6.75V13.75C5 14.2141 5.18437 14.6592 5.51256 14.9874C5.84075 15.3156 6.28587 15.5 6.75 15.5H8.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 12L15.5 12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 15.5L15.5 15.5\"/></svg>', f = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8 8L12 12M12 12L16 16M12 12L16 8M12 12L8 16\"/></svg>', B = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 17C7 17 7 15.2536 7 13.5L5.5 12L7 10.5C7 8.74644 7 7 9 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 17C17 17 17 15.2536 17 13.5L18.5 12L17 10.5C17 8.74644 17 7 15 7\"/></svg>', I = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><line x1=\"6\" x2=\"10\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"14\" x2=\"18\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>', V = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.8833 9.16666L18.2167 12.5M18.2167 12.5L14.8833 15.8333M18.2167 12.5H10.05C9.16594 12.5 8.31809 12.1488 7.69297 11.5237C7.06785 10.8986 6.71666 10.0507 6.71666 9.16666\"/></svg>', j = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.9167 14.9167L11.5833 18.25M11.5833 18.25L8.25 14.9167M11.5833 18.25L11.5833 10.0833C11.5833 9.19928 11.9345 8.35143 12.5596 7.72631C13.1848 7.10119 14.0326 6.75 14.9167 6.75\"/></svg>', y = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.13333 14.9167L12.4667 18.25M12.4667 18.25L15.8 14.9167M12.4667 18.25L12.4667 10.0833C12.4667 9.19928 12.1155 8.35143 11.4904 7.72631C10.8652 7.10119 10.0174 6.75 9.13333 6.75\"/></svg>', Z = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.8833 15.8333L18.2167 12.5M18.2167 12.5L14.8833 9.16667M18.2167 12.5L10.05 12.5C9.16595 12.5 8.31811 12.8512 7.69299 13.4763C7.06787 14.1014 6.71667 14.9493 6.71667 15.8333\"/></svg>', D = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"4\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>', T = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M7.30499 11.995L7.30499 12.005M12.005 11.995V12.005M16.705 11.995L16.705 12.005\"/></svg>', b = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M12.01 7.29999H12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M12.01 12H12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M12.01 16.7H12\"/></svg>', R = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13.3236 8.43554L9.49533 12.1908C9.13119 12.5505 8.93118 13.043 8.9393 13.5598C8.94741 14.0767 9.163 14.5757 9.53862 14.947C9.91424 15.3182 10.4191 15.5314 10.9422 15.5397C11.4653 15.5479 11.9637 15.3504 12.3279 14.9908L16.1562 11.2355C16.8845 10.5161 17.2845 9.53123 17.2682 8.4975C17.252 7.46376 16.8208 6.46583 16.0696 5.72324C15.3184 4.98066 14.3086 4.55425 13.2624 4.53782C12.2162 4.52138 11.2193 4.91627 10.4911 5.63562L6.66277 9.39093C5.57035 10.4699 4.97032 11.9473 4.99467 13.4979C5.01903 15.0485 5.66578 16.5454 6.79264 17.6592C7.9195 18.7731 9.43417 19.4127 11.0034 19.4374C12.5727 19.462 14.068 18.8697 15.1604 17.7907L18.9887 14.0354\"/></svg>', U = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"12\" height=\"6\" x=\"6\" y=\"13\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"2\"/><line x1=\"12\" x2=\"12\" y1=\"9\" y2=\"19\" stroke=\"currentColor\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 11C5 9.89543 5.89543 9 7 9H17C18.1046 9 19 9.89543 19 11V11C19 12.1046 18.1046 13 17 13H7C5.89543 13 5 12.1046 5 11V11Z\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M16 9C16 7.89543 16 6 14 6C12 6 12 7.89543 12 9C12 7.89543 12 6 10 6C8 6 8 7.89543 8 9\"/></svg>', A = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M18 12C18 15.3137 15.3137 18 12 18C8.68629 18 6 15.3137 6 12M18 12C18 8.68629 15.3137 6 12 6C8.68629 6 6 8.68629 6 12M18 12H6M11.7 6C11.7 6 9.7 7.63811 9.7 12C9.7 16.9 11.7 18 11.7 18M12.3 6C12.3 6 14.3 7.63811 14.3 12C14.3 16.9 12.3 18 12.3 18\"/></svg>', S = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9 7L9 12M9 17V12M9 12L15 12M15 7V12M15 17L15 12\"/></svg>', G = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M6.6 7.50001C5.27451 8.82549 5.19999 10.6 6.59999 12.3C8 14 12.2 17.9 12.2 17.9C12.2 17.9 16.5 14 17.8 12.3C19.1 10.6 19.1255 8.82549 17.8 7.5C16.4745 6.17452 14.3255 6.17452 13 7.5L12.2 8.30001L11.4 7.50001C10.0745 6.17453 7.92548 6.17453 6.6 7.50001Z\"/></svg>', P = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6.77778 6L18.5 17.7222\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.687 10C10.2473 10.4392 10.0002 11.035 10 11.6564C9.99978 12.2777 10.2465 12.8737 10.6858 13.3132C11.1251 13.7527 11.7211 13.9998 12.3427 14C12.9642 14.0002 13.5604 13.7536 14 13.3144\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 7C17 11.1666 20 11.17 20 11.67C20 12.17 19 13.17 19 13.17M8.2424 8.80936C7.59317 9.22876 6.97961 9.76732 6.4017 10.4251C5.70398 11.2193 5.35512 11.6164 5.35513 12.3702C5.35514 13.124 5.70406 13.5211 6.40191 14.3154C7.99587 16.1297 9.8618 17.0367 12 17.0367C13.1102 17.0367 14.1466 16.7917 15.1111 16.3024\"/></svg>', W = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16.6954 5C17.912 5 18.8468 6.07716 18.6755 7.28165L17.426 16.0659C17.3183 16.8229 16.7885 17.4522 16.061 17.6873L12.6151 18.8012C12.2152 18.9304 11.7848 18.9304 11.3849 18.8012L7.93898 17.6873C7.21148 17.4522 6.6817 16.8229 6.57403 16.0659L5.32454 7.28165C5.15322 6.07716 6.088 5 7.30461 5H16.6954Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 8.4H9L9.42857 11.7939H14.5714L14.3571 13.2788L14.1429 14.7636L12 15.4L9.85714 14.7636L9.77143 14.3394\"/></svg>', E = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M15.9 8.1V8.11\"/><circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>', N = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M13.34 10C12.4223 12.7337 11 17 11 17\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.21 7H14.2\"/></svg>', Q = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7.69998 12.6L7.67896 12.62C6.53993 13.7048 6.52012 15.5155 7.63516 16.625V16.625C8.72293 17.7073 10.4799 17.7102 11.5712 16.6314L13.0263 15.193C14.0703 14.1609 14.2141 12.525 13.3662 11.3266L13.22 11.12\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M16.22 11.12L16.3564 10.9805C17.2895 10.0265 17.3478 8.5207 16.4914 7.49733V7.49733C15.5691 6.39509 13.9269 6.25143 12.8271 7.17675L11.3901 8.38588C10.0935 9.47674 9.95706 11.4241 11.0888 12.6852L11.12 12.72\"/></svg>', F = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><line x1=\"9\" x2=\"9\" y1=\"11.4\" y2=\"15.4\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M9 8.7V8.71\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 11.4V12M12 15.4V12M12 12C14 11.5 15 11.3611 15 12.5C15 13.5 15 15.4 15 15.4\"/></svg>', J = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><line x1=\"9\" x2=\"19\" y1=\"7\" y2=\"7\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"9\" x2=\"19\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"9\" x2=\"19\" y1=\"17\" y2=\"17\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M5.00001 17H4.99002\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M5.00001 12H4.99002\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M5.00001 7H4.99002\"/></svg>', X = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><line x1=\"12\" x2=\"19\" y1=\"7\" y2=\"7\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"12\" x2=\"19\" y1=\"12\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><line x1=\"12\" x2=\"19\" y1=\"17\" y2=\"17\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7.79999 14L7.79999 7.2135C7.79999 7.12872 7.7011 7.0824 7.63597 7.13668L4.79999 9.5\"/></svg>', q = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 6.99998C9.1747 6.99987 6.99997 9.24998 7 12C7.00003 14.55 9.02119 17 12 17C14.7712 17 17 14.75 17 12\"><animateTransform attributeName=\"transform\" attributeType=\"XML\" dur=\"560ms\" from=\"0,12,12\" repeatCount=\"indefinite\" to=\"360,12,12\" type=\"rotate\"/></path></svg>', z = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M11.3535 9.31802L12.7678 7.90381C13.5488 7.12276 14.8151 7.12276 15.5962 7.90381C16.3772 8.68486 16.3772 9.95119 15.5962 10.7322L14.182 12.1464M11.3535 9.31802L7.96729 12.7043C7.40889 13.2627 7.02826 13.9739 6.87339 14.7482L6.69798 15.6253C6.55803 16.325 7.17495 16.942 7.87467 16.802L8.75175 16.6266C9.52612 16.4717 10.2373 16.0911 10.7957 15.5327L14.182 12.1464M11.3535 9.31802L14.182 12.1464\"/><line x1=\"15\" x2=\"19\" y1=\"17\" y2=\"17\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>', K = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.41 9.66H9.4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 9.66H14.59\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.31 14.36H9.3\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 14.36H14.59\"/></svg>', O = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.40999 7.29999H9.4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 7.29999H14.59\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.30999 12H9.3\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 12H14.59\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M9.40999 16.7H9.4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2.6\" d=\"M14.6 16.7H14.59\"/></svg>', Y = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5.13968 15.32L8.69058 11.5661C9.02934 11.2036 9.48873 11 9.96774 11C10.4467 11 10.9061 11.2036 11.2449 11.5661L15.3871 16M13.5806 14.0664L15.0132 12.533C15.3519 12.1705 15.8113 11.9668 16.2903 11.9668C16.7693 11.9668 17.2287 12.1705 17.5675 12.533L18.841 13.9634\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13.7778 9.33331H13.7867\"/></svg>', _ = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 10.5606V13.4394C10 14.4777 11.1572 15.0971 12.0211 14.5211L14.1803 13.0817C14.9536 12.5661 14.9503 11.4317 14.18 10.9181L12.0214 9.47907C11.1591 8.9042 10 9.5203 10 10.5606Z\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>', $ = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 7V12M12 17V12M17 12H12M12 12H7\"/></svg>', o1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 15.52V15.51\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M10.0024 9.97655C10.1567 9.01858 11 8.5 12 8.5C13 8.5 13.6857 9.17188 13.8693 9.70703C14.0529 10.2422 14.0135 11.0514 13.5067 11.5159C13 11.9805 12.7344 11.832 12.2784 12.3168C12.1134 12.4923 12 12.7476 12 12.7476\"/></svg>', t1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 10.8182L9 10.8182C8.80222 10.8182 8.60888 10.7649 8.44443 10.665C8.27998 10.5651 8.15181 10.4231 8.07612 10.257C8.00043 10.0909 7.98063 9.90808 8.01922 9.73174C8.0578 9.55539 8.15304 9.39341 8.29289 9.26627C8.43275 9.13913 8.61093 9.05255 8.80491 9.01747C8.99889 8.98239 9.19996 9.00039 9.38268 9.0692C9.56541 9.13801 9.72159 9.25453 9.83147 9.40403C9.94135 9.55353 10 9.72929 10 9.90909L10 12.1818C10 12.664 9.78929 13.1265 9.41421 13.4675C9.03914 13.8084 8.53043 14 8 14\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 10.8182L15 10.8182C14.8022 10.8182 14.6089 10.7649 14.4444 10.665C14.28 10.5651 14.1518 10.4231 14.0761 10.257C14.0004 10.0909 13.9806 9.90808 14.0192 9.73174C14.0578 9.55539 14.153 9.39341 14.2929 9.26627C14.4327 9.13913 14.6109 9.05255 14.8049 9.01747C14.9989 8.98239 15.2 9.00039 15.3827 9.0692C15.5654 9.13801 15.7216 9.25453 15.8315 9.40403C15.9414 9.55353 16 9.72929 16 9.90909L16 12.1818C16 12.664 15.7893 13.1265 15.4142 13.4675C15.0391 13.8084 14.5304 14 14 14\"/></svg>', r1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.6667 13.6667L18 10.3333L14.6667 7M18 10.3333H8.83333C7.94928 10.3333 7.10143 10.6845 6.47631 11.3096C5.85119 11.9348 5.5 12.7826 5.5 13.6667C5.5 14.5507 5.85119 15.3986 6.47631 16.0237C7.10143 16.6488 7.94928 17 8.83333 17H9.66667\"/></svg>', e1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 19V19C9.13623 19 8.20435 19 7.46927 18.6955C6.48915 18.2895 5.71046 17.5108 5.30448 16.5307C5 15.7956 5 14.8638 5 13V12C5 9.19108 5 7.78661 5.67412 6.77772C5.96596 6.34096 6.34096 5.96596 6.77772 5.67412C7.78661 5 9.19108 5 12 5H13.5C14.8956 5 15.5933 5 16.1611 5.17224C17.4395 5.56004 18.44 6.56046 18.8278 7.83886C19 8.40666 19 9.10444 19 10.5V10.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M19.1187 14.8787L16.9974 17M14.876 19.1213L16.9974 17M19.1187 19.1213L16.9974 17M16.9974 17L14.876 14.8787\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6.5 17.5L17.5 6.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.9919 10.5H19.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.9919 19H11.0015\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13L13 5\"/></svg>', n1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M11.5 17.5L5 11M5 11V15.5M5 11H9.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12.5 6.5L19 13M19 13V8.5M19 13H14.5\"/></svg>', s1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M15.078 5.62637L15.6153 4.78296L15.078 5.62637C15.4261 5.84808 15.7393 6.15354 16.5711 6.98528L17.2782 6.27817L16.5711 6.98528L17.5251 7.93934C17.8347 8.2489 17.9496 8.36494 18.0489 8.48177C18.5907 9.11982 18.9188 9.91178 18.9868 10.7461C18.9992 10.8989 19 11.0622 19 11.5V12C19 13.4166 18.9992 14.419 18.9352 15.2026C18.8721 15.9745 18.7527 16.4457 18.564 16.816C18.1805 17.5686 17.5686 18.1805 16.816 18.564C16.4457 18.7527 15.9745 18.8721 15.2026 18.9352C14.419 18.9992 13.4166 19 12 19C10.5834 19 9.58104 18.9992 8.79744 18.9352C8.02552 18.8721 7.55435 18.7527 7.18404 18.564C6.43139 18.1805 5.81947 17.5686 5.43597 16.816C5.24729 16.4457 5.12787 15.9745 5.0648 15.2026C5.00078 14.419 5 13.4166 5 12V11.7782C5 10.4673 5.00067 9.53987 5.05572 8.81299C5.10998 8.09655 5.21284 7.65673 5.37487 7.3093C5.77229 6.45718 6.45718 5.77229 7.3093 5.37487C7.65673 5.21284 8.09655 5.10998 8.81299 5.05572C9.53986 5.00067 10.4673 5 11.7782 5C12.9544 5 13.3919 5.00552 13.7948 5.09484C14.2503 5.19583 14.6846 5.37572 15.078 5.62637Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 15C13.1046 15 14 14.1046 14 13C14 11.8954 13.1046 11 12 11C10.8954 11 10 11.8954 10 13C10 14.1046 10.8954 15 12 15Z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 5.5V7C14 7.55228 13.5523 8 13 8H11C10.4477 8 10 7.55228 10 7V5.2\"/></svg>', i1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><circle cx=\"10.5\" cy=\"10.5\" r=\"5.5\" stroke=\"currentColor\" stroke-width=\"2\"/><line x1=\"15.4142\" x2=\"19\" y1=\"15\" y2=\"18.5858\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>', h1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M11.8197 6.04369C11.8924 5.8925 12.1076 5.8925 12.1803 6.04369L13.9776 9.78496C14.0068 9.84564 14.0645 9.88759 14.1312 9.89657L18.2448 10.4498C18.411 10.4722 18.4776 10.6769 18.3562 10.7927L15.3535 13.6582C15.3048 13.7047 15.2827 13.7726 15.2948 13.8388L16.0398 17.922C16.0699 18.087 15.8957 18.2136 15.7481 18.1339L12 16.1124L8.25192 18.1339C8.10429 18.2136 7.93012 18.087 7.96022 17.922L8.7052 13.8388C8.71728 13.7726 8.69523 13.7047 8.64652 13.6582L5.64378 10.7927C5.52244 10.6769 5.58896 10.4722 5.7552 10.4498L9.86876 9.89657C9.93549 9.88759 9.99322 9.84564 10.0224 9.78496L11.8197 6.04369Z\"/></svg>', l1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17 9L20 12L17 15\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 12H20\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 9L4 12L7 15\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 12H10\"/></svg>', w1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.5 8.50001C13.5 7 10.935 6.66476 9.75315 7.79706C9.27092 8.25909 9 8.88574 9 9.53915C9 10.1926 9.27092 10.8192 9.75315 11.2812C10.9835 12.46 13.0165 11.5457 14.2468 12.7244C14.7291 13.1865 15 13.8131 15 14.4665C15 15.1199 14.7291 15.7466 14.2468 16.2086C12.8659 17.5317 10 17.5 9 16\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 12H18\"/></svg>', d1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 10H19\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>', k1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 5V18.5\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M14 5V18.5\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 10H19\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 14H19\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>', c1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 5V18.5\"/><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M5 10H19\"/><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/></svg>', C1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8 9V7.2C8 7.08954 8.08954 7 8.2 7L12 7M16 9V7.2C16 7.08954 15.9105 7 15.8 7L12 7M12 7L12 17M12 17H10M12 17H14\"/></svg>', g1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M7 17C8 14.5 12 12 13 9\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8.5 11C8.5 11 10 14 12.5 15\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6 7.7H16M11 7.7V5.7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M14.5 18L15.2143 16M15.2143 16L16.9159 11.2354C16.9663 11.0942 17.1001 11 17.25 11C17.3999 11 17.5337 11.0942 17.5841 11.2354L19.2857 16M15.2143 16H19.2857M20 18L19.2857 16\"/></svg>', u1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.1328 7.7234C18.423 7.7634 18.7115 7.80571 19 7.85109M18.1328 7.7234L17.2267 17.4023C17.1897 17.8371 16.973 18.2432 16.62 18.5394C16.267 18.8356 15.8037 19.0001 15.3227 19H8.67733C8.19632 19.0001 7.73299 18.8356 7.37998 18.5394C7.02698 18.2432 6.81032 17.8371 6.77333 17.4023L5.86715 7.7234M18.1328 7.7234C17.1536 7.58919 16.1693 7.48733 15.1818 7.41803M5.86715 7.7234C5.57697 7.76263 5.28848 7.80494 5 7.85032M5.86715 7.7234C6.84642 7.58919 7.83074 7.48733 8.81818 7.41803M15.1818 7.41803C13.0638 7.26963 10.9362 7.26963 8.81818 7.41803M15.1818 7.41803C15.1818 5.30368 13.7266 4.34834 12 4.34834C10.2734 4.34834 8.81818 5.43945 8.81818 7.41803\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.5 15.5L10 11\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 11L13.5 15.5\"/></svg>', p1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16.7893 7.87697C17.5 8 18.5 8 18.5 8C18.5 8 17.5 9.5 17.5 10C18.5 18.5 11.5 20.5 5.5 16.5C6.99996 16.6712 8.04617 16.5163 9.25234 15.6024C7.99546 15.58 5.36548 13.6033 5 12.5C6.5 13 8 12 8 12C6.52134 11.0446 4.93005 9.24114 5.97461 7.50832C7.39125 9.18838 9.50766 10.2939 11.8948 10.4097C11.2198 7.60755 14.9218 5.95341 16.7893 7.87697Z\"/></svg>', a1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 7.5V11.5C9 12.2956 9.31607 13.0587 9.87868 13.6213C10.4413 14.1839 11.2044 14.5 12 14.5C12.7956 14.5 13.5587 14.1839 14.1213 13.6213C14.6839 13.0587 15 12.2956 15 11.5V7.5\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7.71429 18H16.2857\"/></svg>', v1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9.33333 13.6667L6 10.3333L9.33333 7M6 10.3333H15.1667C16.0507 10.3333 16.8986 10.6845 17.5237 11.3096C18.1488 11.9348 18.5 12.7826 18.5 13.6667C18.5 14.5507 18.1488 15.3986 17.5237 16.0237C16.8986 16.6488 16.0507 17 15.1667 17H14.3333\"/></svg>', M1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M15.7795 11.5C15.7795 11.5 16.053 11.1962 16.5497 10.6722C17.4442 9.72856 17.4701 8.2475 16.5781 7.30145V7.30145C15.6482 6.31522 14.0873 6.29227 13.1288 7.25073L11.8796 8.49999\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8.24517 12.3883C8.24517 12.3883 7.97171 12.6922 7.47504 13.2161C6.58051 14.1598 6.55467 15.6408 7.44666 16.5869V16.5869C8.37653 17.5731 9.93744 17.5961 10.8959 16.6376L12.1452 15.3883\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17.7802 15.1032L16.597 14.9422C16.0109 14.8624 15.4841 15.3059 15.4627 15.8969L15.4199 17.0818\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M6.39064 9.03238L7.58432 9.06668C8.17551 9.08366 8.6522 8.58665 8.61056 7.99669L8.5271 6.81397\"/><line x1=\"12.1142\" x2=\"11.7\" y1=\"12.2\" y2=\"11.7858\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/></svg>', x1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M12 10C12.7145 10 13.239 9.56559 13.5392 9.11536C13.844 8.65814 14 8.0841 14 7.5C14 6.9159 13.844 6.34186 13.5392 5.88464C13.239 5.43441 12.7145 5 12 5C11.2855 5 10.761 5.43441 10.4608 5.88464C10.156 6.34186 10 6.9159 10 7.5C10 8.0841 10.156 8.65814 10.4608 9.11536C10.761 9.56559 11.2855 10 12 10Z\"/><ellipse cx=\"12\" cy=\"16\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"3\" ry=\"5\" transform=\"rotate(-90 12 16)\"/></svg>', L1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-width=\"2\" d=\"M10 10C10.7145 10 11.239 9.56559 11.5392 9.11536C11.844 8.65814 12 8.0841 12 7.5C12 6.9159 11.844 6.34186 11.5392 5.88464C11.239 5.43441 10.7145 5 10 5C9.28547 5 8.761 5.43441 8.46084 5.88464C8.15603 6.34186 8 6.9159 8 7.5C8 8.0841 8.15603 8.65814 8.46084 9.11536C8.761 9.56559 9.28547 10 10 10Z\"/><ellipse cx=\"10\" cy=\"16\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"3\" ry=\"5\" transform=\"rotate(-90 10 16)\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M15.5555 10.2222C16.5374 10.2222 17.3333 9.42629 17.3333 8.44445C17.3333 7.46261 16.5374 6.66667 15.5555 6.66667\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M17.5 13C21 14.5 20.5 18 18 18.5\"/></svg>', H1 = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" stroke=\"currentColor\" stroke-width=\"2\" rx=\"4\"/><line x1=\"12\" x2=\"12\" y1=\"9\" y2=\"12\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M12 15.02V15.01\"/></svg>';\nexport {\n i as IconAddBackground,\n h as IconAddBorder,\n l as IconAlignCenter,\n w as IconAlignJustify,\n d as IconAlignLeft,\n k as IconAlignRight,\n c as IconBold,\n C as IconBrackets,\n g as IconCheck,\n u as IconChecklist,\n p as IconChevronDown,\n a as IconChevronLeft,\n v as IconChevronRight,\n M as IconChevronUp,\n x as IconClipboard,\n L as IconCollapse,\n H as IconColor,\n m as IconCopy,\n f as IconCross,\n B as IconCurlyBrackets,\n I as IconDelimiter,\n V as IconDirectionDownRight,\n j as IconDirectionLeftDown,\n y as IconDirectionRightDown,\n Z as IconDirectionUpRight,\n D as IconDotCircle,\n T as IconEtcHorisontal,\n b as IconEtcVertical,\n R as IconFile,\n U as IconGift,\n A as IconGlobe,\n o as IconH1,\n t as IconH2,\n r as IconH3,\n e as IconH4,\n n as IconH5,\n s as IconH6,\n S as IconHeading,\n G as IconHeart,\n P as IconHidden,\n W as IconHtml,\n E as IconInstagram,\n N as IconItalic,\n Q as IconLink,\n F as IconLinkedin,\n J as IconListBulleted,\n X as IconListNumbered,\n q as IconLoader,\n z as IconMarker,\n O as IconMenu,\n K as IconMenuSmall,\n Y as IconPicture,\n _ as IconPlay,\n $ as IconPlus,\n o1 as IconQuestion,\n t1 as IconQuote,\n r1 as IconRedo,\n e1 as IconRemoveBackground,\n n1 as IconReplace,\n s1 as IconSave,\n i1 as IconSearch,\n h1 as IconStar,\n l1 as IconStretch,\n w1 as IconStrikethrough,\n c1 as IconTable,\n d1 as IconTableWithHeadings,\n k1 as IconTableWithoutHeadings,\n C1 as IconText,\n g1 as IconTranslate,\n u1 as IconTrash,\n p1 as IconTwitter,\n a1 as IconUnderline,\n v1 as IconUndo,\n M1 as IconUnlink,\n x1 as IconUser,\n L1 as IconUsersGroup,\n H1 as IconWarning\n};\n","const ELEMENT_DELIMITER = '__';\r\nconst MODIFIER_DELIMITER = '--';\r\n\r\n/**\r\n * Utility function that allows to construct class names from block and element names\r\n *\r\n * @example bem('ce-popover)() -> 'ce-popover'\r\n * @example bem('ce-popover)('container') -> 'ce-popover__container'\r\n * @example bem('ce-popover)('container', 'hidden') -> 'ce-popover__container--hidden'\r\n * @example bem('ce-popover)(null, 'hidden') -> 'ce-popover--hidden'\r\n * @param blockName - string with block name\r\n */\r\nexport function bem(blockName: string) {\r\n /**\r\n * @param elementName - string with element name\r\n * @param modifier - modifier to be appended\r\n */\r\n return (elementName?: string | null, modifier?: string) => {\r\n const className = [blockName, elementName]\r\n .filter(x => !!x)\r\n .join(ELEMENT_DELIMITER);\r\n\r\n return [className, modifier]\r\n .filter(x => !!x)\r\n .join(MODIFIER_DELIMITER);\r\n };\r\n}\r\n","import { bem } from '../../../bem';\r\n\r\n/**\r\n * Hint block CSS class constructor\r\n */\r\nconst className = bem('ce-hint');\r\n\r\n/**\r\n * CSS class names to be used in hint class\r\n */\r\nexport const css = {\r\n root: className(),\r\n alignedStart: className(null, 'align-left'),\r\n alignedCenter: className(null, 'align-center'),\r\n title: className('title'),\r\n description: className('description'),\r\n};\r\n","import Dom from '../../../../dom';\r\nimport { css } from './hint.const';\r\nimport type { HintParams } from '../../../../../../types/utils/popover/hint';\r\n\r\nimport './hint.css';\r\n\r\n/**\r\n * Represents the hint content component\r\n */\r\nexport class Hint {\r\n /**\r\n * Html element used to display hint content on screen\r\n */\r\n private nodes: {\r\n root: HTMLElement;\r\n title: HTMLElement;\r\n description?: HTMLElement;\r\n };\r\n\r\n /**\r\n * Constructs the hint content instance\r\n *\r\n * @param params - hint content parameters\r\n */\r\n constructor(params: HintParams) {\r\n this.nodes = {\r\n root: Dom.make('div', [css.root, params.alignment === 'center' ? css.alignedCenter : css.alignedStart]),\r\n title: Dom.make('div', css.title, { textContent: params.title }),\r\n };\r\n\r\n this.nodes.root.appendChild(this.nodes.title);\r\n\r\n if (params.description !== undefined) {\r\n this.nodes.description = Dom.make('div', css.description, { textContent: params.description });\r\n\r\n this.nodes.root.appendChild(this.nodes.description);\r\n }\r\n }\r\n\r\n /**\r\n * Returns the root element of the hint content\r\n */\r\n public getElement(): HTMLElement {\r\n return this.nodes.root;\r\n }\r\n}\r\n","import * as tooltip from '../../../tooltip';\r\nimport { type HintPosition, Hint } from '../hint';\r\nimport type { PopoverItemParams } from '../../../../../../types/utils/popover/popover-item';\r\n\r\n/**\r\n * Popover item abstract class\r\n */\r\nexport abstract class PopoverItem {\r\n /**\r\n * Constructs the instance\r\n *\r\n * @param params - instance parameters\r\n */\r\n constructor(protected readonly params?: PopoverItemParams) {}\r\n\r\n /**\r\n * Item name if exists\r\n */\r\n public get name(): string | undefined {\r\n if (this.params === undefined) {\r\n return;\r\n }\r\n if ('name' in this.params) {\r\n return this.params.name;\r\n }\r\n }\r\n\r\n /**\r\n * Destroys the instance\r\n */\r\n public destroy(): void {\r\n tooltip.hide();\r\n }\r\n\r\n /**\r\n * Called when children popover is opened (if exists)\r\n */\r\n public onChildrenOpen(): void {\r\n if (this.params === undefined) {\r\n return;\r\n }\r\n\r\n if ('children' in this.params && typeof this.params.children?.onOpen === 'function') {\r\n this.params.children.onOpen();\r\n }\r\n }\r\n\r\n /**\r\n * Called when children popover is closed (if exists)\r\n */\r\n public onChildrenClose(): void {\r\n if (this.params === undefined) {\r\n return;\r\n }\r\n\r\n if ('children' in this.params && typeof this.params.children?.onClose === 'function') {\r\n this.params.children.onClose();\r\n }\r\n }\r\n\r\n /**\r\n * Called on popover item click\r\n */\r\n public handleClick(): void {\r\n if (this.params === undefined) {\r\n return;\r\n }\r\n\r\n if (!('onActivate' in this.params)) {\r\n return;\r\n }\r\n\r\n this.params.onActivate?.(this.params);\r\n }\r\n\r\n /**\r\n * Adds hint to the item element if hint data is provided\r\n *\r\n * @param itemElement - popover item root element to add hint to\r\n * @param hintData - hint data\r\n */\r\n protected addHint(itemElement: HTMLElement, hintData: { title: string, description?: string; position: HintPosition }): void {\r\n const content = new Hint(hintData);\r\n\r\n tooltip.onHover(itemElement, content.getElement(), {\r\n placement: hintData.position,\r\n hidingDelay: 100,\r\n });\r\n }\r\n\r\n /**\r\n * Returns popover item root element\r\n */\r\n public abstract getElement(): HTMLElement | null;\r\n\r\n /**\r\n * Toggles item hidden state\r\n *\r\n * @param isHidden - true if item should be hidden\r\n */\r\n public abstract toggleHidden(isHidden: boolean): void;\r\n\r\n\r\n /**\r\n * Returns item children that are represented as popover items\r\n */\r\n public get children(): PopoverItemParams[] {\r\n return this.params !== undefined && 'children' in this.params && this.params.children?.items !== undefined ? this.params.children.items : [];\r\n }\r\n\r\n /**\r\n * Returns true if item has any type of children\r\n */\r\n public get hasChildren(): boolean {\r\n return this.children.length > 0;\r\n }\r\n\r\n /**\r\n * Returns true if item children should be open instantly after popover is opened and not on item click/hover\r\n */\r\n public get isChildrenOpen(): boolean {\r\n return this.params !== undefined && 'children' in this.params && this.params.children?.isOpen === true;\r\n }\r\n\r\n /**\r\n * True if item children items should be navigatable via keyboard\r\n */\r\n public get isChildrenFlippable(): boolean {\r\n if (this.params === undefined) {\r\n return false;\r\n }\r\n\r\n if (!('children' in this.params)) {\r\n return false;\r\n }\r\n\r\n if (this.params.children?.isFlippable === false) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns true if item has children that should be searchable\r\n */\r\n public get isChildrenSearchable(): boolean {\r\n return this.params !== undefined && 'children' in this.params && this.params.children?.searchable === true;\r\n }\r\n\r\n /**\r\n * True if popover should close once item is activated\r\n */\r\n public get closeOnActivate(): boolean | undefined {\r\n return this.params !== undefined && 'closeOnActivate' in this.params && this.params.closeOnActivate;\r\n }\r\n\r\n /**\r\n * True if item is active\r\n */\r\n public get isActive(): boolean {\r\n if (this.params === undefined) {\r\n return false;\r\n }\r\n\r\n if (!('isActive' in this.params)) {\r\n return false;\r\n }\r\n\r\n if (typeof this.params.isActive === 'function') {\r\n return this.params.isActive();\r\n }\r\n\r\n return this.params.isActive === true;\r\n }\r\n}\r\n","import { bem } from '../../../../bem';\r\n\r\n/**\r\n * Popover item block CSS class constructor\r\n */\r\nconst className = bem('ce-popover-item');\r\n\r\n/**\r\n * CSS class names to be used in popover item class\r\n */\r\nexport const css = {\r\n container: className(),\r\n active: className(null, 'active'),\r\n disabled: className(null, 'disabled'),\r\n focused: className(null, 'focused'),\r\n hidden: className(null, 'hidden'),\r\n confirmationState: className(null, 'confirmation'),\r\n noHover: className(null, 'no-hover'),\r\n noFocus: className(null, 'no-focus'),\r\n title: className('title'),\r\n secondaryTitle: className('secondary-title'),\r\n icon: className('icon'),\r\n iconTool: className('icon', 'tool'),\r\n iconChevronRight: className('icon', 'chevron-right'),\r\n wobbleAnimation: bem('wobble')(),\r\n};\r\n","import Dom from '../../../../../dom';\r\nimport { IconDotCircle, IconChevronRight } from '@codexteam/icons';\r\nimport type {\r\n PopoverItemDefaultParams as PopoverItemDefaultParams,\r\n PopoverItemRenderParamsMap,\r\n PopoverItemType\r\n} from '../../../../../../../types/utils/popover/popover-item';\r\nimport { PopoverItem } from '../popover-item';\r\nimport { css } from './popover-item-default.const';\r\n\r\n/**\r\n * Represents sigle popover item node\r\n *\r\n * @todo move nodes initialization to constructor\r\n * @todo replace multiple make() usages with constructing separate instances\r\n * @todo split regular popover item and popover item with confirmation to separate classes\r\n * @todo display icon on the right side of the item for rtl languages\r\n */\r\nexport class PopoverItemDefault extends PopoverItem {\r\n /**\r\n * True if item is disabled and hence not clickable\r\n */\r\n public get isDisabled(): boolean {\r\n return this.params.isDisabled === true;\r\n }\r\n\r\n /**\r\n * Exposes popover item toggle parameter\r\n */\r\n public get toggle(): boolean | string | undefined {\r\n return this.params.toggle;\r\n }\r\n\r\n /**\r\n * Item title\r\n */\r\n public get title(): string | undefined {\r\n return this.params.title;\r\n }\r\n\r\n /**\r\n * True if confirmation state is enabled for popover item\r\n */\r\n public get isConfirmationStateEnabled(): boolean {\r\n return this.confirmationState !== null;\r\n }\r\n\r\n /**\r\n * True if item is focused in keyboard navigation process\r\n */\r\n public get isFocused(): boolean {\r\n if (this.nodes.root === null) {\r\n return false;\r\n }\r\n\r\n return this.nodes.root.classList.contains(css.focused);\r\n }\r\n\r\n /**\r\n * Item html elements\r\n */\r\n private nodes: {\r\n root: null | HTMLElement,\r\n icon: null | HTMLElement\r\n } = {\r\n root: null,\r\n icon: null,\r\n };\r\n\r\n /**\r\n * If item is in confirmation state, stores confirmation params such as icon, label, onActivate callback and so on\r\n */\r\n private confirmationState: PopoverItemDefaultParams | null = null;\r\n\r\n /**\r\n * Constructs popover item instance\r\n *\r\n * @param params - popover item construction params\r\n * @param renderParams - popover item render params.\r\n * The parameters that are not set by user via popover api but rather depend on technical implementation\r\n */\r\n constructor(protected readonly params: PopoverItemDefaultParams, renderParams?: PopoverItemRenderParamsMap[PopoverItemType.Default]) {\r\n super(params);\r\n\r\n this.nodes.root = this.make(params, renderParams);\r\n }\r\n\r\n /**\r\n * Returns popover item root element\r\n */\r\n public getElement(): HTMLElement | null {\r\n return this.nodes.root;\r\n }\r\n\r\n /**\r\n * Called on popover item click\r\n */\r\n public handleClick(): void {\r\n if (this.isConfirmationStateEnabled && this.confirmationState !== null) {\r\n this.activateOrEnableConfirmationMode(this.confirmationState);\r\n\r\n return;\r\n }\r\n\r\n this.activateOrEnableConfirmationMode(this.params);\r\n }\r\n\r\n /**\r\n * Toggles item active state\r\n *\r\n * @param isActive - true if item should strictly should become active\r\n */\r\n public toggleActive(isActive?: boolean): void {\r\n this.nodes.root?.classList.toggle(css.active, isActive);\r\n }\r\n\r\n /**\r\n * Toggles item hidden state\r\n *\r\n * @param isHidden - true if item should be hidden\r\n */\r\n public override toggleHidden(isHidden: boolean): void {\r\n this.nodes.root?.classList.toggle(css.hidden, isHidden);\r\n }\r\n\r\n /**\r\n * Resets popover item to its original state\r\n */\r\n public reset(): void {\r\n if (this.isConfirmationStateEnabled) {\r\n this.disableConfirmationMode();\r\n }\r\n }\r\n\r\n /**\r\n * Method called once item becomes focused during keyboard navigation\r\n */\r\n public onFocus(): void {\r\n this.disableSpecialHoverAndFocusBehavior();\r\n }\r\n\r\n /**\r\n * Constructs HTML element corresponding to popover item params\r\n *\r\n * @param params - item construction params\r\n * @param renderParams - popover item render params\r\n */\r\n private make(params: PopoverItemDefaultParams, renderParams?: PopoverItemRenderParamsMap[PopoverItemType.Default]): HTMLElement {\r\n const tag = renderParams?.wrapperTag || 'div';\r\n const el = Dom.make(tag, css.container, {\r\n type: tag === 'button' ? 'button' : undefined,\r\n });\r\n\r\n if (params.name) {\r\n el.dataset.itemName = params.name;\r\n }\r\n\r\n this.nodes.icon = Dom.make('div', [css.icon, css.iconTool], {\r\n innerHTML: params.icon || IconDotCircle,\r\n });\r\n\r\n el.appendChild(this.nodes.icon);\r\n\r\n if (params.title !== undefined) {\r\n el.appendChild(Dom.make('div', css.title, {\r\n innerHTML: params.title || '',\r\n }));\r\n }\r\n\r\n if (params.secondaryLabel) {\r\n el.appendChild(Dom.make('div', css.secondaryTitle, {\r\n textContent: params.secondaryLabel,\r\n }));\r\n }\r\n\r\n if (this.hasChildren) {\r\n el.appendChild(Dom.make('div', [css.icon, css.iconChevronRight], {\r\n innerHTML: IconChevronRight,\r\n }));\r\n }\r\n\r\n if (this.isActive) {\r\n el.classList.add(css.active);\r\n }\r\n\r\n if (params.isDisabled) {\r\n el.classList.add(css.disabled);\r\n }\r\n\r\n if (params.hint !== undefined && renderParams?.hint?.enabled !== false) {\r\n this.addHint(el, {\r\n ...params.hint,\r\n position: renderParams?.hint?.position || 'right',\r\n });\r\n }\r\n\r\n return el;\r\n }\r\n\r\n /**\r\n * Activates confirmation mode for the item.\r\n *\r\n * @param newState - new popover item params that should be applied\r\n */\r\n private enableConfirmationMode(newState: PopoverItemDefaultParams): void {\r\n if (this.nodes.root === null) {\r\n return;\r\n }\r\n\r\n const params = {\r\n ...this.params,\r\n ...newState,\r\n confirmation: 'confirmation' in newState ? newState.confirmation : undefined,\r\n } as PopoverItemDefaultParams;\r\n const confirmationEl = this.make(params);\r\n\r\n this.nodes.root.innerHTML = confirmationEl.innerHTML;\r\n this.nodes.root.classList.add(css.confirmationState);\r\n\r\n this.confirmationState = newState;\r\n\r\n this.enableSpecialHoverAndFocusBehavior();\r\n }\r\n\r\n /**\r\n * Returns item to its original state\r\n */\r\n private disableConfirmationMode(): void {\r\n if (this.nodes.root === null) {\r\n return;\r\n }\r\n const itemWithOriginalParams = this.make(this.params);\r\n\r\n this.nodes.root.innerHTML = itemWithOriginalParams.innerHTML;\r\n this.nodes.root.classList.remove(css.confirmationState);\r\n\r\n this.confirmationState = null;\r\n\r\n this.disableSpecialHoverAndFocusBehavior();\r\n }\r\n\r\n /**\r\n * Enables special focus and hover behavior for item in confirmation state.\r\n * This is needed to prevent item from being highlighted as hovered/focused just after click.\r\n */\r\n private enableSpecialHoverAndFocusBehavior(): void {\r\n this.nodes.root?.classList.add(css.noHover);\r\n this.nodes.root?.classList.add(css.noFocus);\r\n\r\n this.nodes.root?.addEventListener('mouseleave', this.removeSpecialHoverBehavior, { once: true });\r\n }\r\n\r\n /**\r\n * Disables special focus and hover behavior\r\n */\r\n private disableSpecialHoverAndFocusBehavior(): void {\r\n this.removeSpecialFocusBehavior();\r\n this.removeSpecialHoverBehavior();\r\n\r\n this.nodes.root?.removeEventListener('mouseleave', this.removeSpecialHoverBehavior);\r\n }\r\n\r\n /**\r\n * Removes class responsible for special focus behavior on an item\r\n */\r\n private removeSpecialFocusBehavior = (): void => {\r\n this.nodes.root?.classList.remove(css.noFocus);\r\n };\r\n\r\n /**\r\n * Removes class responsible for special hover behavior on an item\r\n */\r\n private removeSpecialHoverBehavior = (): void => {\r\n this.nodes.root?.classList.remove(css.noHover);\r\n };\r\n\r\n /**\r\n * Executes item's onActivate callback if the item has no confirmation configured\r\n *\r\n * @param item - item to activate or bring to confirmation mode\r\n */\r\n private activateOrEnableConfirmationMode(item: PopoverItemDefaultParams): void {\r\n if (!('confirmation' in item) || item.confirmation === undefined) {\r\n try {\r\n item.onActivate?.(item);\r\n this.disableConfirmationMode();\r\n } catch {\r\n this.animateError();\r\n }\r\n } else {\r\n this.enableConfirmationMode(item.confirmation);\r\n }\r\n }\r\n\r\n /**\r\n * Animates item which symbolizes that error occured while executing 'onActivate()' callback\r\n */\r\n private animateError(): void {\r\n if (this.nodes.icon?.classList.contains(css.wobbleAnimation)) {\r\n return;\r\n }\r\n\r\n this.nodes.icon?.classList.add(css.wobbleAnimation);\r\n\r\n this.nodes.icon?.addEventListener('animationend', this.onErrorAnimationEnd);\r\n }\r\n\r\n /**\r\n * Handles finish of error animation\r\n */\r\n private onErrorAnimationEnd = (): void => {\r\n this.nodes.icon?.classList.remove(css.wobbleAnimation);\r\n this.nodes.icon?.removeEventListener('animationend', this.onErrorAnimationEnd);\r\n };\r\n}\r\n","import { bem } from '../../../../bem';\r\n\r\n/**\r\n * Popover separator block CSS class constructor\r\n */\r\nconst className = bem('ce-popover-item-separator');\r\n\r\n/**\r\n * CSS class names to be used in popover separator class\r\n */\r\nexport const css = {\r\n container: className(),\r\n line: className('line'),\r\n hidden: className(null, 'hidden'),\r\n};\r\n","import Dom from '../../../../../dom';\r\nimport { PopoverItem } from '../popover-item';\r\nimport { css } from './popover-item-separator.const';\r\n\r\n/**\r\n * Represents popover separator node\r\n */\r\nexport class PopoverItemSeparator extends PopoverItem {\r\n /**\r\n * Html elements\r\n */\r\n private nodes: { root: HTMLElement; line: HTMLElement };\r\n\r\n /**\r\n * Constructs the instance\r\n */\r\n constructor() {\r\n super();\r\n\r\n this.nodes = {\r\n root: Dom.make('div', css.container),\r\n line: Dom.make('div', css.line),\r\n };\r\n\r\n this.nodes.root.appendChild(this.nodes.line);\r\n }\r\n\r\n /**\r\n * Returns popover separator root element\r\n */\r\n public getElement(): HTMLElement {\r\n return this.nodes.root;\r\n }\r\n\r\n /**\r\n * Toggles item hidden state\r\n *\r\n * @param isHidden - true if item should be hidden\r\n */\r\n public toggleHidden(isHidden: boolean): void {\r\n this.nodes.root?.classList.toggle(css.hidden, isHidden);\r\n }\r\n}\r\n","\r\n/**\r\n * Event that can be triggered by the Popover\r\n */\r\nexport enum PopoverEvent {\r\n /**\r\n * When popover closes\r\n */\r\n Closed = 'closed',\r\n\r\n /**\r\n * When it closes because item with 'closeOnActivate' property set was clicked\r\n */\r\n ClosedOnActivate = 'closed-on-activate',\r\n}\r\n","import { bem } from '../bem';\r\n\r\n/**\r\n * Popover block CSS class constructor\r\n */\r\nconst className = bem('ce-popover');\r\n\r\n/**\r\n * CSS class names to be used in popover\r\n */\r\nexport const css = {\r\n popover: className(),\r\n popoverContainer: className('container'),\r\n popoverOpenTop: className(null, 'open-top'),\r\n popoverOpenLeft: className(null, 'open-left'),\r\n popoverOpened: className(null, 'opened'),\r\n search: className('search'),\r\n nothingFoundMessage: className('nothing-found-message'),\r\n nothingFoundMessageDisplayed: className('nothing-found-message', 'displayed'),\r\n items: className('items'),\r\n overlay: className('overlay'),\r\n overlayHidden: className('overlay', 'hidden'),\r\n popoverNested: className(null, 'nested'),\r\n getPopoverNestedClass: (level: number) => className(null, `nested-level-${level.toString()}` ),\r\n popoverInline: className(null, 'inline'),\r\n popoverHeader: className('header'),\r\n};\r\n\r\n/**\r\n * CSS variables names to be used in popover\r\n */\r\nexport enum CSSVariables {\r\n /**\r\n * Stores nesting level of the popover\r\n */\r\n NestingLevel = '--nesting-level',\r\n\r\n /**\r\n * Stores actual popover height. Used for desktop popovers\r\n */\r\n PopoverHeight = '--popover-height',\r\n\r\n /**\r\n * Width of the inline popover\r\n */\r\n InlinePopoverWidth = '--inline-popover-width',\r\n\r\n /**\r\n * Offset from left of the inline popover item click on which triggers the nested popover opening\r\n */\r\n TriggerItemLeft = '--trigger-item-left',\r\n\r\n /**\r\n * Offset from top of the desktop popover item click on which triggers the nested popover opening\r\n */\r\n TriggerItemTop = '--trigger-item-top',\r\n}\r\n","import { bem } from '../../../../bem';\r\n\r\n/**\r\n * Popover item block CSS class constructor\r\n */\r\nconst className = bem('ce-popover-item-html');\r\n\r\n/**\r\n * CSS class names to be used in popover item class\r\n */\r\nexport const css = {\r\n root: className(),\r\n hidden: className(null, 'hidden'),\r\n};\r\n","import { PopoverItem } from '../popover-item';\r\nimport type { PopoverItemHtmlParams, PopoverItemRenderParamsMap, PopoverItemType } from '../../../../../../../types/utils/popover/popover-item';\r\nimport { css } from './popover-item-html.const';\r\nimport Dom from '../../../../../dom';\r\n\r\n/**\r\n * Represents popover item with custom html content\r\n */\r\nexport class PopoverItemHtml extends PopoverItem {\r\n /**\r\n * Item html elements\r\n */\r\n private nodes: { root: HTMLElement };\r\n\r\n /**\r\n * Constructs the instance\r\n *\r\n * @param params – instance parameters\r\n * @param renderParams – popover item render params.\r\n * The parameters that are not set by user via popover api but rather depend on technical implementation\r\n */\r\n constructor(params: PopoverItemHtmlParams, renderParams?: PopoverItemRenderParamsMap[PopoverItemType.Html]) {\r\n super(params);\r\n this.nodes = {\r\n root: Dom.make('div', css.root),\r\n };\r\n\r\n this.nodes.root.appendChild(params.element);\r\n\r\n if (params.name) {\r\n this.nodes.root.dataset.itemName = params.name;\r\n }\r\n\r\n if (params.hint !== undefined && renderParams?.hint?.enabled !== false) {\r\n this.addHint(this.nodes.root, {\r\n ...params.hint,\r\n position: renderParams?.hint?.position || 'right',\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Returns popover item root element\r\n */\r\n public getElement(): HTMLElement {\r\n return this.nodes.root;\r\n }\r\n\r\n /**\r\n * Toggles item hidden state\r\n *\r\n * @param isHidden - true if item should be hidden\r\n */\r\n public toggleHidden(isHidden: boolean): void {\r\n this.nodes.root?.classList.toggle(css.hidden, isHidden);\r\n }\r\n\r\n /**\r\n * Returns list of buttons and inputs inside custom content\r\n */\r\n public getControls(): HTMLElement[] {\r\n /** Query buttons and inputs inside custom html */\r\n const controls = this.nodes.root.querySelectorAll<HTMLElement>(\r\n `button, ${Dom.allInputsSelector}`\r\n );\r\n\r\n return Array.from(controls);\r\n }\r\n}\r\n","import type { PopoverItem, PopoverItemRenderParamsMap } from './components/popover-item';\r\nimport { PopoverItemDefault, PopoverItemSeparator, PopoverItemType } from './components/popover-item';\r\nimport Dom from '../../dom';\r\nimport type { SearchInput } from './components/search-input';\r\nimport EventsDispatcher from '../events';\r\nimport Listeners from '../listeners';\r\nimport type { PopoverEventMap, PopoverMessages, PopoverParams, PopoverNodes } from '../../../../types/utils/popover/popover';\r\nimport { PopoverEvent } from '../../../../types/utils/popover/popover-event';\r\nimport { css } from './popover.const';\r\nimport type { PopoverItemParams } from './components/popover-item';\r\nimport { PopoverItemHtml } from './components/popover-item/popover-item-html/popover-item-html';\r\n\r\n/**\r\n * Class responsible for rendering popover and handling its behaviour\r\n */\r\nexport abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes> extends EventsDispatcher<PopoverEventMap> {\r\n /**\r\n * List of popover items\r\n */\r\n protected items: Array<PopoverItem>;\r\n\r\n /**\r\n * Listeners util instance\r\n */\r\n protected listeners: Listeners = new Listeners();\r\n\r\n /**\r\n * Refs to created HTML elements\r\n */\r\n protected nodes: Nodes;\r\n\r\n /**\r\n * List of default popover items that are searchable and may have confirmation state\r\n */\r\n protected get itemsDefault(): PopoverItemDefault[] {\r\n return this.items.filter(item => item instanceof PopoverItemDefault) as PopoverItemDefault[];\r\n }\r\n\r\n /**\r\n * Instance of the Search Input\r\n */\r\n protected search: SearchInput | undefined;\r\n\r\n /**\r\n * Messages that will be displayed in popover\r\n */\r\n protected messages: PopoverMessages = {\r\n nothingFound: 'Nothing found',\r\n search: 'Search',\r\n };\r\n\r\n /**\r\n * Constructs the instance\r\n *\r\n * @param params - popover construction params\r\n * @param itemsRenderParams - popover item render params.\r\n * The parameters that are not set by user via popover api but rather depend on technical implementation\r\n */\r\n constructor(\r\n protected readonly params: PopoverParams,\r\n protected readonly itemsRenderParams: PopoverItemRenderParamsMap = {}\r\n ) {\r\n super();\r\n\r\n this.items = this.buildItems(params.items);\r\n\r\n if (params.messages) {\r\n this.messages = {\r\n ...this.messages,\r\n ...params.messages,\r\n };\r\n }\r\n\r\n /** Build html elements */\r\n this.nodes = {} as Nodes;\r\n\r\n this.nodes.popoverContainer = Dom.make('div', [ css.popoverContainer ]);\r\n\r\n this.nodes.nothingFoundMessage = Dom.make('div', [ css.nothingFoundMessage ], {\r\n textContent: this.messages.nothingFound,\r\n });\r\n\r\n this.nodes.popoverContainer.appendChild(this.nodes.nothingFoundMessage);\r\n this.nodes.items = Dom.make('div', [ css.items ]);\r\n\r\n this.items.forEach(item => {\r\n const itemEl = item.getElement();\r\n\r\n if (itemEl === null) {\r\n return;\r\n }\r\n\r\n this.nodes.items.appendChild(itemEl);\r\n });\r\n\r\n this.nodes.popoverContainer.appendChild(this.nodes.items);\r\n\r\n this.listeners.on(this.nodes.popoverContainer, 'click', (event: Event) => this.handleClick(event));\r\n\r\n this.nodes.popover = Dom.make('div', [\r\n css.popover,\r\n this.params.class,\r\n ]);\r\n\r\n this.nodes.popover.appendChild(this.nodes.popoverContainer);\r\n }\r\n\r\n /**\r\n * Returns HTML element corresponding to the popover\r\n */\r\n public getElement(): HTMLElement {\r\n return this.nodes.popover as HTMLElement;\r\n }\r\n\r\n /**\r\n * Open popover\r\n */\r\n public show(): void {\r\n this.nodes.popover.classList.add(css.popoverOpened);\r\n\r\n if (this.search !== undefined) {\r\n this.search.focus();\r\n }\r\n }\r\n\r\n /**\r\n * Closes popover\r\n */\r\n public hide(): void {\r\n this.nodes.popover.classList.remove(css.popoverOpened);\r\n this.nodes.popover.classList.remove(css.popoverOpenTop);\r\n\r\n this.itemsDefault.forEach(item => item.reset());\r\n\r\n if (this.search !== undefined) {\r\n this.search.clear();\r\n }\r\n\r\n this.emit(PopoverEvent.Closed);\r\n }\r\n\r\n /**\r\n * Clears memory\r\n */\r\n public destroy(): void {\r\n this.items.forEach(item => item.destroy());\r\n this.nodes.popover.remove();\r\n this.listeners.removeAll();\r\n this.search?.destroy();\r\n }\r\n\r\n /**\r\n * Looks for the item by name and imitates click on it\r\n *\r\n * @param name - name of the item to activate\r\n */\r\n public activateItemByName(name: string): void {\r\n const foundItem = this.items.find(item => item.name === name);\r\n\r\n this.handleItemClick(foundItem);\r\n }\r\n\r\n /**\r\n * Factory method for creating popover items\r\n *\r\n * @param items - list of items params\r\n */\r\n protected buildItems(items: PopoverItemParams[]): Array<PopoverItem> {\r\n return items.map(item => {\r\n switch (item.type) {\r\n case PopoverItemType.Separator:\r\n return new PopoverItemSeparator();\r\n case PopoverItemType.Html:\r\n return new PopoverItemHtml(item, this.itemsRenderParams[PopoverItemType.Html]);\r\n default:\r\n return new PopoverItemDefault(item, this.itemsRenderParams[PopoverItemType.Default]);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Retrieves popover item that is the target of the specified event\r\n *\r\n * @param event - event to retrieve popover item from\r\n */\r\n protected getTargetItem(event: Event): PopoverItemDefault | PopoverItemHtml | undefined {\r\n return this.items\r\n .filter(item => item instanceof PopoverItemDefault || item instanceof PopoverItemHtml)\r\n .find(item => {\r\n const itemEl = item.getElement();\r\n\r\n if (itemEl === null) {\r\n return false;\r\n }\r\n\r\n return event.composedPath().includes(itemEl);\r\n }) as PopoverItemDefault | PopoverItemHtml | undefined;\r\n }\r\n\r\n /**\r\n * Handles popover item click\r\n *\r\n * @param item - item to handle click of\r\n */\r\n protected handleItemClick(item: PopoverItem): void {\r\n if ('isDisabled' in item && item.isDisabled) {\r\n return;\r\n }\r\n\r\n if (item.hasChildren) {\r\n this.showNestedItems(item as PopoverItemDefault | PopoverItemHtml);\r\n\r\n if ('handleClick' in item && typeof item.handleClick === 'function') {\r\n item.handleClick();\r\n }\r\n\r\n return;\r\n }\r\n\r\n /** Cleanup other items state */\r\n this.itemsDefault.filter(x => x !== item).forEach(x => x.reset());\r\n\r\n if ('handleClick' in item && typeof item.handleClick === 'function') {\r\n item.handleClick();\r\n }\r\n\r\n this.toggleItemActivenessIfNeeded(item);\r\n\r\n if (item.closeOnActivate) {\r\n this.hide();\r\n\r\n this.emit(PopoverEvent.ClosedOnActivate);\r\n }\r\n }\r\n\r\n /**\r\n * Handles clicks inside popover\r\n *\r\n * @param event - item to handle click of\r\n */\r\n private handleClick(event: Event): void {\r\n const item = this.getTargetItem(event);\r\n\r\n if (item === undefined) {\r\n return;\r\n }\r\n\r\n this.handleItemClick(item);\r\n }\r\n\r\n /**\r\n * - Toggles item active state, if clicked popover item has property 'toggle' set to true.\r\n *\r\n * - Performs radiobutton-like behavior if the item has property 'toggle' set to string key.\r\n * (All the other items with the same key get inactive, and the item gets active)\r\n *\r\n * @param clickedItem - popover item that was clicked\r\n */\r\n private toggleItemActivenessIfNeeded(clickedItem: PopoverItem): void {\r\n if (!(clickedItem instanceof PopoverItemDefault)) {\r\n return;\r\n }\r\n\r\n if (clickedItem.toggle === true) {\r\n clickedItem.toggleActive();\r\n }\r\n\r\n if (typeof clickedItem.toggle === 'string') {\r\n const itemsInToggleGroup = this.itemsDefault.filter(item => item.toggle === clickedItem.toggle);\r\n\r\n /** If there's only one item in toggle group, toggle it */\r\n if (itemsInToggleGroup.length === 1) {\r\n clickedItem.toggleActive();\r\n\r\n return;\r\n }\r\n\r\n /** Set clicked item as active and the rest items with same toggle key value as inactive */\r\n itemsInToggleGroup.forEach(item => {\r\n item.toggleActive(item === clickedItem);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Handles displaying nested items for the item. Behaviour differs depending on platform.\r\n *\r\n * @param item – item to show nested popover for\r\n */\r\n protected abstract showNestedItems(item: PopoverItemDefault | PopoverItemHtml): void;\r\n}\r\n","/**\r\n * Item that could be searched\r\n */\r\nexport interface SearchableItem {\r\n /**\r\n * Items title\r\n */\r\n title?: string;\r\n}\r\n\r\n\r\n/**\r\n * Event that can be triggered by the Search Input\r\n */\r\nexport enum SearchInputEvent {\r\n /**\r\n * When search quert applied\r\n */\r\n Search = 'search'\r\n}\r\n\r\n/**\r\n * Events fired by the Search Input\r\n */\r\nexport interface SearchInputEventMap {\r\n /**\r\n * Fired when search quert applied\r\n */\r\n [SearchInputEvent.Search]: { query: string; items: SearchableItem[]};\r\n}\r\n","import { bem } from '../../../bem';\r\n\r\n/**\r\n * Popover search input block CSS class constructor\r\n */\r\nconst className = bem('cdx-search-field');\r\n\r\n/**\r\n * CSS class names to be used in popover search input class\r\n */\r\nexport const css = {\r\n wrapper: className(),\r\n icon: className('icon'),\r\n input: className('input'),\r\n};\r\n","import Dom from '../../../../dom';\r\nimport Listeners from '../../../listeners';\r\nimport { IconSearch } from '@codexteam/icons';\r\nimport type { SearchInputEventMap, SearchableItem } from './search-input.types';\r\nimport { SearchInputEvent } from './search-input.types';\r\nimport { css } from './search-input.const';\r\nimport EventsDispatcher from '../../../events';\r\n\r\n/**\r\n * Provides search input element and search logic\r\n */\r\nexport class SearchInput extends EventsDispatcher<SearchInputEventMap> {\r\n /**\r\n * Input wrapper element\r\n */\r\n private wrapper: HTMLElement;\r\n\r\n /**\r\n * Editable input itself\r\n */\r\n private input: HTMLInputElement;\r\n\r\n /**\r\n * The instance of the Listeners util\r\n */\r\n private listeners: Listeners;\r\n\r\n /**\r\n * Items for local search\r\n */\r\n private items: SearchableItem[];\r\n\r\n /**\r\n * Current search query\r\n */\r\n private searchQuery: string | undefined;\r\n\r\n /**\r\n * @param options - available config\r\n * @param options.items - searchable items list\r\n * @param options.placeholder - input placeholder\r\n */\r\n constructor({ items, placeholder }: {\r\n items: SearchableItem[];\r\n placeholder?: string;\r\n }) {\r\n super();\r\n\r\n this.listeners = new Listeners();\r\n this.items = items;\r\n\r\n /** Build ui */\r\n this.wrapper = Dom.make('div', css.wrapper);\r\n\r\n const iconWrapper = Dom.make('div', css.icon, {\r\n innerHTML: IconSearch,\r\n });\r\n\r\n this.input = Dom.make('input', css.input, {\r\n placeholder,\r\n /**\r\n * Used to prevent focusing on the input by Tab key\r\n * (Popover in the Toolbar lays below the blocks,\r\n * so Tab in the last block will focus this hidden input if this property is not set)\r\n */\r\n tabIndex: -1,\r\n }) as HTMLInputElement;\r\n\r\n this.wrapper.appendChild(iconWrapper);\r\n this.wrapper.appendChild(this.input);\r\n\r\n this.listeners.on(this.input, 'input', () => {\r\n this.searchQuery = this.input.value;\r\n\r\n this.emit(SearchInputEvent.Search, {\r\n query: this.searchQuery,\r\n items: this.foundItems,\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Returns search field element\r\n */\r\n public getElement(): HTMLElement {\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Sets focus to the input\r\n */\r\n public focus(): void {\r\n this.input.focus();\r\n }\r\n\r\n /**\r\n * Clears search query and results\r\n */\r\n public clear(): void {\r\n this.input.value = '';\r\n this.searchQuery = '';\r\n\r\n this.emit(SearchInputEvent.Search, {\r\n query: '',\r\n items: this.foundItems,\r\n });\r\n }\r\n\r\n /**\r\n * Clears memory\r\n */\r\n public destroy(): void {\r\n this.listeners.removeAll();\r\n }\r\n\r\n /**\r\n * Returns list of found items for the current search query\r\n */\r\n private get foundItems(): SearchableItem[] {\r\n return this.items.filter(item => this.checkItem(item));\r\n }\r\n\r\n /**\r\n * Contains logic for checking whether passed item conforms the search query\r\n *\r\n * @param item - item to be checked\r\n */\r\n private checkItem(item: SearchableItem): boolean {\r\n const text = item.title?.toLowerCase() || '';\r\n const query = this.searchQuery?.toLowerCase();\r\n\r\n return query !== undefined ? text.includes(query) : false;\r\n }\r\n}\r\n","import Flipper from '../../flipper';\r\nimport { PopoverAbstract } from './popover-abstract';\r\nimport type { PopoverItem, PopoverItemRenderParamsMap } from './components/popover-item';\r\nimport { PopoverItemSeparator, css as popoverItemCls } from './components/popover-item';\r\nimport type { PopoverParams } from '../../../../types/utils/popover/popover';\r\nimport { PopoverEvent } from '../../../../types/utils/popover/popover-event';\r\nimport { keyCodes } from '../../utils';\r\nimport { CSSVariables, css } from './popover.const';\r\nimport type { SearchableItem } from './components/search-input';\r\nimport { SearchInput, SearchInputEvent } from './components/search-input';\r\nimport { cacheable } from '../../utils';\r\nimport { PopoverItemDefault } from './components/popover-item';\r\nimport { PopoverItemHtml } from './components/popover-item/popover-item-html/popover-item-html';\r\n\r\n/**\r\n * Desktop popover.\r\n * On desktop devices popover behaves like a floating element. Nested popover appears at right or left side.\r\n *\r\n * @todo support rtl for nested popovers and search\r\n */\r\nexport class PopoverDesktop extends PopoverAbstract {\r\n /**\r\n * Flipper - module for keyboard iteration between elements\r\n */\r\n public flipper: Flipper | undefined;\r\n\r\n /**\r\n * Popover nesting level. 0 value means that it is a root popover\r\n */\r\n public nestingLevel = 0;\r\n\r\n /**\r\n * Reference to nested popover if exists.\r\n * Undefined by default, PopoverDesktop when exists and null after destroyed.\r\n */\r\n protected nestedPopover: PopoverDesktop | undefined | null;\r\n\r\n /**\r\n * Item nested popover is displayed for\r\n */\r\n protected nestedPopoverTriggerItem: PopoverItem | null = null;\r\n\r\n /**\r\n * Last hovered item inside popover.\r\n * Is used to determine if cursor is moving inside one item or already moved away to another one.\r\n * Helps prevent reopening nested popover while cursor is moving inside one item area.\r\n */\r\n private previouslyHoveredItem: PopoverItem | null = null;\r\n\r\n /**\r\n * Element of the page that creates 'scope' of the popover.\r\n * If possible, popover will not cross specified element's borders when opening.\r\n */\r\n private scopeElement: HTMLElement = document.body;\r\n\r\n /**\r\n * Construct the instance\r\n *\r\n * @param params - popover params\r\n * @param itemsRenderParams – popover item render params.\r\n * The parameters that are not set by user via popover api but rather depend on technical implementation\r\n */\r\n constructor(params: PopoverParams, itemsRenderParams?: PopoverItemRenderParamsMap) {\r\n super(params, itemsRenderParams);\r\n\r\n if (params.nestingLevel !== undefined) {\r\n this.nestingLevel = params.nestingLevel;\r\n }\r\n\r\n if (this.nestingLevel > 0) {\r\n this.nodes.popover.classList.add(css.popoverNested);\r\n }\r\n\r\n if (params.scopeElement !== undefined) {\r\n this.scopeElement = params.scopeElement;\r\n }\r\n\r\n if (this.nodes.popoverContainer !== null) {\r\n this.listeners.on(this.nodes.popoverContainer, 'mouseover', (event: Event) => this.handleHover(event));\r\n }\r\n\r\n if (params.searchable) {\r\n this.addSearch();\r\n }\r\n\r\n if (params.flippable !== false) {\r\n this.flipper = new Flipper({\r\n items: this.flippableElements,\r\n focusedItemClass: popoverItemCls.focused,\r\n allowedKeys: [\r\n keyCodes.TAB,\r\n keyCodes.UP,\r\n keyCodes.DOWN,\r\n keyCodes.ENTER,\r\n ],\r\n });\r\n\r\n this.flipper.onFlip(this.onFlip);\r\n }\r\n }\r\n\r\n /**\r\n * Returns true if some item inside popover is focused\r\n */\r\n public hasFocus(): boolean {\r\n if (this.flipper === undefined) {\r\n return false;\r\n }\r\n\r\n return this.flipper.hasFocus();\r\n }\r\n\r\n /**\r\n * Scroll position inside items container of the popover\r\n */\r\n public get scrollTop(): number {\r\n if (this.nodes.items === null) {\r\n return 0;\r\n }\r\n\r\n return this.nodes.items.scrollTop;\r\n }\r\n\r\n /**\r\n * Returns visible element offset top\r\n */\r\n public get offsetTop(): number {\r\n if (this.nodes.popoverContainer === null) {\r\n return 0;\r\n }\r\n\r\n return this.nodes.popoverContainer.offsetTop;\r\n }\r\n\r\n /**\r\n * Open popover\r\n */\r\n public show(): void {\r\n this.nodes.popover.style.setProperty(CSSVariables.PopoverHeight, this.size.height + 'px');\r\n\r\n if (!this.shouldOpenBottom) {\r\n this.nodes.popover.classList.add(css.popoverOpenTop);\r\n }\r\n\r\n if (!this.shouldOpenRight) {\r\n this.nodes.popover.classList.add(css.popoverOpenLeft);\r\n }\r\n\r\n super.show();\r\n this.flipper?.activate(this.flippableElements);\r\n }\r\n\r\n /**\r\n * Closes popover\r\n */\r\n public hide = (): void => {\r\n super.hide();\r\n\r\n this.destroyNestedPopoverIfExists();\r\n\r\n this.flipper?.deactivate();\r\n\r\n this.previouslyHoveredItem = null;\r\n };\r\n\r\n /**\r\n * Clears memory\r\n */\r\n public destroy(): void {\r\n this.hide();\r\n super.destroy();\r\n }\r\n\r\n /**\r\n * Handles displaying nested items for the item.\r\n *\r\n * @param item – item to show nested popover for\r\n */\r\n protected override showNestedItems(item: PopoverItem): void {\r\n if (this.nestedPopover !== null && this.nestedPopover !== undefined) {\r\n return;\r\n }\r\n\r\n this.nestedPopoverTriggerItem = item;\r\n\r\n this.showNestedPopoverForItem(item);\r\n }\r\n\r\n /**\r\n * Handles hover events inside popover items container\r\n *\r\n * @param event - hover event data\r\n */\r\n protected handleHover(event: Event): void {\r\n const item = this.getTargetItem(event);\r\n\r\n if (item === undefined) {\r\n return;\r\n }\r\n\r\n if (this.previouslyHoveredItem === item) {\r\n return;\r\n }\r\n\r\n this.destroyNestedPopoverIfExists();\r\n\r\n this.previouslyHoveredItem = item;\r\n\r\n if (!item.hasChildren) {\r\n return;\r\n }\r\n\r\n this.showNestedPopoverForItem(item);\r\n }\r\n\r\n /**\r\n * Sets CSS variable with position of item near which nested popover should be displayed.\r\n * Is used for correct positioning of the nested popover\r\n *\r\n * @param nestedPopoverEl - nested popover element\r\n * @param item – item near which nested popover should be displayed\r\n */\r\n protected setTriggerItemPosition(nestedPopoverEl: HTMLElement, item: PopoverItem): void {\r\n const itemEl = item.getElement();\r\n const itemOffsetTop = (itemEl ? itemEl.offsetTop : 0) - this.scrollTop;\r\n const topOffset = this.offsetTop + itemOffsetTop;\r\n\r\n nestedPopoverEl.style.setProperty(CSSVariables.TriggerItemTop, topOffset + 'px');\r\n }\r\n\r\n /**\r\n * Destroys existing nested popover\r\n */\r\n protected destroyNestedPopoverIfExists(): void {\r\n if (this.nestedPopover === undefined || this.nestedPopover === null) {\r\n return;\r\n }\r\n\r\n this.nestedPopover.off(PopoverEvent.ClosedOnActivate, this.hide);\r\n this.nestedPopover.hide();\r\n this.nestedPopover.destroy();\r\n this.nestedPopover.getElement().remove();\r\n this.nestedPopover = null;\r\n this.flipper?.activate(this.flippableElements);\r\n\r\n this.nestedPopoverTriggerItem?.onChildrenClose();\r\n }\r\n\r\n /**\r\n * Creates and displays nested popover for specified item.\r\n * Is used only on desktop\r\n *\r\n * @param item - item to display nested popover by\r\n */\r\n protected showNestedPopoverForItem(item: PopoverItem): PopoverDesktop {\r\n this.nestedPopover = new PopoverDesktop({\r\n searchable: item.isChildrenSearchable,\r\n items: item.children,\r\n nestingLevel: this.nestingLevel + 1,\r\n flippable: item.isChildrenFlippable,\r\n messages: this.messages,\r\n });\r\n\r\n item.onChildrenOpen();\r\n\r\n /**\r\n * Close nested popover when item with 'closeOnActivate' property set was clicked\r\n * parent popover should also be closed\r\n */\r\n this.nestedPopover.on(PopoverEvent.ClosedOnActivate, this.hide);\r\n\r\n const nestedPopoverEl = this.nestedPopover.getElement();\r\n\r\n this.nodes.popover.appendChild(nestedPopoverEl);\r\n\r\n this.setTriggerItemPosition(nestedPopoverEl, item);\r\n\r\n /* We need nesting level value in CSS to calculate offset left for nested popover */\r\n nestedPopoverEl.style.setProperty(CSSVariables.NestingLevel, this.nestedPopover.nestingLevel.toString());\r\n\r\n this.nestedPopover.show();\r\n this.flipper?.deactivate();\r\n\r\n return this.nestedPopover;\r\n }\r\n\r\n /**\r\n * Checks if popover should be opened bottom.\r\n * It should happen when there is enough space below or not enough space above\r\n */\r\n private get shouldOpenBottom(): boolean {\r\n if (this.nodes.popover === undefined || this.nodes.popover === null) {\r\n return false;\r\n }\r\n const popoverRect = this.nodes.popoverContainer.getBoundingClientRect();\r\n const scopeElementRect = this.scopeElement.getBoundingClientRect();\r\n const popoverHeight = this.size.height;\r\n const popoverPotentialBottomEdge = popoverRect.top + popoverHeight;\r\n const popoverPotentialTopEdge = popoverRect.top - popoverHeight;\r\n const bottomEdgeForComparison = Math.min(window.innerHeight, scopeElementRect.bottom);\r\n\r\n return popoverPotentialTopEdge < scopeElementRect.top || popoverPotentialBottomEdge <= bottomEdgeForComparison;\r\n }\r\n\r\n /**\r\n * Checks if popover should be opened left.\r\n * It should happen when there is enough space in the right or not enough space in the left\r\n */\r\n private get shouldOpenRight(): boolean {\r\n if (this.nodes.popover === undefined || this.nodes.popover === null) {\r\n return false;\r\n }\r\n\r\n const popoverRect = this.nodes.popover.getBoundingClientRect();\r\n const scopeElementRect = this.scopeElement.getBoundingClientRect();\r\n const popoverWidth = this.size.width;\r\n const popoverPotentialRightEdge = popoverRect.right + popoverWidth;\r\n const popoverPotentialLeftEdge = popoverRect.left - popoverWidth;\r\n const rightEdgeForComparison = Math.min(window.innerWidth, scopeElementRect.right);\r\n\r\n return popoverPotentialLeftEdge < scopeElementRect.left || popoverPotentialRightEdge <= rightEdgeForComparison;\r\n }\r\n\r\n /**\r\n * Helps to calculate size of popover that is only resolved when popover is displayed on screen.\r\n * Renders invisible clone of popover to get actual values.\r\n */\r\n @cacheable\r\n public get size(): { height: number; width: number } {\r\n const size = {\r\n height: 0,\r\n width: 0,\r\n };\r\n\r\n if (this.nodes.popover === null) {\r\n return size;\r\n }\r\n\r\n const popoverClone = this.nodes.popover.cloneNode(true) as HTMLElement;\r\n\r\n popoverClone.style.visibility = 'hidden';\r\n popoverClone.style.position = 'absolute';\r\n popoverClone.style.top = '-1000px';\r\n\r\n popoverClone.classList.add(css.popoverOpened);\r\n popoverClone.querySelector('.' + css.popoverNested)?.remove();\r\n document.body.appendChild(popoverClone);\r\n\r\n const container = popoverClone.querySelector('.' + css.popoverContainer) as HTMLElement;\r\n\r\n size.height = container.offsetHeight;\r\n size.width = container.offsetWidth;\r\n popoverClone.remove();\r\n\r\n return size;\r\n }\r\n\r\n /**\r\n * Returns list of elements available for keyboard navigation.\r\n */\r\n private get flippableElements(): HTMLElement[] {\r\n const result = this.items\r\n .map(item => {\r\n if (item instanceof PopoverItemDefault) {\r\n return item.getElement();\r\n }\r\n if (item instanceof PopoverItemHtml) {\r\n return item.getControls();\r\n }\r\n })\r\n .flat()\r\n .filter(item => item !== undefined && item !== null);\r\n\r\n return result as HTMLElement[];\r\n }\r\n\r\n /**\r\n * Called on flipper navigation\r\n */\r\n private onFlip = (): void => {\r\n const focusedItem = this.itemsDefault.find(item => item.isFocused);\r\n\r\n focusedItem?.onFocus();\r\n };\r\n\r\n /**\r\n * Adds search to the popover\r\n */\r\n private addSearch(): void {\r\n this.search = new SearchInput({\r\n items: this.itemsDefault,\r\n placeholder: this.messages.search,\r\n });\r\n\r\n this.search.on(SearchInputEvent.Search, this.onSearch);\r\n\r\n const searchElement = this.search.getElement();\r\n\r\n searchElement.classList.add(css.search);\r\n\r\n this.nodes.popoverContainer.insertBefore(searchElement, this.nodes.popoverContainer.firstChild);\r\n }\r\n\r\n /**\r\n * Handles input inside search field\r\n *\r\n * @param data - search input event data\r\n * @param data.query - search query text\r\n * @param data.result - search results\r\n */\r\n private onSearch = (data: { query: string, items: SearchableItem[] }): void => {\r\n const isEmptyQuery = data.query === '';\r\n const isNothingFound = data.items.length === 0;\r\n\r\n this.items\r\n .forEach((item) => {\r\n let isHidden = false;\r\n\r\n if (item instanceof PopoverItemDefault) {\r\n isHidden = !data.items.includes(item);\r\n } else if (item instanceof PopoverItemSeparator || item instanceof PopoverItemHtml) {\r\n /** Should hide separators if nothing found message displayed or if there is some search query applied */\r\n isHidden = isNothingFound || !isEmptyQuery;\r\n }\r\n item.toggleHidden(isHidden);\r\n });\r\n this.toggleNothingFoundMessage(isNothingFound);\r\n\r\n /** List of elements available for keyboard navigation considering search query applied */\r\n const flippableElements = data.query === '' ? this.flippableElements : data.items.map(item => (item as PopoverItem).getElement());\r\n\r\n if (this.flipper?.isActivated) {\r\n /** Update flipper items with only visible */\r\n this.flipper.deactivate();\r\n this.flipper.activate(flippableElements as HTMLElement[]);\r\n }\r\n };\r\n\r\n /**\r\n * Toggles nothing found message visibility\r\n *\r\n * @param isDisplayed - true if the message should be displayed\r\n */\r\n private toggleNothingFoundMessage(isDisplayed: boolean): void {\r\n this.nodes.nothingFoundMessage.classList.toggle(css.nothingFoundMessageDisplayed, isDisplayed);\r\n }\r\n}\r\n","import { isMobileScreen } from '../../utils';\r\nimport type { PopoverItem } from './components/popover-item';\r\nimport { PopoverItemDefault, PopoverItemType } from './components/popover-item';\r\nimport { PopoverItemHtml } from './components/popover-item/popover-item-html/popover-item-html';\r\nimport { PopoverDesktop } from './popover-desktop';\r\nimport { CSSVariables, css } from './popover.const';\r\nimport type { PopoverParams } from '../../../../types/utils/popover/popover';\r\n\r\n/**\r\n * Horizontal popover that is displayed inline with the content\r\n */\r\nexport class PopoverInline extends PopoverDesktop {\r\n /**\r\n * Constructs the instance\r\n *\r\n * @param params - instance parameters\r\n */\r\n constructor(params: PopoverParams) {\r\n const isHintEnabled = !isMobileScreen();\r\n\r\n super(\r\n {\r\n ...params,\r\n class: css.popoverInline,\r\n },\r\n {\r\n [PopoverItemType.Default]: {\r\n /**\r\n * We use button instead of div here to fix bug associated with focus loss (which leads to selection change) on click in safari\r\n *\r\n * @todo figure out better way to solve the issue\r\n */\r\n wrapperTag: 'button',\r\n hint: {\r\n position: 'top',\r\n alignment: 'center',\r\n enabled: isHintEnabled,\r\n },\r\n },\r\n [PopoverItemType.Html]: {\r\n hint: {\r\n position: 'top',\r\n alignment: 'center',\r\n enabled: isHintEnabled,\r\n },\r\n },\r\n }\r\n );\r\n\r\n /**\r\n * If active popover item has children, show them.\r\n * This is needed to display link url text (which is displayed as a nested popover content)\r\n * once you select <a> tag content in text\r\n */\r\n this.items\r\n .forEach((item) => {\r\n if (!(item instanceof PopoverItemDefault) && !(item instanceof PopoverItemHtml)) {\r\n return;\r\n }\r\n\r\n if (item.hasChildren && item.isChildrenOpen) {\r\n this.showNestedItems(item);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Returns visible element offset top\r\n */\r\n public get offsetLeft(): number {\r\n if (this.nodes.popoverContainer === null) {\r\n return 0;\r\n }\r\n\r\n return this.nodes.popoverContainer.offsetLeft;\r\n }\r\n\r\n /**\r\n * Open popover\r\n */\r\n public override show(): void {\r\n /**\r\n * If this is not a nested popover, set CSS variable with width of the popover\r\n */\r\n if (this.nestingLevel === 0) {\r\n this.nodes.popover.style.setProperty(\r\n CSSVariables.InlinePopoverWidth,\r\n this.size.width + 'px'\r\n );\r\n }\r\n super.show();\r\n }\r\n\r\n /**\r\n * Disable hover event handling.\r\n * Overrides parent's class behavior\r\n */\r\n protected override handleHover(): void {\r\n return;\r\n }\r\n\r\n /**\r\n * Sets CSS variable with position of item near which nested popover should be displayed.\r\n * Is used to position nested popover right below clicked item\r\n *\r\n * @param nestedPopoverEl - nested popover element\r\n * @param item – item near which nested popover should be displayed\r\n */\r\n protected override setTriggerItemPosition(\r\n nestedPopoverEl: HTMLElement,\r\n item: PopoverItemDefault\r\n ): void {\r\n const itemEl = item.getElement();\r\n const itemOffsetLeft = itemEl ? itemEl.offsetLeft : 0;\r\n const totalLeftOffset = this.offsetLeft + itemOffsetLeft;\r\n\r\n nestedPopoverEl.style.setProperty(\r\n CSSVariables.TriggerItemLeft,\r\n totalLeftOffset + 'px'\r\n );\r\n }\r\n\r\n /**\r\n * Handles displaying nested items for the item.\r\n * Overriding in order to add toggling behaviour\r\n *\r\n * @param item – item to toggle nested popover for\r\n */\r\n protected override showNestedItems(item: PopoverItemDefault | PopoverItemHtml): void {\r\n if (this.nestedPopoverTriggerItem === item) {\r\n this.destroyNestedPopoverIfExists();\r\n\r\n this.nestedPopoverTriggerItem = null;\r\n\r\n return;\r\n }\r\n\r\n super.showNestedItems(item);\r\n }\r\n\r\n /**\r\n * Creates and displays nested popover for specified item.\r\n * Is used only on desktop\r\n *\r\n * @param item - item to display nested popover by\r\n */\r\n protected showNestedPopoverForItem(item: PopoverItem): PopoverDesktop {\r\n const nestedPopover = super.showNestedPopoverForItem(item);\r\n const nestedPopoverEl = nestedPopover.getElement();\r\n\r\n /**\r\n * We need to add class with nesting level, shich will help position nested popover.\r\n * Currently only '.ce-popover--nested-level-1' class is used\r\n */\r\n nestedPopoverEl.classList.add(css.getPopoverNestedClass(nestedPopover.nestingLevel));\r\n\r\n return nestedPopover;\r\n }\r\n\r\n /**\r\n * Overrides default item click handling.\r\n * Helps to close nested popover once other item is clicked.\r\n *\r\n * @param item - clicked item\r\n */\r\n protected override handleItemClick(item: PopoverItem): void {\r\n if (item !== this.nestedPopoverTriggerItem) {\r\n /**\r\n * In case tool had special handling for toggling button (like link tool which modifies selection)\r\n * we need to call handleClick on nested popover trigger item\r\n */\r\n this.nestedPopoverTriggerItem?.handleClick();\r\n\r\n /**\r\n * Then close the nested popover\r\n */\r\n super.destroyNestedPopoverIfExists();\r\n }\r\n\r\n super.handleItemClick(item);\r\n }\r\n}\r\n","import { isIosDevice } from '../utils';\r\n\r\n/**\r\n * Utility allowing to lock body scroll on demand\r\n */\r\nexport default class ScrollLocker {\r\n /**\r\n * Style classes\r\n */\r\n private static CSS = {\r\n scrollLocked: 'ce-scroll-locked',\r\n scrollLockedHard: 'ce-scroll-locked--hard',\r\n };\r\n\r\n /**\r\n * Stores scroll position, used for hard scroll lock\r\n */\r\n private scrollPosition: null | number = null;\r\n\r\n /**\r\n * Locks body element scroll\r\n */\r\n public lock(): void {\r\n if (isIosDevice) {\r\n this.lockHard();\r\n } else {\r\n document.body.classList.add(ScrollLocker.CSS.scrollLocked);\r\n }\r\n }\r\n\r\n /**\r\n * Unlocks body element scroll\r\n */\r\n public unlock(): void {\r\n if (isIosDevice) {\r\n this.unlockHard();\r\n } else {\r\n document.body.classList.remove(ScrollLocker.CSS.scrollLocked);\r\n }\r\n }\r\n\r\n /**\r\n * Locks scroll in a hard way (via setting fixed position to body element)\r\n */\r\n private lockHard(): void {\r\n this.scrollPosition = window.pageYOffset;\r\n document.documentElement.style.setProperty(\r\n '--window-scroll-offset',\r\n `${this.scrollPosition}px`\r\n );\r\n document.body.classList.add(ScrollLocker.CSS.scrollLockedHard);\r\n }\r\n\r\n /**\r\n * Unlocks hard scroll lock\r\n */\r\n private unlockHard(): void {\r\n document.body.classList.remove(ScrollLocker.CSS.scrollLockedHard);\r\n if (this.scrollPosition !== null) {\r\n window.scrollTo(0, this.scrollPosition);\r\n }\r\n this.scrollPosition = null;\r\n }\r\n}\r\n","import { bem } from '../../../bem';\r\n\r\n/**\r\n * Popover header block CSS class constructor\r\n */\r\nconst className = bem('ce-popover-header');\r\n\r\n/**\r\n * CSS class names to be used in popover header class\r\n */\r\nexport const css = {\r\n root: className(),\r\n text: className('text'),\r\n backButton: className('back-button'),\r\n};\r\n","import type { PopoverHeaderParams } from './popover-header.types';\r\nimport Dom from '../../../../dom';\r\nimport { css } from './popover-header.const';\r\nimport { IconChevronLeft } from '@codexteam/icons';\r\nimport Listeners from '../../../listeners';\r\n\r\n/**\r\n * Represents popover header ui element\r\n */\r\nexport class PopoverHeader {\r\n /**\r\n * Listeners util instance\r\n */\r\n private listeners = new Listeners();\r\n\r\n /**\r\n * Header html elements\r\n */\r\n private nodes: {\r\n root: HTMLElement,\r\n text: HTMLElement,\r\n backButton: HTMLElement\r\n };\r\n\r\n /**\r\n * Text displayed inside header\r\n */\r\n private readonly text: string;\r\n\r\n /**\r\n * Back button click handler\r\n */\r\n private readonly onBackButtonClick: () => void;\r\n\r\n /**\r\n * Constructs the instance\r\n *\r\n * @param params - popover header params\r\n */\r\n constructor({ text, onBackButtonClick }: PopoverHeaderParams) {\r\n this.text = text;\r\n this.onBackButtonClick = onBackButtonClick;\r\n\r\n this.nodes = {\r\n root: Dom.make('div', [ css.root ]),\r\n backButton: Dom.make('button', [ css.backButton ]),\r\n text: Dom.make('div', [ css.text ]),\r\n };\r\n this.nodes.backButton.innerHTML = IconChevronLeft;\r\n this.nodes.root.appendChild(this.nodes.backButton);\r\n this.listeners.on(this.nodes.backButton, 'click', this.onBackButtonClick);\r\n\r\n this.nodes.text.innerText = this.text;\r\n this.nodes.root.appendChild(this.nodes.text);\r\n }\r\n\r\n /**\r\n * Returns popover header root html element\r\n */\r\n public getElement(): HTMLElement | null {\r\n return this.nodes.root;\r\n }\r\n\r\n /**\r\n * Destroys the instance\r\n */\r\n public destroy(): void {\r\n this.nodes.root.remove();\r\n this.listeners.destroy();\r\n }\r\n}\r\n","import type { PopoverItemParams } from '../../../../../types/utils/popover/popover-item';\r\n\r\n/**\r\n * Represents single states history item\r\n */\r\ninterface PopoverStatesHistoryItem {\r\n /**\r\n * Popover title\r\n */\r\n title?: string;\r\n\r\n /**\r\n * Popover items\r\n */\r\n items: PopoverItemParams[]\r\n}\r\n\r\n/**\r\n * Manages items history inside popover. Allows to navigate back in history\r\n */\r\nexport class PopoverStatesHistory {\r\n /**\r\n * Previous items states\r\n */\r\n private history: PopoverStatesHistoryItem[] = [];\r\n\r\n /**\r\n * Push new popover state\r\n *\r\n * @param state - new state\r\n */\r\n public push(state: PopoverStatesHistoryItem): void {\r\n this.history.push(state);\r\n }\r\n\r\n /**\r\n * Pop last popover state\r\n */\r\n public pop(): PopoverStatesHistoryItem | undefined {\r\n return this.history.pop();\r\n }\r\n\r\n /**\r\n * Title retrieved from the current state\r\n */\r\n public get currentTitle(): string | undefined {\r\n if (this.history.length === 0) {\r\n return '';\r\n }\r\n\r\n return this.history[this.history.length - 1].title;\r\n }\r\n\r\n /**\r\n * Items list retrieved from the current state\r\n */\r\n public get currentItems(): PopoverItemParams[] {\r\n if (this.history.length === 0) {\r\n return [];\r\n }\r\n\r\n return this.history[this.history.length - 1].items;\r\n }\r\n\r\n /**\r\n * Returns history to initial popover state\r\n */\r\n public reset(): void {\r\n while (this.history.length > 1) {\r\n this.pop();\r\n }\r\n }\r\n}\r\n","import { PopoverAbstract } from './popover-abstract';\r\nimport ScrollLocker from '../scroll-locker';\r\nimport { PopoverHeader } from './components/popover-header';\r\nimport { PopoverStatesHistory } from './utils/popover-states-history';\r\nimport type { PopoverMobileNodes, PopoverParams } from '../../../../types/utils/popover/popover';\r\nimport type { PopoverItemDefault, PopoverItemParams } from './components/popover-item';\r\nimport { PopoverItemType } from './components/popover-item';\r\nimport { css } from './popover.const';\r\nimport Dom from '../../dom';\r\n\r\n\r\n/**\r\n * Mobile Popover.\r\n * On mobile devices Popover behaves like a fixed panel at the bottom of screen. Nested item appears like \"pages\" with the \"back\" button\r\n */\r\nexport class PopoverMobile extends PopoverAbstract<PopoverMobileNodes> {\r\n /**\r\n * ScrollLocker instance\r\n */\r\n private scrollLocker = new ScrollLocker();\r\n\r\n /**\r\n * Reference to popover header if exists\r\n */\r\n private header: PopoverHeader | undefined | null;\r\n\r\n /**\r\n * History of popover states for back navigation.\r\n * Is used for mobile version of popover,\r\n * where we can not display nested popover of the screen and\r\n * have to render nested items in the same popover switching to new state\r\n */\r\n private history = new PopoverStatesHistory();\r\n\r\n /**\r\n * Flag that indicates if popover is hidden\r\n */\r\n private isHidden = true;\r\n\r\n /**\r\n * Construct the instance\r\n *\r\n * @param params - popover params\r\n */\r\n constructor(params: PopoverParams) {\r\n super(params, {\r\n [PopoverItemType.Default]: {\r\n hint: {\r\n enabled: false,\r\n },\r\n },\r\n [PopoverItemType.Html]: {\r\n hint: {\r\n enabled: false,\r\n },\r\n },\r\n });\r\n\r\n this.nodes.overlay = Dom.make('div', [css.overlay, css.overlayHidden]);\r\n this.nodes.popover.insertBefore(this.nodes.overlay, this.nodes.popover.firstChild);\r\n\r\n this.listeners.on(this.nodes.overlay, 'click', () => {\r\n this.hide();\r\n });\r\n\r\n /* Save state to history for proper navigation between nested and parent popovers */\r\n this.history.push({ items: params.items });\r\n }\r\n\r\n /**\r\n * Open popover\r\n */\r\n public show(): void {\r\n this.nodes.overlay.classList.remove(css.overlayHidden);\r\n\r\n super.show();\r\n\r\n this.scrollLocker.lock();\r\n\r\n this.isHidden = false;\r\n }\r\n\r\n /**\r\n * Closes popover\r\n */\r\n public hide(): void {\r\n if (this.isHidden) {\r\n return;\r\n }\r\n\r\n super.hide();\r\n this.nodes.overlay.classList.add(css.overlayHidden);\r\n\r\n this.scrollLocker.unlock();\r\n\r\n this.history.reset();\r\n\r\n this.isHidden = true;\r\n }\r\n\r\n /**\r\n * Clears memory\r\n */\r\n public destroy(): void {\r\n super.destroy();\r\n\r\n this.scrollLocker.unlock();\r\n }\r\n\r\n /**\r\n * Handles displaying nested items for the item\r\n *\r\n * @param item – item to show nested popover for\r\n */\r\n protected override showNestedItems(item: PopoverItemDefault): void {\r\n /** Show nested items */\r\n this.updateItemsAndHeader(item.children, item.title);\r\n\r\n this.history.push({\r\n title: item.title,\r\n items: item.children,\r\n });\r\n }\r\n\r\n /**\r\n * Removes rendered popover items and header and displays new ones\r\n *\r\n * @param items - new popover items\r\n * @param title - new popover header text\r\n */\r\n private updateItemsAndHeader(items: PopoverItemParams[], title?: string ): void {\r\n /** Re-render header */\r\n if (this.header !== null && this.header !== undefined) {\r\n this.header.destroy();\r\n this.header = null;\r\n }\r\n if (title !== undefined) {\r\n this.header = new PopoverHeader({\r\n text: title,\r\n onBackButtonClick: () => {\r\n this.history.pop();\r\n\r\n this.updateItemsAndHeader(this.history.currentItems, this.history.currentTitle);\r\n },\r\n });\r\n const headerEl = this.header.getElement();\r\n\r\n if (headerEl !== null) {\r\n this.nodes.popoverContainer.insertBefore(headerEl, this.nodes.popoverContainer.firstChild);\r\n }\r\n }\r\n\r\n /** Re-render items */\r\n this.items.forEach(item => item.getElement()?.remove());\r\n\r\n this.items = this.buildItems(items);\r\n\r\n this.items.forEach(item => {\r\n const itemEl = item.getElement();\r\n\r\n if (itemEl === null) {\r\n return;\r\n }\r\n this.nodes.items?.appendChild(itemEl);\r\n });\r\n }\r\n}\r\n","import Module from '../../__module';\r\nimport $ from '../../dom';\r\nimport SelectionUtils from '../../selection';\r\nimport type Block from '../../block';\r\nimport I18n from '../../i18n';\r\nimport { I18nInternalNS } from '../../i18n/namespace-internal';\r\nimport type Flipper from '../../flipper';\r\nimport type { MenuConfigItem } from '../../../../types/tools';\r\nimport { resolveAliases } from '../../utils/resolve-aliases';\r\nimport type { PopoverItemParams } from '../../utils/popover';\r\nimport { type Popover, PopoverDesktop, PopoverMobile, PopoverItemType } from '../../utils/popover';\r\nimport { PopoverEvent } from '../../../../types/utils/popover/popover-event';\r\nimport { isMobileScreen } from '../../utils';\r\nimport { EditorMobileLayoutToggled } from '../../events';\r\nimport { IconReplace } from '@codexteam/icons';\r\nimport { getConvertibleToolsForBlock } from '../../utils/blocks';\r\n\r\n/**\r\n * HTML Elements that used for BlockSettings\r\n */\r\ninterface BlockSettingsNodes {\r\n /**\r\n * Block Settings wrapper. Undefined when before \"make\" method called\r\n */\r\n wrapper: HTMLElement | undefined;\r\n}\r\n\r\n/**\r\n * Block Settings\r\n *\r\n * @todo Make Block Settings no-module but a standalone class, like Toolbox\r\n */\r\nexport default class BlockSettings extends Module<BlockSettingsNodes> {\r\n /**\r\n * Module Events\r\n */\r\n public get events(): { opened: string; closed: string } {\r\n return {\r\n opened: 'block-settings-opened',\r\n closed: 'block-settings-closed',\r\n };\r\n }\r\n\r\n /**\r\n * Block Settings CSS\r\n */\r\n public get CSS(): { [name: string]: string } {\r\n return {\r\n settings: 'ce-settings',\r\n };\r\n }\r\n\r\n /**\r\n * Opened state\r\n */\r\n public opened = false;\r\n\r\n /**\r\n * Getter for inner popover's flipper instance\r\n *\r\n * @todo remove once BlockSettings becomes standalone non-module class\r\n */\r\n public get flipper(): Flipper | undefined {\r\n if (this.popover === null) {\r\n return;\r\n }\r\n\r\n return 'flipper' in this.popover ? this.popover?.flipper : undefined;\r\n }\r\n\r\n /**\r\n * Page selection utils\r\n */\r\n private selection: SelectionUtils = new SelectionUtils();\r\n\r\n /**\r\n * Popover instance. There is a util for vertical lists.\r\n * Null until popover is not initialized\r\n */\r\n private popover: Popover | null = null;\r\n\r\n /**\r\n * Panel with block settings with 2 sections:\r\n * - Tool's Settings\r\n * - Default Settings [Move, Remove, etc]\r\n */\r\n public make(): void {\r\n this.nodes.wrapper = $.make('div', [ this.CSS.settings ]);\r\n\r\n if (import.meta.env.MODE === 'test') {\r\n this.nodes.wrapper.setAttribute('data-cy', 'block-tunes');\r\n }\r\n\r\n this.eventsDispatcher.on(EditorMobileLayoutToggled, this.close);\r\n }\r\n\r\n /**\r\n * Destroys module\r\n */\r\n public destroy(): void {\r\n this.removeAllNodes();\r\n this.listeners.destroy();\r\n this.eventsDispatcher.off(EditorMobileLayoutToggled, this.close);\r\n }\r\n\r\n /**\r\n * Open Block Settings pane\r\n *\r\n * @param targetBlock - near which Block we should open BlockSettings\r\n */\r\n public async open(targetBlock: Block = this.Editor.BlockManager.currentBlock): Promise<void> {\r\n this.opened = true;\r\n\r\n /**\r\n * If block settings contains any inputs, focus will be set there,\r\n * so we need to save current selection to restore it after block settings is closed\r\n */\r\n this.selection.save();\r\n\r\n /**\r\n * Highlight content of a Block we are working with\r\n */\r\n this.Editor.BlockSelection.selectBlock(targetBlock);\r\n this.Editor.BlockSelection.clearCache();\r\n\r\n /** Get tool's settings data */\r\n const { toolTunes, commonTunes } = targetBlock.getTunes();\r\n\r\n /** Tell to subscribers that block settings is opened */\r\n this.eventsDispatcher.emit(this.events.opened);\r\n\r\n const PopoverClass = isMobileScreen() ? PopoverMobile : PopoverDesktop;\r\n\r\n this.popover = new PopoverClass({\r\n searchable: false, //lrj:关闭搜索功能\r\n items: await this.getTunesItems(targetBlock, commonTunes, toolTunes),\r\n scopeElement: this.Editor.API.methods.ui.nodes.redactor,\r\n messages: {\r\n nothingFound: I18n.ui(I18nInternalNS.ui.popover, 'Nothing found'),\r\n search: I18n.ui(I18nInternalNS.ui.popover, 'Filter'),\r\n },\r\n });\r\n\r\n this.popover.on(PopoverEvent.Closed, this.onPopoverClose);\r\n\r\n this.nodes.wrapper?.append(this.popover.getElement());\r\n\r\n this.popover.show();\r\n }\r\n\r\n /**\r\n * Returns root block settings element\r\n */\r\n public getElement(): HTMLElement | undefined {\r\n return this.nodes.wrapper;\r\n }\r\n\r\n /**\r\n * Close Block Settings pane\r\n */\r\n public close = (): void => {\r\n if (!this.opened) {\r\n return;\r\n }\r\n\r\n this.opened = false;\r\n\r\n /**\r\n * If selection is at editor on Block Settings closing,\r\n * it means that caret placed at some editable element inside the Block Settings.\r\n * Previously we have saved the selection, then open the Block Settings and set caret to the input\r\n *\r\n * So, we need to restore selection back to Block after closing the Block Settings\r\n */\r\n if (!SelectionUtils.isAtEditor) {\r\n this.selection.restore();\r\n }\r\n\r\n this.selection.clearSaved();\r\n\r\n /**\r\n * Remove highlighted content of a Block we are working with\r\n */\r\n if (!this.Editor.CrossBlockSelection.isCrossBlockSelectionStarted && this.Editor.BlockManager.currentBlock) {\r\n this.Editor.BlockSelection.unselectBlock(this.Editor.BlockManager.currentBlock);\r\n }\r\n\r\n /** Tell to subscribers that block settings is closed */\r\n this.eventsDispatcher.emit(this.events.closed);\r\n\r\n if (this.popover) {\r\n this.popover.off(PopoverEvent.Closed, this.onPopoverClose);\r\n this.popover.destroy();\r\n this.popover.getElement().remove();\r\n this.popover = null;\r\n }\r\n };\r\n\r\n /**\r\n * Returns list of items to be displayed in block tunes menu.\r\n * Merges tool specific tunes, conversion menu and common tunes in one list in predefined order\r\n *\r\n * @param currentBlock – block we are about to open block tunes for\r\n * @param commonTunes – common tunes\r\n * @param toolTunes - tool specific tunes\r\n */\r\n private async getTunesItems(currentBlock: Block, commonTunes: MenuConfigItem[], toolTunes?: MenuConfigItem[]): Promise<PopoverItemParams[]> {\r\n const items = [] as MenuConfigItem[];\r\n\r\n if (toolTunes !== undefined && toolTunes.length > 0) {\r\n items.push(...toolTunes);\r\n items.push({\r\n type: PopoverItemType.Separator,\r\n });\r\n }\r\n\r\n const allBlockTools = Array.from(this.Editor.Tools.blockTools.values());\r\n const convertibleTools = await getConvertibleToolsForBlock(currentBlock, allBlockTools);\r\n const convertToItems = convertibleTools.reduce((result, tool) => {\r\n tool.toolbox.forEach((toolboxItem) => {\r\n result.push({\r\n icon: toolboxItem.icon,\r\n title: I18n.t(I18nInternalNS.toolNames, toolboxItem.title),\r\n name: tool.name,\r\n //lrj\r\n hint: {\r\n title: I18n.t(I18nInternalNS.toolNames, toolboxItem.title)\r\n },\r\n closeOnActivate: true,\r\n onActivate: async () => {\r\n const { BlockManager, Caret, Toolbar } = this.Editor;\r\n\r\n const newBlock = await BlockManager.convert(currentBlock, tool.name, toolboxItem.data);\r\n\r\n Toolbar.close();\r\n\r\n Caret.setToBlock(newBlock, Caret.positions.END);\r\n },\r\n });\r\n });\r\n\r\n return result;\r\n }, []);\r\n\r\n if (convertToItems.length > 0) {\r\n items.push({\r\n icon: IconReplace,\r\n name: 'convert-to',\r\n title: I18n.ui(I18nInternalNS.ui.popover, 'Convert to'),\r\n children: {\r\n searchable: false, //lrj:关闭搜索功能\r\n items: convertToItems,\r\n },\r\n });\r\n items.push({\r\n type: PopoverItemType.Separator,\r\n });\r\n }\r\n\r\n items.push(...commonTunes);\r\n\r\n return items.map(tune => this.resolveTuneAliases(tune));\r\n }\r\n\r\n /**\r\n * Handles popover close event\r\n */\r\n private onPopoverClose = (): void => {\r\n this.close();\r\n };\r\n\r\n /**\r\n * Resolves aliases in tunes menu items\r\n *\r\n * @param item - item with resolved aliases\r\n */\r\n private resolveTuneAliases(item: MenuConfigItem): PopoverItemParams {\r\n if (item.type === PopoverItemType.Separator || item.type === PopoverItemType.Html) {\r\n return item;\r\n }\r\n const result = resolveAliases(item, { label: 'title' });\r\n\r\n if (item.confirmation) {\r\n result.confirmation = this.resolveTuneAliases(item.confirmation);\r\n }\r\n\r\n return result;\r\n }\r\n}\r\n","/*!\n * Library for handling keyboard shortcuts\n * @copyright CodeX (https://codex.so)\n * @license MIT\n * @author CodeX (https://codex.so)\n * @version 1.2.0\n */\n!function(e,t){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define([],t):\"object\"==typeof exports?exports.Shortcut=t():e.Shortcut=t()}(window,function(){return function(n){var r={};function o(e){if(r[e])return r[e].exports;var t=r[e]={i:e,l:!1,exports:{}};return n[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}return o.m=n,o.c=r,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},o.r=function(e){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&\"object\"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,\"default\",{enumerable:!0,value:t}),2&e&&\"string\"!=typeof t)for(var r in t)o.d(n,r,function(e){return t[e]}.bind(null,r));return n},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,\"a\",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p=\"\",o(o.s=0)}([function(e,t,n){\"use strict\";function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function o(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}n.r(t);var u=function(){function i(e){var t=this;!function(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}(this,i),this.commands={},this.keys={},this.name=e.name,this.parseShortcutName(e.name),this.element=e.on,this.callback=e.callback,this.executeShortcut=function(e){t.execute(e)},this.element.addEventListener(\"keydown\",this.executeShortcut,!1)}return o(i,null,[{key:\"supportedCommands\",get:function(){return{SHIFT:[\"SHIFT\"],CMD:[\"CMD\",\"CONTROL\",\"COMMAND\",\"WINDOWS\",\"CTRL\"],ALT:[\"ALT\",\"OPTION\"]}}},{key:\"keyCodes\",get:function(){return{0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,BACKSPACE:8,ENTER:13,ESCAPE:27,LEFT:37,UP:38,RIGHT:39,DOWN:40,INSERT:45,DELETE:46,\".\":190}}}]),o(i,[{key:\"parseShortcutName\",value:function(e){e=e.split(\"+\");for(var t=0;t<e.length;t++){e[t]=e[t].toUpperCase();var n=!1;for(var r in i.supportedCommands)if(i.supportedCommands[r].includes(e[t])){n=this.commands[r]=!0;break}n||(this.keys[e[t]]=!0)}for(var o in i.supportedCommands)this.commands[o]||(this.commands[o]=!1)}},{key:\"execute\",value:function(e){var t,n={CMD:e.ctrlKey||e.metaKey,SHIFT:e.shiftKey,ALT:e.altKey},r=!0;for(t in this.commands)this.commands[t]!==n[t]&&(r=!1);var o,u=!0;for(o in this.keys)u=u&&e.keyCode===i.keyCodes[o];r&&u&&this.callback(e)}},{key:\"remove\",value:function(){this.element.removeEventListener(\"keydown\",this.executeShortcut)}}]),i}();t.default=u}]).default});","import Shortcut from '@codexteam/shortcuts';\r\n\r\n/**\r\n * Contains keyboard and mouse events binded on each Block by Block Manager\r\n */\r\n\r\n/**\r\n * ShortcutData interface\r\n * Each shortcut must have name and handler\r\n * `name` is a shortcut, like 'CMD+K', 'CMD+B' etc\r\n * `handler` is a callback\r\n *\r\n * @interface ShortcutData\r\n */\r\nexport interface ShortcutData {\r\n\r\n /**\r\n * Shortcut name\r\n * Ex. CMD+I, CMD+B ....\r\n */\r\n name: string;\r\n\r\n /**\r\n * Shortcut handler\r\n */\r\n handler(event): void;\r\n\r\n /**\r\n * Element handler should be added for\r\n */\r\n on: HTMLElement | Document;\r\n}\r\n\r\n/**\r\n * @class Shortcut\r\n * @classdesc Allows to register new shortcut\r\n *\r\n * Internal Shortcuts Module\r\n */\r\nclass Shortcuts {\r\n /**\r\n * All registered shortcuts\r\n *\r\n * @type {Map<Element, Shortcut[]>}\r\n */\r\n private registeredShortcuts: Map<Element, Shortcut[]> = new Map();\r\n\r\n /**\r\n * Register shortcut\r\n *\r\n * @param shortcut - shortcut options\r\n */\r\n public add(shortcut: ShortcutData): void {\r\n const foundShortcut = this.findShortcut(shortcut.on, shortcut.name);\r\n\r\n if (foundShortcut) {\r\n throw Error(\r\n `Shortcut ${shortcut.name} is already registered for ${shortcut.on}. Please remove it before add a new handler.`\r\n );\r\n }\r\n\r\n const newShortcut = new Shortcut({\r\n name: shortcut.name,\r\n on: shortcut.on,\r\n callback: shortcut.handler,\r\n });\r\n const shortcuts = this.registeredShortcuts.get(shortcut.on) || [];\r\n\r\n this.registeredShortcuts.set(shortcut.on, [...shortcuts, newShortcut]);\r\n }\r\n\r\n /**\r\n * Remove shortcut\r\n *\r\n * @param element - Element shortcut is set for\r\n * @param name - shortcut name\r\n */\r\n public remove(element: Element, name: string): void {\r\n const shortcut = this.findShortcut(element, name);\r\n\r\n if (!shortcut) {\r\n return;\r\n }\r\n\r\n shortcut.remove();\r\n\r\n const shortcuts = this.registeredShortcuts.get(element);\r\n\r\n const filteredShortcuts = shortcuts.filter(el => el !== shortcut);\r\n\r\n if (filteredShortcuts.length === 0) {\r\n this.registeredShortcuts.delete(element);\r\n\r\n return;\r\n }\r\n\r\n this.registeredShortcuts.set(element, filteredShortcuts);\r\n }\r\n\r\n /**\r\n * Get Shortcut instance if exist\r\n *\r\n * @param element - Element shorcut is set for\r\n * @param shortcut - shortcut name\r\n * @returns {number} index - shortcut index if exist\r\n */\r\n private findShortcut(element: Element, shortcut: string): Shortcut | void {\r\n const shortcuts = this.registeredShortcuts.get(element) || [];\r\n\r\n return shortcuts.find(({ name }) => name === shortcut);\r\n }\r\n}\r\n\r\nexport default new Shortcuts();\r\n","import * as _ from '../utils';\r\nimport { BlockToolAPI } from '../block';\r\nimport Shortcuts from '../utils/shortcuts';\r\nimport type BlockToolAdapter from '../tools/block';\r\nimport type ToolsCollection from '../tools/collection';\r\nimport type { API, BlockToolData, ToolboxConfigEntry, PopoverItemParams, BlockAPI } from '../../../types';\r\nimport EventsDispatcher from '../utils/events';\r\nimport I18n from '../i18n';\r\nimport { I18nInternalNS } from '../i18n/namespace-internal';\r\nimport { PopoverEvent } from '../../../types/utils/popover/popover-event';\r\nimport Listeners from '../utils/listeners';\r\nimport Dom from '../dom';\r\nimport type { Popover } from '../utils/popover';\r\nimport { PopoverDesktop, PopoverMobile } from '../utils/popover';\r\nimport { EditorMobileLayoutToggled } from '../events';\r\n\r\n/**\r\n * @todo the first Tab on the Block — focus Plus Button, the second — focus Block Tunes Toggler, the third — focus next Block\r\n */\r\n\r\n/**\r\n * Event that can be triggered by the Toolbox\r\n */\r\nexport enum ToolboxEvent {\r\n /**\r\n * When the Toolbox is opened\r\n */\r\n Opened = 'toolbox-opened',\r\n\r\n /**\r\n * When the Toolbox is closed\r\n */\r\n Closed = 'toolbox-closed',\r\n\r\n /**\r\n * When the new Block added by Toolbox\r\n */\r\n BlockAdded = 'toolbox-block-added',\r\n}\r\n\r\n/**\r\n * Events fired by the Toolbox\r\n *\r\n * Event name -> payload\r\n */\r\nexport interface ToolboxEventMap {\r\n [ToolboxEvent.Opened]: undefined;\r\n [ToolboxEvent.Closed]: undefined;\r\n [ToolboxEvent.BlockAdded]: {\r\n block: BlockAPI\r\n };\r\n}\r\n\r\n/**\r\n * Available i18n dict keys that should be passed to the constructor\r\n */\r\ntype ToolboxTextLabelsKeys = 'filter' | 'nothingFound';\r\n\r\n/**\r\n * Toolbox\r\n * This UI element contains list of Block Tools available to be inserted\r\n * It appears after click on the Plus Button\r\n *\r\n * @implements {EventsDispatcher} with some events, see {@link ToolboxEvent}\r\n */\r\nexport default class Toolbox extends EventsDispatcher<ToolboxEventMap> {\r\n /**\r\n * Returns True if Toolbox is Empty and nothing to show\r\n *\r\n * @returns {boolean}\r\n */\r\n public get isEmpty(): boolean {\r\n return this.toolsToBeDisplayed.length === 0;\r\n }\r\n\r\n /**\r\n * Opening state\r\n *\r\n * @type {boolean}\r\n */\r\n public opened = false;\r\n\r\n /**\r\n * Listeners util instance\r\n */\r\n protected listeners: Listeners = new Listeners();\r\n\r\n /**\r\n * Editor API\r\n */\r\n private api: API;\r\n\r\n /**\r\n * Popover instance. There is a util for vertical lists.\r\n * Null until initialized\r\n */\r\n private popover: Popover | null = null;\r\n\r\n /**\r\n * List of Tools available. Some of them will be shown in the Toolbox\r\n */\r\n private tools: ToolsCollection<BlockToolAdapter>;\r\n\r\n /**\r\n * Text labels used in the Toolbox. Should be passed from the i18n module\r\n */\r\n private i18nLabels: Record<ToolboxTextLabelsKeys, string>;\r\n\r\n /**\r\n * Current module HTML Elements\r\n */\r\n private nodes: {\r\n toolbox: HTMLElement;\r\n } ;\r\n\r\n /**\r\n * CSS styles\r\n */\r\n private static get CSS(): {\r\n toolbox: string;\r\n } {\r\n return {\r\n toolbox: 'ce-toolbox',\r\n };\r\n }\r\n\r\n /**\r\n * Toolbox constructor\r\n *\r\n * @param options - available parameters\r\n * @param options.api - Editor API methods\r\n * @param options.tools - Tools available to check whether some of them should be displayed at the Toolbox or not\r\n */\r\n constructor({ api, tools, i18nLabels }: {api: API; tools: ToolsCollection<BlockToolAdapter>; i18nLabels: Record<ToolboxTextLabelsKeys, string>}) {\r\n super();\r\n\r\n this.api = api;\r\n this.tools = tools;\r\n this.i18nLabels = i18nLabels;\r\n\r\n this.enableShortcuts();\r\n\r\n this.nodes = {\r\n toolbox: Dom.make('div', Toolbox.CSS.toolbox),\r\n };\r\n\r\n this.initPopover();\r\n\r\n if (import.meta.env.MODE === 'test') {\r\n this.nodes.toolbox.setAttribute('data-cy', 'toolbox');\r\n }\r\n\r\n this.api.events.on(EditorMobileLayoutToggled, this.handleMobileLayoutToggle);\r\n }\r\n\r\n /**\r\n * Returns root block settings element\r\n */\r\n public getElement(): HTMLElement | null {\r\n return this.nodes.toolbox;\r\n }\r\n\r\n /**\r\n * Returns true if the Toolbox has the Flipper activated and the Flipper has selected button\r\n */\r\n public hasFocus(): boolean | undefined {\r\n if (this.popover === null) {\r\n return;\r\n }\r\n\r\n return 'hasFocus' in this.popover ? this.popover.hasFocus() : undefined;\r\n }\r\n\r\n /**\r\n * Destroy Module\r\n */\r\n public destroy(): void {\r\n super.destroy();\r\n\r\n if (this.nodes && this.nodes.toolbox) {\r\n this.nodes.toolbox.remove();\r\n }\r\n\r\n this.removeAllShortcuts();\r\n this.popover?.off(PopoverEvent.Closed, this.onPopoverClose);\r\n this.listeners.destroy();\r\n this.api.events.off(EditorMobileLayoutToggled, this.handleMobileLayoutToggle);\r\n }\r\n\r\n /**\r\n * Toolbox Tool's button click handler\r\n *\r\n * @param toolName - tool type to be activated\r\n * @param blockDataOverrides - Block data predefined by the activated Toolbox item\r\n */\r\n public toolButtonActivated(toolName: string, blockDataOverrides: BlockToolData): void {\r\n this.insertNewBlock(toolName, blockDataOverrides);\r\n }\r\n\r\n /**\r\n * Open Toolbox with Tools\r\n */\r\n public open(): void {\r\n if (this.isEmpty) {\r\n return;\r\n }\r\n\r\n this.popover?.show();\r\n this.opened = true;\r\n this.emit(ToolboxEvent.Opened);\r\n }\r\n\r\n /**\r\n * Close Toolbox\r\n */\r\n public close(): void {\r\n this.popover?.hide();\r\n this.opened = false;\r\n this.emit(ToolboxEvent.Closed);\r\n }\r\n\r\n /**\r\n * Close Toolbox\r\n */\r\n public toggle(): void {\r\n if (!this.opened) {\r\n this.open();\r\n } else {\r\n this.close();\r\n }\r\n }\r\n\r\n /**\r\n * Destroys existing popover instance and contructs the new one.\r\n */\r\n public handleMobileLayoutToggle = (): void => {\r\n this.destroyPopover();\r\n this.initPopover();\r\n };\r\n\r\n /**\r\n * Creates toolbox popover and appends it inside wrapper element\r\n */\r\n private initPopover(): void {\r\n const PopoverClass = _.isMobileScreen() ? PopoverMobile : PopoverDesktop;\r\n\r\n this.popover = new PopoverClass({\r\n scopeElement: this.api.ui.nodes.redactor,\r\n searchable: false, //lrj:关闭搜索功能\r\n messages: {\r\n nothingFound: this.i18nLabels.nothingFound,\r\n search: this.i18nLabels.filter,\r\n },\r\n items: this.toolboxItemsToBeDisplayed,\r\n });\r\n\r\n this.popover.on(PopoverEvent.Closed, this.onPopoverClose);\r\n this.nodes.toolbox?.append(this.popover.getElement());\r\n }\r\n\r\n /**\r\n * Destroys popover instance and removes it from DOM\r\n */\r\n private destroyPopover(): void {\r\n if (this.popover !== null) {\r\n this.popover.hide();\r\n this.popover.off(PopoverEvent.Closed, this.onPopoverClose);\r\n this.popover.destroy();\r\n this.popover = null;\r\n }\r\n\r\n if (this.nodes.toolbox !== null) {\r\n this.nodes.toolbox.innerHTML = '';\r\n }\r\n }\r\n\r\n /**\r\n * Handles popover close event\r\n */\r\n private onPopoverClose = (): void => {\r\n this.opened = false;\r\n this.emit(ToolboxEvent.Closed);\r\n };\r\n\r\n /**\r\n * Returns list of tools that enables the Toolbox (by specifying the 'toolbox' getter)\r\n */\r\n @_.cacheable\r\n private get toolsToBeDisplayed(): BlockToolAdapter[] {\r\n const result: BlockToolAdapter[] = [];\r\n\r\n this.tools.forEach((tool) => {\r\n const toolToolboxSettings = tool.toolbox;\r\n\r\n if (toolToolboxSettings) {\r\n result.push(tool);\r\n }\r\n });\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns list of items that will be displayed in toolbox\r\n */\r\n @_.cacheable\r\n private get toolboxItemsToBeDisplayed(): PopoverItemParams[] {\r\n /**\r\n * Maps tool data to popover item structure\r\n */\r\n const toPopoverItem = (toolboxItem: ToolboxConfigEntry, tool: BlockToolAdapter, displaySecondaryLabel = true): PopoverItemParams => {\r\n return {\r\n icon: toolboxItem.icon,\r\n title: I18n.t(I18nInternalNS.toolNames, toolboxItem.title || _.capitalize(tool.name)),\r\n //lrj\r\n hint: {\r\n title: I18n.t(I18nInternalNS.toolNames, toolboxItem.title || _.capitalize(tool.name)),\r\n },\r\n name: tool.name,\r\n onActivate: (): void => {\r\n this.toolButtonActivated(tool.name, toolboxItem.data);\r\n },\r\n secondaryLabel: (tool.shortcut && displaySecondaryLabel) ? _.beautifyShortcut(tool.shortcut) : '',\r\n };\r\n };\r\n\r\n return this.toolsToBeDisplayed\r\n .reduce<PopoverItemParams[]>((result, tool) => {\r\n if (Array.isArray(tool.toolbox)) {\r\n tool.toolbox.forEach((item, index) => {\r\n result.push(toPopoverItem(item, tool, index === 0));\r\n });\r\n } else if (tool.toolbox !== undefined) {\r\n result.push(toPopoverItem(tool.toolbox, tool));\r\n }\r\n\r\n return result;\r\n }, []);\r\n }\r\n\r\n /**\r\n * Iterate all tools and enable theirs shortcuts if specified\r\n */\r\n private enableShortcuts(): void {\r\n this.toolsToBeDisplayed.forEach((tool: BlockToolAdapter) => {\r\n const shortcut = tool.shortcut;\r\n\r\n if (shortcut) {\r\n this.enableShortcutForTool(tool.name, shortcut);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Enable shortcut Block Tool implemented shortcut\r\n *\r\n * @param {string} toolName - Tool name\r\n * @param {string} shortcut - shortcut according to the ShortcutData Module format\r\n */\r\n private enableShortcutForTool(toolName: string, shortcut: string): void {\r\n Shortcuts.add({\r\n name: shortcut,\r\n on: this.api.ui.nodes.redactor,\r\n handler: async (event: KeyboardEvent) => {\r\n event.preventDefault();\r\n\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);\r\n\r\n /**\r\n * Try to convert current Block to shortcut's tool\r\n * If conversion is not possible, insert a new Block below\r\n */\r\n if (currentBlock) {\r\n try {\r\n const newBlock = await this.api.blocks.convert(currentBlock.id, toolName);\r\n\r\n this.api.caret.setToBlock(newBlock, 'end');\r\n\r\n return;\r\n } catch (error) {}\r\n }\r\n\r\n this.insertNewBlock(toolName);\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Removes all added shortcuts\r\n * Fired when the Read-Only mode is activated\r\n */\r\n private removeAllShortcuts(): void {\r\n this.toolsToBeDisplayed.forEach((tool: BlockToolAdapter) => {\r\n const shortcut = tool.shortcut;\r\n\r\n if (shortcut) {\r\n Shortcuts.remove(this.api.ui.nodes.redactor, shortcut);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Inserts new block\r\n * Can be called when button clicked on Toolbox or by ShortcutData\r\n *\r\n * @param {string} toolName - Tool name\r\n * @param blockDataOverrides - predefined Block data\r\n */\r\n private async insertNewBlock(toolName: string, blockDataOverrides?: BlockToolData): Promise<void> {\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);\r\n\r\n if (!currentBlock) {\r\n return;\r\n }\r\n\r\n /**\r\n * On mobile version, we see the Plus Button even near non-empty blocks,\r\n * so if current block is not empty, add the new block below the current\r\n */\r\n const index = currentBlock.isEmpty ? currentBlockIndex : currentBlockIndex + 1;\r\n\r\n let blockData;\r\n\r\n if (blockDataOverrides) {\r\n /**\r\n * Merge real tool's data with data overrides\r\n */\r\n const defaultBlockData = await this.api.blocks.composeBlockData(toolName);\r\n\r\n blockData = Object.assign(defaultBlockData, blockDataOverrides);\r\n }\r\n\r\n const newBlock = this.api.blocks.insert(\r\n toolName,\r\n blockData,\r\n undefined,\r\n index,\r\n undefined,\r\n currentBlock.isEmpty\r\n );\r\n\r\n /**\r\n * Apply callback before inserting html\r\n */\r\n newBlock.call(BlockToolAPI.APPEND_CALLBACK);\r\n\r\n this.api.caret.setToBlock(index);\r\n\r\n this.emit(ToolboxEvent.BlockAdded, {\r\n block: newBlock,\r\n });\r\n\r\n /**\r\n * close toolbar when node is changed\r\n */\r\n this.api.toolbar.close();\r\n }\r\n}\r\n","import type Block from '../block';\r\n\r\n/**\r\n * Fired when some block is hovered by user\r\n */\r\nexport const BlockHovered = 'block hovered';\r\n\r\n/**\r\n * Payload that will be passed with the event\r\n */\r\nexport interface BlockHoveredPayload {\r\n /**\r\n * Hovered block\r\n */\r\n block: Block;\r\n}\r\n","declare global {\r\n /**\r\n * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardLayoutMap\r\n */\r\n interface KeyboardLayoutMap {\r\n get(key: string): string | undefined;\r\n has(key: string): boolean;\r\n size: number;\r\n entries(): IterableIterator<[string, string]>;\r\n keys(): IterableIterator<string>;\r\n values(): IterableIterator<string>;\r\n forEach(callbackfn: (value: string, key: string, map: KeyboardLayoutMap) => void, thisArg?: unknown): void;\r\n }\r\n\r\n /**\r\n * The getLayoutMap() method of the Keyboard interface returns a Promise\r\n * that resolves with an instance of KeyboardLayoutMap which is a map-like object\r\n * with functions for retrieving the strings associated with specific physical keys.\r\n * https://developer.mozilla.org/en-US/docs/Web/API/Keyboard/getLayoutMap\r\n */\r\n interface Keyboard {\r\n getLayoutMap(): Promise<KeyboardLayoutMap>;\r\n }\r\n\r\n interface Navigator {\r\n /**\r\n * Keyboard API. Not supported by Firefox and Safari.\r\n */\r\n keyboard?: Keyboard;\r\n }\r\n}\r\n\r\n/**\r\n * Returns real layout-related keyboard key for a given key code.\r\n * For example, for \"Slash\" it will return \"/\" on US keyboard and \"-\" on Spanish keyboard.\r\n *\r\n * Works with Keyboard API which is not supported by Firefox and Safari. So fallback is used for these browsers.\r\n *\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Keyboard\r\n * @param code - {@link https://www.w3.org/TR/uievents-code/#key-alphanumeric-writing-system}\r\n * @param fallback - fallback value to be returned if Keyboard API is not supported (Safari, Firefox)\r\n */\r\nexport async function getKeyboardKeyForCode(code: string, fallback: string): Promise<string> {\r\n const keyboard = navigator.keyboard;\r\n\r\n if (!keyboard) {\r\n return fallback;\r\n }\r\n\r\n try {\r\n const map = await keyboard.getLayoutMap();\r\n\r\n const key = map.get(code);\r\n\r\n return key || fallback;\r\n } catch (e) {\r\n console.error(e);\r\n\r\n return fallback;\r\n }\r\n}\r\n","\r\nexport const IconCode: string = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 17C7 17 7 15.2536 7 13.5L5.5 12L7 10.5C7 8.74644 7 7 9 7\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 17C17 17 17 15.2536 17 13.5L18.5 12L17 10.5C17 8.74644 17 7 15 7\"/></svg>';\r\n\r\nexport const IconToolboxAlert: string = '<svg class=\"icon-toolbox-alert\" viewBox=\"0 0 1024 1024\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><path d=\"M83.2 147.2V448c0 25.6 19.2 44.8 44.8 44.8h768c25.6 0 44.8-19.2 44.8-44.8V147.2c0-25.6-19.2-44.8-44.8-44.8H128c-25.6 6.4-44.8 25.6-44.8 44.8z m89.6 256V192h684.8v211.2H172.8zM810.24 642.56c0-25.6-19.2-44.8-44.8-44.8h-640c-25.6 0-44.8 19.2-44.8 44.8 0 25.6 19.2 44.8 44.8 44.8h640c25.6 6.4 44.8-12.8 44.8-44.8zM554.56 866.24c0-25.6-19.2-44.8-44.8-44.8h-384c-25.6 0-44.8 19.2-44.8 44.8 0 25.6 19.2 44.8 44.8 44.8h384c25.6 6.4 44.8-12.8 44.8-44.8z\" fill=\"#000000\" ></path></svg>';","import Module from '../../__module';\r\nimport $, { calculateBaseline } from '../../dom';\r\nimport * as _ from '../../utils';\r\nimport I18n from '../../i18n';\r\nimport { I18nInternalNS } from '../../i18n/namespace-internal';\r\nimport * as tooltip from '../../utils/tooltip';\r\nimport type { ModuleConfig } from '../../../types-internal/module-config';\r\nimport type Block from '../../block';\r\nimport Toolbox, { ToolboxEvent } from '../../ui/toolbox';\r\nimport { IconMenu, IconPlus } from '@codexteam/icons';\r\nimport { BlockHovered } from '../../events/BlockHovered';\r\nimport { beautifyShortcut } from '../../utils';\r\nimport { getKeyboardKeyForCode } from '../../utils/keyboard';\r\nimport { IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconText,IconQuote,IconDelimiter,IconListBulleted,IconListNumbered,IconChecklist, IconTable,IconPicture} from '@codexteam/icons';\r\nimport {IconCode,IconToolboxAlert} from './toolbarIcon';\r\n/**\r\n * @todo Tab on non-empty block should open Block Settings of the hoveredBlock (not where caret is set)\r\n * - make Block Settings a standalone module\r\n * @todo - Keyboard-only mode bug:\r\n * press Tab, flip to the Checkbox. press Enter (block will be added), Press Tab\r\n * (Block Tunes will be opened with Move up focused), press Enter, press Tab ———— both Block Tunes and Toolbox will be opened\r\n * @todo TEST CASE - show toggler after opening and closing the Inline Toolbar\r\n * @todo TEST CASE - Click outside Editor holder should close Toolbar and Clear Focused blocks\r\n * @todo TEST CASE - Click inside Editor holder should close Toolbar and Clear Focused blocks\r\n * @todo TEST CASE - Click inside Redactor zone when Block Settings are opened:\r\n * - should close Block Settings\r\n * - should not close Toolbar\r\n * - should move Toolbar to the clicked Block\r\n * @todo TEST CASE - Toolbar should be closed on the Cross Block Selection\r\n * @todo TEST CASE - Toolbar should be closed on the Rectangle Selection\r\n * @todo TEST CASE - If Block Settings or Toolbox are opened, the Toolbar should not be moved by Bocks hovering\r\n */\r\n\r\n/**\r\n * HTML Elements used for Toolbar UI\r\n */\r\ninterface ToolbarNodes {\r\n wrapper: HTMLElement | undefined;\r\n content: HTMLElement | undefined;\r\n actions: HTMLElement | undefined;\r\n\r\n plusButton: HTMLElement | undefined;\r\n settingsToggler: HTMLElement | undefined;\r\n}\r\n/**\r\n *\r\n * «Toolbar» is the node that moves up/down over current block\r\n *\r\n * ______________________________________ Toolbar ____________________________________________\r\n * | |\r\n * | ..................... Content ......................................................... |\r\n * | . ........ Block Actions ........... |\r\n * | . . [Open Settings] . |\r\n * | . [Plus Button] [Toolbox: {Tool1}, {Tool2}] . . |\r\n * | . . [Settings Panel] . |\r\n * | . .................................. |\r\n * | ....................................................................................... |\r\n * | |\r\n * |___________________________________________________________________________________________|\r\n *\r\n *\r\n * Toolbox — its an Element contains tools buttons. Can be shown by Plus Button.\r\n *\r\n * _______________ Toolbox _______________\r\n * | |\r\n * | [Header] [Image] [List] [Quote] ... |\r\n * |_______________________________________|\r\n *\r\n *\r\n * Settings Panel — is an Element with block settings:\r\n *\r\n * ____ Settings Panel ____\r\n * | ...................... |\r\n * | . Tool Settings . |\r\n * | ...................... |\r\n * | . Default Settings . |\r\n * | ...................... |\r\n * |________________________|\r\n *\r\n *\r\n * @class\r\n * @classdesc Toolbar module\r\n * @typedef {Toolbar} Toolbar\r\n * @property {object} nodes - Toolbar nodes\r\n * @property {Element} nodes.wrapper - Toolbar main element\r\n * @property {Element} nodes.content - Zone with Plus button and toolbox.\r\n * @property {Element} nodes.actions - Zone with Block Settings and Remove Button\r\n * @property {Element} nodes.blockActionsButtons - Zone with Block Buttons: [Settings]\r\n * @property {Element} nodes.plusButton - Button that opens or closes Toolbox\r\n * @property {Element} nodes.toolbox - Container for tools\r\n * @property {Element} nodes.settingsToggler - open/close Settings Panel button\r\n * @property {Element} nodes.settings - Settings Panel\r\n * @property {Element} nodes.pluginSettings - Plugin Settings section of Settings Panel\r\n * @property {Element} nodes.defaultSettings - Default Settings section of Settings Panel\r\n */\r\nexport default class Toolbar extends Module<ToolbarNodes> {\r\n /**\r\n * Block near which we display the Toolbox\r\n */\r\n private hoveredBlock: Block;\r\n\r\n /**\r\n * Toolbox class instance\r\n * It will be created in requestIdleCallback so it can be null in some period of time\r\n */\r\n private toolboxInstance: Toolbox | null = null;\r\n\r\n /**\r\n * @class\r\n * @param moduleConfiguration - Module Configuration\r\n * @param moduleConfiguration.config - Editor's config\r\n * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher\r\n */\r\n constructor({ config, eventsDispatcher }: ModuleConfig) {\r\n super({\r\n config,\r\n eventsDispatcher,\r\n });\r\n }\r\n\r\n /**\r\n * CSS styles\r\n *\r\n * @returns {object}\r\n */\r\n public get CSS(): { [name: string]: string } {\r\n return {\r\n toolbar: 'ce-toolbar',\r\n content: 'ce-toolbar__content',\r\n actions: 'ce-toolbar__actions',\r\n actionsOpened: 'ce-toolbar__actions--opened',\r\n\r\n toolbarOpened: 'ce-toolbar--opened',\r\n openedToolboxHolderModifier: 'codex-editor--toolbox-opened',\r\n\r\n plusButton: 'ce-toolbar__plus',\r\n plusButtonShortcut: 'ce-toolbar__plus-shortcut',\r\n settingsToggler: 'ce-toolbar__settings-btn',\r\n settingsTogglerHidden: 'ce-toolbar__settings-btn--hidden',\r\n };\r\n }\r\n\r\n /**\r\n * Returns the Toolbar opening state\r\n *\r\n * @returns {boolean}\r\n */\r\n public get opened(): boolean {\r\n return this.nodes.wrapper.classList.contains(this.CSS.toolbarOpened);\r\n }\r\n\r\n /**\r\n * Public interface for accessing the Toolbox\r\n */\r\n public get toolbox(): {\r\n opened: boolean | undefined; // undefined is for the case when Toolbox is not initialized yet\r\n close: () => void;\r\n open: () => void;\r\n toggle: () => void;\r\n hasFocus: () => boolean | undefined;\r\n } {\r\n return {\r\n opened: this.toolboxInstance?.opened,\r\n close: () => {\r\n this.toolboxInstance?.close();\r\n },\r\n open: () => {\r\n /**\r\n * If Toolbox is not initialized yet, do nothing\r\n */\r\n if (this.toolboxInstance === null) {\r\n _.log('toolbox.open() called before initialization is finished', 'warn');\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Set current block to cover the case when the Toolbar showed near hovered Block but caret is set to another Block.\r\n */\r\n this.Editor.BlockManager.currentBlock = this.hoveredBlock;\r\n\r\n this.toolboxInstance.open();\r\n },\r\n toggle: () => {\r\n /**\r\n * If Toolbox is not initialized yet, do nothing\r\n */\r\n if (this.toolboxInstance === null) {\r\n _.log('toolbox.toggle() called before initialization is finished', 'warn');\r\n\r\n return;\r\n }\r\n\r\n this.toolboxInstance.toggle();\r\n },\r\n hasFocus: () => this.toolboxInstance?.hasFocus(),\r\n };\r\n }\r\n\r\n /**\r\n * Block actions appearance manipulations\r\n */\r\n private get blockActions(): { hide: () => void; show: () => void } {\r\n return {\r\n hide: (): void => {\r\n this.nodes.actions.classList.remove(this.CSS.actionsOpened);\r\n },\r\n show: (): void => {\r\n this.nodes.actions.classList.add(this.CSS.actionsOpened);\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Methods for working with Block Tunes toggler\r\n */\r\n private get blockTunesToggler(): { hide: () => void; show: () => void } {\r\n return {\r\n hide: (): void => this.nodes.settingsToggler.classList.add(this.CSS.settingsTogglerHidden),\r\n show: (): void => this.nodes.settingsToggler.classList.remove(this.CSS.settingsTogglerHidden),\r\n };\r\n }\r\n\r\n\r\n /**\r\n * Toggles read-only mode\r\n *\r\n * @param {boolean} readOnlyEnabled - read-only mode\r\n */\r\n public toggleReadOnly(readOnlyEnabled: boolean): void {\r\n if (!readOnlyEnabled) {\r\n window.requestIdleCallback(() => {\r\n this.drawUI();\r\n this.enableModuleBindings();\r\n }, { timeout: 2000 });\r\n } else {\r\n this.destroy();\r\n this.Editor.BlockSettings.destroy();\r\n this.disableModuleBindings();\r\n }\r\n }\r\n\r\n /**\r\n * Move Toolbar to the passed (or current) Block\r\n *\r\n * @param block - block to move Toolbar near it\r\n */\r\n public async moveAndOpen(block: Block = this.Editor.BlockManager.currentBlock): void {\r\n /**\r\n * Some UI elements creates inside requestIdleCallback, so the can be not ready yet\r\n */\r\n if (this.toolboxInstance === null) {\r\n _.log('Can\\'t open Toolbar since Editor initialization is not finished yet', 'warn');\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Close Toolbox when we move toolbar\r\n */\r\n if (this.toolboxInstance.opened) {\r\n this.toolboxInstance.close();\r\n }\r\n\r\n if (this.Editor.BlockSettings.opened) {\r\n this.Editor.BlockSettings.close();\r\n }\r\n\r\n /**\r\n * If no one Block selected as a Current\r\n */\r\n if (!block) {\r\n return;\r\n }\r\n\r\n this.hoveredBlock = block;\r\n\r\n const targetBlockHolder = block.holder;\r\n const { isMobile } = this.Editor.UI;\r\n\r\n\r\n /**\r\n * 1. Mobile:\r\n * - Toolbar at the bottom of the block\r\n *\r\n * 2. Desktop:\r\n * There are two cases of a toolbar position:\r\n * 2.1 Toolbar is moved to the top of the block (+ padding top of the block)\r\n * - when the first input is far from the top of the block, for example in Image tool\r\n * - when block has no inputs\r\n * 2.2 Toolbar is moved to the baseline of the first input\r\n * - when the first input is close to the top of the block\r\n */\r\n let toolbarY;\r\n const MAX_OFFSET = 20;\r\n\r\n /**\r\n * Compute first input position\r\n */\r\n const firstInput = block.firstInput;\r\n const targetBlockHolderRect = targetBlockHolder.getBoundingClientRect();\r\n const firstInputRect = firstInput !== undefined ? firstInput.getBoundingClientRect() : null;\r\n\r\n /**\r\n * Compute the offset of the first input from the top of the block\r\n */\r\n const firstInputOffset = firstInputRect !== null ? firstInputRect.top - targetBlockHolderRect.top : null;\r\n\r\n /**\r\n * Check if the first input is far from the top of the block\r\n */\r\n const isFirstInputFarFromTop = firstInputOffset !== null ? firstInputOffset > MAX_OFFSET : undefined;\r\n\r\n /**\r\n * Case 1.\r\n * On mobile — Toolbar at the bottom of Block\r\n */\r\n if (isMobile) {\r\n toolbarY = targetBlockHolder.offsetTop + targetBlockHolder.offsetHeight;\r\n\r\n /**\r\n * Case 2.1\r\n * On Desktop — without inputs or with the first input far from the top of the block\r\n * Toolbar should be moved to the top of the block\r\n */\r\n } else if (firstInput === undefined || isFirstInputFarFromTop) {\r\n const pluginContentOffset = parseInt(window.getComputedStyle(block.pluginsContent).paddingTop);\r\n\r\n const paddingTopBasedY = targetBlockHolder.offsetTop + pluginContentOffset;\r\n\r\n toolbarY = paddingTopBasedY;\r\n\r\n /**\r\n * Case 2.2\r\n * On Desktop — Toolbar should be moved to the baseline of the first input\r\n */\r\n } else {\r\n const baseline = calculateBaseline(firstInput);\r\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\r\n const toolbarActionsHeight = parseInt(window.getComputedStyle(this.nodes.plusButton!).height, 10);\r\n /**\r\n * Visual padding inside the SVG icon\r\n */\r\n const toolbarActionsPaddingBottom = 8;\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\r\n const baselineBasedY = targetBlockHolder.offsetTop + baseline - toolbarActionsHeight + toolbarActionsPaddingBottom + firstInputOffset!;\r\n\r\n toolbarY = baselineBasedY;\r\n }\r\n\r\n /**\r\n * Move Toolbar to the Top coordinate of Block\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\r\n this.nodes.wrapper!.style.top = `${Math.floor(toolbarY)}px`;\r\n\r\n /**\r\n * Do not show Block Tunes Toggler near single and empty block\r\n */\r\n if (this.Editor.BlockManager.blocks.length === 1 && block.isEmpty) {\r\n this.blockTunesToggler.hide();\r\n } else {\r\n this.blockTunesToggler.show();\r\n }\r\n //lrj \r\n console.log(\"block\",block);\r\n this.nodes.plusButton?.classList.remove(\"ce-toolbar__plus--hidden\");\r\n this.nodes.settingsToggler?.classList.remove(\"ce-toolbar__settings-btn--hidden\");\r\n if (block.isEmpty&&block.name!==\"delimiter\") {\r\n this.nodes.settingsToggler?.classList.add(\"ce-toolbar__settings-btn--hidden\");\r\n } else {\r\n \r\n const iconBlockName = this.nodes.settingsToggler?.querySelector<HTMLElement>(\".icon-block-name\");\r\n if (iconBlockName) {\r\n iconBlockName.innerHTML = await this.getIconBlockName(block);\r\n }\r\n this.nodes.plusButton?.classList.add(\"ce-toolbar__plus--hidden\");\r\n }\r\n this.open();\r\n }\r\n\r\n private async getIconBlockName(block: Block): Promise<string> {\r\n switch (block.name) {\r\n case \"image\":\r\n return IconPicture;\r\n break;\r\n case \"table\":\r\n return IconTable;\r\n break;\r\n case \"alert\":\r\n return IconToolboxAlert;\r\n break;\r\n case \"List\":\r\n \r\n const blockData = await block.data;\r\n if (blockData.style === \"checklist\") {\r\n return IconChecklist;\r\n } else if (blockData.style === \"ordered\") {\r\n return IconListNumbered;\r\n } else if(blockData.style === \"unordered\") {\r\n return IconListBulleted;\r\n }\r\n return \"\";\r\n break;\r\n case \"delimiter\":\r\n return IconDelimiter;\r\n break;\r\n case \"h1\":\r\n return IconH1;\r\n break;\r\n case \"h2\":\r\n return IconH2;\r\n break;\r\n case \"h3\":\r\n return IconH3;\r\n break;\r\n case \"h4\":\r\n return IconH4;\r\n break;\r\n case \"h5\":\r\n return IconH5;\r\n break;\r\n case \"h6\":\r\n return IconH6;\r\n break;\r\n case \"paragraph\":\r\n return IconText;\r\n break;\r\n case \"code\":\r\n return IconCode;\r\n break;\r\n case \"quote\":\r\n return IconQuote;\r\n break;\r\n\r\n default:\r\n return \"\";\r\n }\r\n }\r\n /**\r\n * Close the Toolbar\r\n */\r\n public close(): void {\r\n if (this.Editor.ReadOnly.isEnabled) {\r\n return;\r\n }\r\n\r\n this.nodes.wrapper?.classList.remove(this.CSS.toolbarOpened);\r\n\r\n /** Close components */\r\n this.blockActions.hide();\r\n this.toolboxInstance?.close();\r\n this.Editor.BlockSettings.close();\r\n this.reset();\r\n }\r\n\r\n /**\r\n * Reset the Toolbar position to prevent DOM height growth, for example after blocks deletion\r\n */\r\n private reset(): void {\r\n this.nodes.wrapper.style.top = 'unset';\r\n }\r\n\r\n /**\r\n * Open Toolbar with Plus Button and Actions\r\n *\r\n * @param {boolean} withBlockActions - by default, Toolbar opens with Block Actions.\r\n * This flag allows to open Toolbar without Actions.\r\n */\r\n private open(withBlockActions = true): void {\r\n this.nodes.wrapper.classList.add(this.CSS.toolbarOpened);\r\n\r\n if (withBlockActions) {\r\n this.blockActions.show();\r\n } else {\r\n this.blockActions.hide();\r\n }\r\n }\r\n\r\n /**\r\n * Draws Toolbar elements\r\n */\r\n private async make(): Promise<void> {\r\n this.nodes.wrapper = $.make('div', this.CSS.toolbar);\r\n /**\r\n * @todo detect test environment and add data-cy=\"toolbar\" to use it in tests instead of class name\r\n */\r\n\r\n /**\r\n * Make Content Zone and Actions Zone\r\n */\r\n ['content', 'actions'].forEach((el) => {\r\n this.nodes[el] = $.make('div', this.CSS[el]);\r\n });\r\n\r\n /**\r\n * Actions will be included to the toolbar content so we can align in to the right of the content\r\n */\r\n $.append(this.nodes.wrapper, this.nodes.content);\r\n $.append(this.nodes.content, this.nodes.actions);\r\n\r\n /**\r\n * Fill Content Zone:\r\n * - Plus Button\r\n * - Toolbox\r\n */\r\n this.nodes.plusButton = $.make('div', this.CSS.plusButton, {\r\n innerHTML: IconPlus,\r\n });\r\n $.append(this.nodes.actions, this.nodes.plusButton);\r\n\r\n this.readOnlyMutableListeners.on(this.nodes.plusButton, 'click', () => {\r\n tooltip.hide(true);\r\n this.plusButtonClicked();\r\n }, false);\r\n\r\n /**\r\n * Add events to show/hide tooltip for plus button\r\n */\r\n const tooltipContent = $.make('div');\r\n\r\n tooltipContent.appendChild(document.createTextNode(I18n.ui(I18nInternalNS.ui.toolbar.toolbox, 'Add')));\r\n tooltipContent.appendChild($.make('div', this.CSS.plusButtonShortcut, {\r\n textContent: '/',\r\n }));\r\n\r\n tooltip.onHover(this.nodes.plusButton, tooltipContent, {\r\n hidingDelay: 400,\r\n });\r\n\r\n /**\r\n * Fill Actions Zone:\r\n * - Settings Toggler\r\n * - Remove Block Button\r\n * - Settings Panel\r\n */\r\n const settingbtn=$.make('span', this.CSS.settingsToggler, {\r\n innerHTML: \"<span class='icon-block-name'></span>\"+\"<span class='icon-menu'>\"+IconMenu+\"</span>\",\r\n });\r\n //const \r\n //lrj todo...\r\n this.nodes.settingsToggler = settingbtn;\r\n\r\n $.append(this.nodes.actions, this.nodes.settingsToggler);\r\n\r\n const blockTunesTooltip = $.make('div');\r\n const blockTunesTooltipEl = $.text(I18n.ui(I18nInternalNS.ui.blockTunes.toggler, 'Click to tune'));\r\n const slashRealKey = await getKeyboardKeyForCode('Slash', '/');\r\n\r\n blockTunesTooltip.appendChild(blockTunesTooltipEl);\r\n blockTunesTooltip.appendChild($.make('div', this.CSS.plusButtonShortcut, {\r\n textContent: beautifyShortcut(`CMD + ${slashRealKey}`),\r\n }));\r\n\r\n tooltip.onHover(this.nodes.settingsToggler, blockTunesTooltip, {\r\n hidingDelay: 400,\r\n });\r\n\r\n /**\r\n * Appending Toolbar components to itself\r\n */\r\n $.append(this.nodes.actions, this.makeToolbox());\r\n $.append(this.nodes.actions, this.Editor.BlockSettings.getElement());\r\n\r\n /**\r\n * Append toolbar to the Editor\r\n */\r\n $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\r\n }\r\n\r\n /**\r\n * Creates the Toolbox instance and return it's rendered element\r\n */\r\n private makeToolbox(): Element {\r\n /**\r\n * Make the Toolbox\r\n */\r\n this.toolboxInstance = new Toolbox({\r\n api: this.Editor.API.methods,\r\n tools: this.Editor.Tools.blockTools,\r\n i18nLabels: {\r\n filter: I18n.ui(I18nInternalNS.ui.popover, 'Filter'),\r\n nothingFound: I18n.ui(I18nInternalNS.ui.popover, 'Nothing found'),\r\n },\r\n });\r\n\r\n this.toolboxInstance.on(ToolboxEvent.Opened, () => {\r\n this.Editor.UI.nodes.wrapper.classList.add(this.CSS.openedToolboxHolderModifier);\r\n });\r\n\r\n this.toolboxInstance.on(ToolboxEvent.Closed, () => {\r\n this.Editor.UI.nodes.wrapper.classList.remove(this.CSS.openedToolboxHolderModifier);\r\n });\r\n\r\n this.toolboxInstance.on(ToolboxEvent.BlockAdded, ({ block }) => {\r\n const { BlockManager, Caret } = this.Editor;\r\n const newBlock = BlockManager.getBlockById(block.id);\r\n\r\n /**\r\n * If the new block doesn't contain inputs, insert the new paragraph below\r\n */\r\n if (newBlock.inputs.length === 0) {\r\n if (newBlock === BlockManager.lastBlock) {\r\n BlockManager.insertAtEnd();\r\n Caret.setToBlock(BlockManager.lastBlock);\r\n } else {\r\n Caret.setToBlock(BlockManager.nextBlock);\r\n }\r\n }\r\n });\r\n\r\n return this.toolboxInstance.getElement();\r\n }\r\n\r\n\r\n /**\r\n * Handler for Plus Button\r\n */\r\n private plusButtonClicked(): void {\r\n /**\r\n * We need to update Current Block because user can click on the Plus Button (thanks to appearing by hover) without any clicks on editor\r\n * In this case currentBlock will point last block\r\n */\r\n this.Editor.BlockManager.currentBlock = this.hoveredBlock;\r\n\r\n this.toolboxInstance?.toggle();\r\n }\r\n\r\n /**\r\n * Enable bindings\r\n */\r\n private enableModuleBindings(): void {\r\n /**\r\n * Settings toggler\r\n *\r\n * mousedown is used because on click selection is lost in Safari and FF\r\n */\r\n this.readOnlyMutableListeners.on(this.nodes.settingsToggler, 'mousedown', (e) => {\r\n /**\r\n * Stop propagation to prevent block selection clearance\r\n *\r\n * @see UI.documentClicked\r\n */\r\n e.stopPropagation();\r\n\r\n this.settingsTogglerClicked();\r\n\r\n if (this.toolboxInstance?.opened) {\r\n this.toolboxInstance.close();\r\n }\r\n\r\n tooltip.hide(true);\r\n }, true);\r\n\r\n /**\r\n * Subscribe to the 'block-hovered' event if current view is not mobile\r\n *\r\n * @see https://github.com/codex-team/editor.js/issues/1972\r\n */\r\n if (!_.isMobileScreen()) {\r\n /**\r\n * Subscribe to the 'block-hovered' event\r\n */\r\n this.eventsDispatcher.on(BlockHovered, (data) => {\r\n /**\r\n * Do not move toolbar if Block Settings or Toolbox opened\r\n */\r\n if (this.Editor.BlockSettings.opened || this.toolboxInstance?.opened) {\r\n return;\r\n }\r\n\r\n this.moveAndOpen(data.block);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Disable bindings\r\n */\r\n private disableModuleBindings(): void {\r\n this.readOnlyMutableListeners.clearAll();\r\n }\r\n\r\n /**\r\n * Clicks on the Block Settings toggler\r\n */\r\n private settingsTogglerClicked(): void {\r\n /**\r\n * We need to update Current Block because user can click on toggler (thanks to appearing by hover) without any clicks on editor\r\n * In this case currentBlock will point last block\r\n */\r\n this.Editor.BlockManager.currentBlock = this.hoveredBlock;\r\n\r\n if (this.Editor.BlockSettings.opened) {\r\n this.Editor.BlockSettings.close();\r\n } else {\r\n this.Editor.BlockSettings.open(this.hoveredBlock);\r\n }\r\n }\r\n\r\n /**\r\n * Draws Toolbar UI\r\n *\r\n * Toolbar contains BlockSettings and Toolbox.\r\n * That's why at first we draw its components and then Toolbar itself\r\n *\r\n * Steps:\r\n * - Make Toolbar dependent components like BlockSettings, Toolbox and so on\r\n * - Make itself and append dependent nodes to itself\r\n *\r\n */\r\n private drawUI(): void {\r\n /**\r\n * Make BlockSettings Panel\r\n */\r\n this.Editor.BlockSettings.make();\r\n\r\n /**\r\n * Make Toolbar\r\n */\r\n void this.make();\r\n }\r\n\r\n /**\r\n * Removes all created and saved HTMLElements\r\n * It is used in Read-Only mode\r\n */\r\n private destroy(): void {\r\n this.removeAllNodes();\r\n if (this.toolboxInstance) {\r\n this.toolboxInstance.destroy();\r\n }\r\n }\r\n}\r\n","/**\r\n * What kind of plugins developers can create\r\n */\r\nexport enum ToolType {\r\n /**\r\n * Block tool\r\n */\r\n Block,\r\n /**\r\n * Inline tool\r\n */\r\n Inline,\r\n\r\n /**\r\n * Block tune\r\n */\r\n Tune,\r\n}\r\n","import type { Tool, ToolConstructable, ToolSettings } from '../../../types/tools';\r\nimport type { SanitizerConfig, API as ApiMethods } from '../../../types';\r\nimport * as _ from '../utils';\r\nimport { ToolType } from '../../../types/tools/adapters/tool-type';\r\nimport type { BaseToolAdapter as BaseToolAdapterInterface } from '../../../types/tools/adapters/base-tool-adapter';\r\nimport type { InlineToolAdapter as InlineToolAdapterInterface } from '../../../types/tools/adapters/inline-tool-adapter';\r\nimport type { BlockToolAdapter as BlockToolAdapterInterface } from '../../../types/tools/adapters/block-tool-adapter';\r\nimport type { BlockTuneAdapter as BlockTuneAdapterInterface } from '../../../types/tools/adapters/block-tune-adapter';\r\n\r\n/**\r\n * Enum of Tool options provided by user\r\n */\r\nexport enum UserSettings {\r\n /**\r\n * Shortcut for Tool\r\n */\r\n Shortcut = 'shortcut',\r\n /**\r\n * Toolbox config for Tool\r\n */\r\n Toolbox = 'toolbox',\r\n /**\r\n * Enabled Inline Tools for Block Tool\r\n */\r\n EnabledInlineTools = 'inlineToolbar',\r\n /**\r\n * Enabled Block Tunes for Block Tool\r\n */\r\n EnabledBlockTunes = 'tunes',\r\n /**\r\n * Tool configuration\r\n */\r\n Config = 'config',\r\n}\r\n\r\n/**\r\n * Enum of Tool options provided by Tool\r\n */\r\nexport enum CommonInternalSettings {\r\n /**\r\n * Shortcut for Tool\r\n */\r\n Shortcut = 'shortcut',\r\n /**\r\n * Sanitize configuration for Tool\r\n */\r\n SanitizeConfig = 'sanitize',\r\n\r\n}\r\n\r\n/**\r\n * Enum of Tool options provided by Block Tool\r\n */\r\nexport enum InternalBlockToolSettings {\r\n /**\r\n * Is line breaks enabled for Tool\r\n */\r\n IsEnabledLineBreaks = 'enableLineBreaks',\r\n /**\r\n * Tool Toolbox config\r\n */\r\n Toolbox = 'toolbox',\r\n /**\r\n * Tool conversion config\r\n */\r\n ConversionConfig = 'conversionConfig',\r\n /**\r\n * Is readonly mode supported for Tool\r\n */\r\n IsReadOnlySupported = 'isReadOnlySupported',\r\n /**\r\n * Tool paste config\r\n */\r\n PasteConfig = 'pasteConfig'\r\n}\r\n\r\n/**\r\n * Enum of Tool options provided by Inline Tool\r\n */\r\nexport enum InternalInlineToolSettings {\r\n /**\r\n * Flag specifies Tool is inline\r\n */\r\n IsInline = 'isInline',\r\n /**\r\n * Inline Tool title for toolbar\r\n */\r\n Title = 'title', // for Inline Tools. Block Tools can pass title along with icon through the 'toolbox' static prop.\r\n\r\n /**\r\n * Allows inline tool to be available in read-only mode\r\n * Can be used, for example, by comments tool\r\n */\r\n IsReadOnlySupported = 'isReadOnlySupported',\r\n}\r\n\r\n/**\r\n * Enum of Tool options provided by Block Tune\r\n */\r\nexport enum InternalTuneSettings {\r\n /**\r\n * Flag specifies Tool is Block Tune\r\n */\r\n IsTune = 'isTune',\r\n}\r\n\r\nexport type ToolOptions = Omit<ToolSettings, 'class'>;\r\n\r\ninterface ConstructorOptions {\r\n name: string;\r\n constructable: ToolConstructable;\r\n config: ToolOptions;\r\n api: ApiMethods;\r\n isDefault: boolean;\r\n isInternal: boolean;\r\n defaultPlaceholder?: string | false;\r\n}\r\n\r\n/**\r\n * Base abstract class for Tools\r\n */\r\nexport default abstract class BaseToolAdapter<Type extends ToolType = ToolType, ToolClass extends Tool = Tool> implements BaseToolAdapterInterface<ToolType, Tool> {\r\n /**\r\n * Tool type: Block, Inline or Tune\r\n */\r\n public type: Type;\r\n\r\n /**\r\n * Tool name specified in EditorJS config\r\n */\r\n public name: string;\r\n\r\n /**\r\n * Flag show is current Tool internal (bundled with EditorJS core) or not\r\n */\r\n public readonly isInternal: boolean;\r\n\r\n /**\r\n * Flag show is current Tool default or not\r\n */\r\n public readonly isDefault: boolean;\r\n\r\n /**\r\n * EditorJS API for current Tool\r\n */\r\n protected api: ApiMethods;\r\n\r\n /**\r\n * Current tool user configuration\r\n */\r\n protected config: ToolOptions;\r\n\r\n /**\r\n * Tool's constructable blueprint\r\n */\r\n protected constructable: ToolConstructable;\r\n\r\n /**\r\n * Default placeholder specified in EditorJS user configuration\r\n */\r\n protected defaultPlaceholder?: string | false;\r\n\r\n /**\r\n * @class\r\n * @param {ConstructorOptions} options - Constructor options\r\n */\r\n constructor({\r\n name,\r\n constructable,\r\n config,\r\n api,\r\n isDefault,\r\n isInternal = false,\r\n defaultPlaceholder,\r\n }: ConstructorOptions) {\r\n this.api = api;\r\n this.name = name;\r\n this.constructable = constructable;\r\n this.config = config;\r\n this.isDefault = isDefault;\r\n this.isInternal = isInternal;\r\n this.defaultPlaceholder = defaultPlaceholder;\r\n }\r\n\r\n /**\r\n * Returns Tool user configuration\r\n */\r\n public get settings(): ToolOptions {\r\n const config = this.config[UserSettings.Config] || {};\r\n\r\n if (this.isDefault && !('placeholder' in config) && this.defaultPlaceholder) {\r\n config.placeholder = this.defaultPlaceholder;\r\n }\r\n\r\n return config;\r\n }\r\n\r\n /**\r\n * Calls Tool's reset method\r\n */\r\n public reset(): void | Promise<void> {\r\n if (_.isFunction(this.constructable.reset)) {\r\n return this.constructable.reset();\r\n }\r\n }\r\n\r\n /**\r\n * Calls Tool's prepare method\r\n */\r\n public prepare(): void | Promise<void> {\r\n if (_.isFunction(this.constructable.prepare)) {\r\n return this.constructable.prepare({\r\n toolName: this.name,\r\n config: this.settings,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Returns shortcut for Tool (internal or specified by user)\r\n */\r\n public get shortcut(): string | undefined {\r\n const toolShortcut = this.constructable[CommonInternalSettings.Shortcut];\r\n const userShortcut = this.config[UserSettings.Shortcut];\r\n\r\n return userShortcut || toolShortcut;\r\n }\r\n\r\n /**\r\n * Returns Tool's sanitizer configuration\r\n */\r\n public get sanitizeConfig(): SanitizerConfig {\r\n return this.constructable[CommonInternalSettings.SanitizeConfig] || {};\r\n }\r\n\r\n /**\r\n * Returns true if Tools is inline\r\n */\r\n public isInline(): this is InlineToolAdapterInterface {\r\n return this.type === ToolType.Inline;\r\n }\r\n\r\n /**\r\n * Returns true if Tools is block\r\n */\r\n public isBlock(): this is BlockToolAdapterInterface {\r\n return this.type === ToolType.Block;\r\n }\r\n\r\n /**\r\n * Returns true if Tools is tune\r\n */\r\n public isTune(): this is BlockTuneAdapterInterface {\r\n return this.type === ToolType.Tune;\r\n }\r\n\r\n /**\r\n * Constructs new Tool instance from constructable blueprint\r\n *\r\n * @param args\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n public abstract create(...args: any[]): ToolClass;\r\n}\r\n","/* eslint-disable @typescript-eslint/no-non-null-assertion */\r\nimport Module from '../../__module';\r\nimport $ from '../../dom';\r\nimport SelectionUtils from '../../selection';\r\nimport * as _ from '../../utils';\r\nimport type { InlineTool as IInlineTool } from '../../../../types';\r\nimport I18n from '../../i18n';\r\nimport { I18nInternalNS } from '../../i18n/namespace-internal';\r\nimport Shortcuts from '../../utils/shortcuts';\r\nimport type { ModuleConfig } from '../../../types-internal/module-config';\r\nimport { CommonInternalSettings } from '../../tools/base';\r\nimport type { Popover, PopoverItemHtmlParams, PopoverItemParams, WithChildren } from '../../utils/popover';\r\nimport { PopoverItemType } from '../../utils/popover';\r\nimport { PopoverInline } from '../../utils/popover/popover-inline';\r\nimport type InlineToolAdapter from 'src/components/tools/inline';\r\n\r\n/**\r\n * Inline Toolbar elements\r\n */\r\ninterface InlineToolbarNodes {\r\n wrapper: HTMLElement | undefined;\r\n}\r\n\r\n/**\r\n * Inline toolbar with actions that modifies selected text fragment\r\n *\r\n * |¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|\r\n * | B i [link] [mark] |\r\n * |________________________|\r\n */\r\nexport default class InlineToolbar extends Module<InlineToolbarNodes> {\r\n /**\r\n * CSS styles\r\n */\r\n public CSS = {\r\n inlineToolbar: 'ce-inline-toolbar',\r\n };\r\n\r\n /**\r\n * State of inline toolbar\r\n */\r\n public opened = false;\r\n\r\n /**\r\n * Popover instance reference\r\n */\r\n private popover: Popover | null = null;\r\n\r\n /**\r\n * Margin above/below the Toolbar\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n private readonly toolbarVerticalMargin: number = _.isMobileScreen() ? 20 : 6;\r\n\r\n /**\r\n * Currently visible tools instances\r\n */\r\n private tools: Map<InlineToolAdapter, IInlineTool> = new Map();\r\n\r\n /**\r\n * @param moduleConfiguration - Module Configuration\r\n * @param moduleConfiguration.config - Editor's config\r\n * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher\r\n */\r\n constructor({ config, eventsDispatcher }: ModuleConfig) {\r\n super({\r\n config,\r\n eventsDispatcher,\r\n });\r\n\r\n window.requestIdleCallback(() => {\r\n this.make();\r\n }, { timeout: 2000 });\r\n }\r\n\r\n /**\r\n * Moving / appearance\r\n * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n */\r\n\r\n /**\r\n * Shows Inline Toolbar if something is selected\r\n *\r\n * @param [needToClose] - pass true to close toolbar if it is not allowed.\r\n * Avoid to use it just for closing IT, better call .close() clearly.\r\n */\r\n public async tryToShow(needToClose = false): Promise<void> {\r\n if (needToClose) {\r\n this.close();\r\n }\r\n\r\n if (!this.allowedToShow()) {\r\n return;\r\n }\r\n\r\n await this.open();\r\n\r\n this.Editor.Toolbar.close();\r\n }\r\n\r\n /**\r\n * Hides Inline Toolbar\r\n */\r\n public close(): void {\r\n if (!this.opened) {\r\n return;\r\n }\r\n\r\n for (const [tool, toolInstance] of this.tools) {\r\n const shortcut = this.getToolShortcut(tool.name);\r\n\r\n if (shortcut !== undefined) {\r\n Shortcuts.remove(this.Editor.UI.nodes.redactor, shortcut);\r\n }\r\n\r\n /**\r\n * @todo replace 'clear' with 'destroy'\r\n */\r\n if (_.isFunction(toolInstance.clear)) {\r\n toolInstance.clear();\r\n }\r\n }\r\n\r\n this.tools = new Map();\r\n\r\n this.reset();\r\n this.opened = false;\r\n\r\n this.popover?.hide();\r\n this.popover?.destroy();\r\n this.popover = null;\r\n }\r\n\r\n /**\r\n * Check if node is contained by Inline Toolbar\r\n *\r\n * @param {Node} node — node to check\r\n */\r\n public containsNode(node: Node): boolean {\r\n if (this.nodes.wrapper === undefined) {\r\n return false;\r\n }\r\n\r\n return this.nodes.wrapper.contains(node);\r\n }\r\n\r\n /**\r\n * Removes UI and its components\r\n */\r\n public destroy(): void {\r\n this.removeAllNodes();\r\n this.popover?.destroy();\r\n this.popover = null;\r\n }\r\n\r\n /**\r\n * Making DOM\r\n */\r\n private make(): void {\r\n this.nodes.wrapper = $.make('div', [\r\n this.CSS.inlineToolbar,\r\n ...(this.isRtl ? [ this.Editor.UI.CSS.editorRtlFix ] : []),\r\n ]);\r\n\r\n if (import.meta.env.MODE === 'test') {\r\n this.nodes.wrapper.setAttribute('data-cy', 'inline-toolbar');\r\n }\r\n\r\n /**\r\n * Append the inline toolbar to the editor.\r\n */\r\n $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\r\n }\r\n\r\n /**\r\n * Shows Inline Toolbar\r\n */\r\n private async open(): Promise<void> {\r\n if (this.opened) {\r\n return;\r\n }\r\n\r\n /**\r\n * Show Inline Toolbar\r\n */\r\n\r\n this.opened = true;\r\n\r\n if (this.popover !== null) {\r\n this.popover.destroy();\r\n }\r\n\r\n this.createToolsInstances();\r\n\r\n const popoverItems = await this.getPopoverItems();\r\n\r\n this.popover = new PopoverInline({\r\n items: popoverItems,\r\n scopeElement: this.Editor.API.methods.ui.nodes.redactor,\r\n messages: {\r\n nothingFound: I18n.ui(I18nInternalNS.ui.popover, 'Nothing found'),\r\n search: I18n.ui(I18nInternalNS.ui.popover, 'Filter'),\r\n },\r\n });\r\n\r\n this.move(this.popover.size.width);\r\n\r\n this.nodes.wrapper?.append(this.popover.getElement());\r\n\r\n this.popover.show();\r\n }\r\n\r\n /**\r\n * Move Toolbar to the selected text\r\n *\r\n * @param popoverWidth - width of the toolbar popover\r\n */\r\n private move(popoverWidth: number): void {\r\n const selectionRect = SelectionUtils.rect as DOMRect;\r\n const wrapperOffset = this.Editor.UI.nodes.wrapper.getBoundingClientRect();\r\n const newCoords = {\r\n x: selectionRect.x - wrapperOffset.x,\r\n y: selectionRect.y +\r\n selectionRect.height -\r\n // + window.scrollY\r\n wrapperOffset.top +\r\n this.toolbarVerticalMargin,\r\n };\r\n\r\n const realRightCoord = newCoords.x + popoverWidth + wrapperOffset.x;\r\n\r\n /**\r\n * Prevent InlineToolbar from overflowing the content zone on the right side\r\n */\r\n if (realRightCoord > this.Editor.UI.contentRect.right) {\r\n newCoords.x = this.Editor.UI.contentRect.right -popoverWidth - wrapperOffset.x;\r\n }\r\n\r\n this.nodes.wrapper!.style.left = Math.floor(newCoords.x) + 'px';\r\n this.nodes.wrapper!.style.top = Math.floor(newCoords.y) + 'px';\r\n }\r\n\r\n /**\r\n * Clear orientation classes and reset position\r\n */\r\n private reset(): void {\r\n this.nodes.wrapper!.style.left = '0';\r\n this.nodes.wrapper!.style.top = '0';\r\n }\r\n\r\n /**\r\n * Need to show Inline Toolbar or not\r\n */\r\n private allowedToShow(): boolean {\r\n /**\r\n * Tags conflicts with window.selection function.\r\n * Ex. IMG tag returns null (Firefox) or Redactors wrapper (Chrome)\r\n */\r\n const tagsConflictsWithSelection = ['IMG', 'INPUT'];\r\n const currentSelection = SelectionUtils.get();\r\n const selectedText = SelectionUtils.text;\r\n\r\n // old browsers\r\n if (!currentSelection || !currentSelection.anchorNode) {\r\n return false;\r\n }\r\n\r\n // empty selection\r\n if (currentSelection.isCollapsed || selectedText.length < 1) {\r\n return false;\r\n }\r\n\r\n const target = !$.isElement(currentSelection.anchorNode)\r\n ? currentSelection.anchorNode.parentElement\r\n : currentSelection.anchorNode;\r\n\r\n if (target === null) {\r\n return false;\r\n }\r\n\r\n if (currentSelection !== null && tagsConflictsWithSelection.includes(target.tagName)) {\r\n return false;\r\n }\r\n\r\n /**\r\n * Check if there is at leas one tool enabled by current Block's Tool\r\n */\r\n const currentBlock = this.Editor.BlockManager.getBlock(currentSelection.anchorNode as HTMLElement);\r\n\r\n if (!currentBlock) {\r\n return false;\r\n }\r\n\r\n /**\r\n * Check that at least one tool is available for the current block\r\n */\r\n const toolsAvailable = this.getTools();\r\n const isAtLeastOneToolAvailable = toolsAvailable.some((tool) => currentBlock.tool.inlineTools.has(tool.name));\r\n\r\n if (isAtLeastOneToolAvailable === false) {\r\n return false;\r\n }\r\n\r\n /**\r\n * Inline toolbar will be shown only if the target is contenteditable\r\n * In Read-Only mode, the target should be contenteditable with \"false\" value\r\n */\r\n const contenteditable = target.closest('[contenteditable]');\r\n\r\n return contenteditable !== null;\r\n }\r\n\r\n /**\r\n * Working with Tools\r\n * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n */\r\n\r\n /**\r\n * Returns tools that are available for current block\r\n *\r\n * Used to check if Inline Toolbar could be shown\r\n * and to render tools in the Inline Toolbar\r\n */\r\n private getTools(): InlineToolAdapter[] {\r\n const currentBlock = this.Editor.BlockManager.currentBlock;\r\n\r\n if (!currentBlock) {\r\n return [];\r\n }\r\n\r\n const inlineTools = Array.from(currentBlock.tool.inlineTools.values());\r\n\r\n return inlineTools.filter((tool) => {\r\n /**\r\n * We support inline tools in read only mode.\r\n * Such tools should have isReadOnlySupported flag set to true\r\n */\r\n if (this.Editor.ReadOnly.isEnabled && tool.isReadOnlySupported !== true) {\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n }\r\n\r\n /**\r\n * Constructs tools instances and saves them to this.tools\r\n */\r\n private createToolsInstances(): void {\r\n this.tools = new Map();\r\n\r\n const tools = this.getTools();\r\n\r\n tools.forEach((tool) => {\r\n const instance = tool.create();\r\n\r\n this.tools.set(tool, instance);\r\n });\r\n }\r\n\r\n /**\r\n * Returns Popover Items for tools segregated by their appearance type: regular items and custom html elements.\r\n */\r\n private async getPopoverItems(): Promise<PopoverItemParams[]> {\r\n const popoverItems = [] as PopoverItemParams[];\r\n\r\n let i = 0;\r\n\r\n for (const [tool, instance] of this.tools) {\r\n const renderedTool = await instance.render();\r\n\r\n /** Enable tool shortcut */\r\n const shortcut = this.getToolShortcut(tool.name);\r\n\r\n if (shortcut !== undefined) {\r\n try {\r\n this.enableShortcuts(tool.name, shortcut);\r\n } catch (e) {}\r\n }\r\n\r\n const shortcutBeautified = shortcut !== undefined ? _.beautifyShortcut(shortcut) : undefined;\r\n\r\n const toolTitle = I18n.t(\r\n I18nInternalNS.toolNames,\r\n tool.title || _.capitalize(tool.name)\r\n );\r\n\r\n [ renderedTool ].flat().forEach((item) => {\r\n const commonPopoverItemParams = {\r\n name: tool.name,\r\n onActivate: () => {\r\n this.toolClicked(instance);\r\n },\r\n hint: {\r\n title: toolTitle,\r\n description: shortcutBeautified,\r\n },\r\n } as PopoverItemParams;\r\n\r\n if ($.isElement(item)) {\r\n /**\r\n * Deprecated way to add custom html elements to the Inline Toolbar\r\n */\r\n\r\n const popoverItem = {\r\n ...commonPopoverItemParams,\r\n element: item,\r\n type: PopoverItemType.Html,\r\n } as PopoverItemParams;\r\n\r\n /**\r\n * If tool specifies actions in deprecated manner, append them as children\r\n */\r\n if (_.isFunction(instance.renderActions)) {\r\n const actions = instance.renderActions();\r\n\r\n (popoverItem as WithChildren<PopoverItemHtmlParams>).children = {\r\n isOpen: instance.checkState?.(SelectionUtils.get()),\r\n /** Disable keyboard navigation in actions, as it might conflict with enter press handling */\r\n isFlippable: false,\r\n items: [\r\n {\r\n type: PopoverItemType.Html,\r\n element: actions,\r\n },\r\n ],\r\n };\r\n } else {\r\n /**\r\n * Legacy inline tools might perform some UI mutating logic in checkState method, so, call it just in case\r\n */\r\n instance.checkState?.(SelectionUtils.get());\r\n }\r\n\r\n popoverItems.push(popoverItem);\r\n } else if (item.type === PopoverItemType.Html) {\r\n /**\r\n * Actual way to add custom html elements to the Inline Toolbar\r\n */\r\n popoverItems.push({\r\n ...commonPopoverItemParams,\r\n ...item,\r\n type: PopoverItemType.Html,\r\n });\r\n } else if (item.type === PopoverItemType.Separator) {\r\n /**\r\n * Separator item\r\n */\r\n popoverItems.push({\r\n type: PopoverItemType.Separator,\r\n });\r\n } else {\r\n /**\r\n * Default item\r\n */\r\n const popoverItem = {\r\n ...commonPopoverItemParams,\r\n ...item,\r\n type: PopoverItemType.Default,\r\n } as PopoverItemParams;\r\n\r\n /**\r\n * Prepend the separator if item has children and not the first one\r\n */\r\n if ('children' in popoverItem && i !== 0) {\r\n popoverItems.push({\r\n type: PopoverItemType.Separator,\r\n });\r\n }\r\n\r\n popoverItems.push(popoverItem);\r\n\r\n /**\r\n * Append a separator after the item if it has children and not the last one\r\n */\r\n if ('children' in popoverItem && i < this.tools.size - 1) {\r\n popoverItems.push({\r\n type: PopoverItemType.Separator,\r\n });\r\n }\r\n }\r\n });\r\n\r\n i++;\r\n }\r\n\r\n return popoverItems;\r\n }\r\n\r\n /**\r\n * Get shortcut name for tool\r\n *\r\n * @param toolName — Tool name\r\n */\r\n private getToolShortcut(toolName: string): string | undefined {\r\n const { Tools } = this.Editor;\r\n\r\n /**\r\n * Enable shortcuts\r\n * Ignore tool that doesn't have shortcut or empty string\r\n */\r\n const tool = Tools.inlineTools.get(toolName);\r\n\r\n /**\r\n * 1) For internal tools, check public getter 'shortcut'\r\n * 2) For external tools, check tool's settings\r\n * 3) If shortcut is not set in settings, check Tool's public property\r\n */\r\n const internalTools = Tools.internal.inlineTools;\r\n\r\n if (Array.from(internalTools.keys()).includes(toolName)) {\r\n return this.inlineTools[toolName][CommonInternalSettings.Shortcut];\r\n }\r\n\r\n return tool?.shortcut;\r\n }\r\n\r\n /**\r\n * Enable Tool shortcut with Editor Shortcuts Module\r\n *\r\n * @param toolName - tool name\r\n * @param shortcut - shortcut according to the ShortcutData Module format\r\n */\r\n private enableShortcuts(toolName: string, shortcut: string): void {\r\n Shortcuts.add({\r\n name: shortcut,\r\n handler: (event) => {\r\n const { currentBlock } = this.Editor.BlockManager;\r\n\r\n /**\r\n * Editor is not focused\r\n */\r\n if (!currentBlock) {\r\n return;\r\n }\r\n\r\n /**\r\n * We allow to fire shortcut with empty selection (isCollapsed=true)\r\n * it can be used by tools like «Mention» that works without selection:\r\n * Example: by SHIFT+@ show dropdown and insert selected username\r\n */\r\n // if (SelectionUtils.isCollapsed) return;\r\n\r\n if (!currentBlock.tool.enabledInlineTools) {\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n\r\n this.popover?.activateItemByName(toolName);\r\n },\r\n /**\r\n * We need to bind shortcut to the document to make it work in read-only mode\r\n */\r\n on: document,\r\n });\r\n }\r\n\r\n /**\r\n * Inline Tool button clicks\r\n *\r\n * @param tool - Tool's instance\r\n */\r\n private toolClicked(tool: IInlineTool): void {\r\n const range = SelectionUtils.range;\r\n\r\n tool.surround?.(range);\r\n this.checkToolsState();\r\n }\r\n\r\n /**\r\n * Check Tools` state by selection\r\n */\r\n private checkToolsState(): void {\r\n this.tools?.forEach((toolInstance) => {\r\n toolInstance.checkState?.(SelectionUtils.get());\r\n });\r\n }\r\n\r\n /**\r\n * Get inline tools tools\r\n * Tools that has isInline is true\r\n */\r\n private get inlineTools(): { [name: string]: IInlineTool } {\r\n const result = {} as { [name: string]: IInlineTool } ;\r\n\r\n Array\r\n .from(this.Editor.Tools.inlineTools.entries())\r\n .forEach(([name, tool]) => {\r\n result[name] = tool.create();\r\n });\r\n\r\n return result;\r\n }\r\n}\r\n","import $, { isCollapsedWhitespaces } from '../dom';\r\n\r\n/**\r\n * Returns TextNode containing a caret and a caret offset in it\r\n * Returns null if there is no caret set\r\n *\r\n * Handles a case when focusNode is an ElementNode and focusOffset is a child index,\r\n * returns child node with focusOffset index as a new focusNode\r\n */\r\nexport function getCaretNodeAndOffset(): [ Node | null, number ] {\r\n const selection = window.getSelection();\r\n\r\n if (selection === null) {\r\n return [null, 0];\r\n }\r\n\r\n let focusNode = selection.focusNode;\r\n let focusOffset = selection.focusOffset;\r\n\r\n if (focusNode === null) {\r\n return [null, 0];\r\n }\r\n\r\n /**\r\n * Case when focusNode is an Element (or Document). In this case, focusOffset is a child index.\r\n * We need to return child with focusOffset index as a new focusNode.\r\n *\r\n * <div>|hello</div> <---- Selection references to <div> instead of text node\r\n *\r\n *\r\n */\r\n if (focusNode.nodeType !== Node.TEXT_NODE && focusNode.childNodes.length > 0) {\r\n /**\r\n * In normal cases, focusOffset is a child index.\r\n */\r\n if (focusNode.childNodes[focusOffset]) {\r\n focusNode = focusNode.childNodes[focusOffset];\r\n focusOffset = 0;\r\n /**\r\n * But in Firefox, focusOffset can be 1 with the single child.\r\n */\r\n } else {\r\n focusNode = focusNode.childNodes[focusOffset - 1];\r\n focusOffset = focusNode.textContent.length;\r\n }\r\n }\r\n\r\n return [focusNode, focusOffset];\r\n}\r\n\r\n/**\r\n * Checks content at left or right of the passed node for emptiness.\r\n *\r\n * @param contenteditable - The contenteditable element containing the nodes.\r\n * @param fromNode - The starting node to check from.\r\n * @param offsetInsideNode - The offset inside the starting node.\r\n * @param direction - The direction to check ('left' or 'right').\r\n * @returns true if adjacent content is empty, false otherwise.\r\n */\r\nexport function checkContenteditableSliceForEmptiness(contenteditable: HTMLElement, fromNode: Node, offsetInsideNode: number, direction: 'left' | 'right'): boolean {\r\n const range = document.createRange();\r\n\r\n /**\r\n * In case of \"left\":\r\n * Set range from the start of the contenteditable to the passed offset\r\n */\r\n if (direction === 'left') {\r\n range.setStart(contenteditable, 0);\r\n range.setEnd(fromNode, offsetInsideNode);\r\n\r\n /**\r\n * In case of \"right\":\r\n * Set range from the passed offset to the end of the contenteditable\r\n */\r\n } else {\r\n range.setStart(fromNode, offsetInsideNode);\r\n range.setEnd(contenteditable, contenteditable.childNodes.length);\r\n }\r\n\r\n /**\r\n * Clone the range's content and check its text content\r\n */\r\n const clonedContent = range.cloneContents();\r\n const tempDiv = document.createElement('div');\r\n\r\n tempDiv.appendChild(clonedContent);\r\n\r\n const textContent = tempDiv.textContent || '';\r\n\r\n /**\r\n * In HTML there are two types of whitespaces:\r\n * - visible ( )\r\n * - invisible (trailing spaces, tabs, etc.)\r\n *\r\n * If text contains only invisible whitespaces, it is considered to be empty\r\n */\r\n return isCollapsedWhitespaces(textContent);\r\n}\r\n\r\n/**\r\n * Checks if caret is at the start of the passed input\r\n *\r\n * Cases:\r\n * Native input:\r\n * - if offset is 0, caret is at the start\r\n * Contenteditable:\r\n * - caret at the first text node and offset is 0 — caret is at the start\r\n * - caret not at the first text node — we need to check left siblings for emptiness\r\n * - caret offset > 0, but all left part is visible (nbsp) — caret is not at the start\r\n * - caret offset > 0, but all left part is invisible (whitespaces) — caret is at the start\r\n *\r\n * @param input - input where caret should be checked\r\n */\r\nexport function isCaretAtStartOfInput(input: HTMLElement): boolean {\r\n const firstNode = $.getDeepestNode(input);\r\n\r\n if (firstNode === null || $.isEmpty(input)) {\r\n return true;\r\n }\r\n\r\n /**\r\n * In case of native input, we simply check if offset is 0\r\n */\r\n if ($.isNativeInput(firstNode)) {\r\n return (firstNode as HTMLInputElement).selectionEnd === 0;\r\n }\r\n\r\n if ($.isEmpty(input)) {\r\n return true;\r\n }\r\n\r\n const [caretNode, caretOffset] = getCaretNodeAndOffset();\r\n\r\n /**\r\n * If there is no selection, caret is not at the start\r\n */\r\n if (caretNode === null) {\r\n return false;\r\n }\r\n\r\n /**\r\n * If there is nothing visible to the left of the caret, it is considered to be at the start\r\n */\r\n return checkContenteditableSliceForEmptiness(input, caretNode, caretOffset, 'left');\r\n}\r\n\r\n/**\r\n * Checks if caret is at the end of the passed input\r\n *\r\n * Cases:\r\n * Native input:\r\n * - if offset is equal to value length, caret is at the end\r\n * Contenteditable:\r\n * - caret at the last text node and offset is equal to text length — caret is at the end\r\n * - caret not at the last text node — we need to check right siblings for emptiness\r\n * - caret offset < text length, but all right part is visible (nbsp) — caret is at the end\r\n * - caret offset < text length, but all right part is invisible (whitespaces) — caret is at the end\r\n *\r\n * @param input - input where caret should be checked\r\n */\r\nexport function isCaretAtEndOfInput(input: HTMLElement): boolean {\r\n const lastNode = $.getDeepestNode(input, true);\r\n\r\n if (lastNode === null) {\r\n return true;\r\n }\r\n\r\n /**\r\n * In case of native input, we simply check if offset is equal to value length\r\n */\r\n if ($.isNativeInput(lastNode)) {\r\n return (lastNode as HTMLInputElement).selectionEnd === (lastNode as HTMLInputElement).value.length;\r\n }\r\n\r\n const [caretNode, caretOffset] = getCaretNodeAndOffset();\r\n\r\n /**\r\n * If there is no selection, caret is not at the end\r\n */\r\n if (caretNode === null) {\r\n return false;\r\n }\r\n\r\n /**\r\n * If there is nothing visible to the right of the caret, it is considered to be at the end\r\n */\r\n return checkContenteditableSliceForEmptiness(input, caretNode, caretOffset, 'right');\r\n}\r\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.allInputsSelector = allInputsSelector;\n/**\n * Returns CSS selector for all text inputs\n */\nfunction allInputsSelector() {\n var allowedInputTypes = ['text', 'password', 'email', 'number', 'search', 'tel', 'url'];\n return '[contenteditable=true], textarea, input:not([type]), '\n + allowedInputTypes.map(function (type) { return \"input[type=\\\"\".concat(type, \"\\\"]\"); }).join(', ');\n}\n//# sourceMappingURL=allInputsSelector.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.allInputsSelector = void 0;\nvar allInputsSelector_1 = require(\"./allInputsSelector\");\nObject.defineProperty(exports, \"allInputsSelector\", { enumerable: true, get: function () { return allInputsSelector_1.allInputsSelector; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isNativeInput = isNativeInput;\n/**\n * Checks target if it is native input\n * @param target - HTML element or string\n * @returns true if target is an input element, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isNativeInput(target) {\n var nativeInputs = [\n 'INPUT',\n 'TEXTAREA',\n ];\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument\n return target && target.tagName ? nativeInputs.includes(target.tagName) : false;\n}\n//# sourceMappingURL=isNativeInput.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isNativeInput = void 0;\nvar isNativeInput_1 = require(\"./isNativeInput\");\nObject.defineProperty(exports, \"isNativeInput\", { enumerable: true, get: function () { return isNativeInput_1.isNativeInput; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.append = append;\n/**\n * Append one or several elements to the parent\n * @param parent - where to append\n * @param elements - element or elements list\n */\nfunction append(parent, elements) {\n if (Array.isArray(elements)) {\n elements.forEach(function (el) {\n parent.appendChild(el);\n });\n }\n else {\n parent.appendChild(elements);\n }\n}\n//# sourceMappingURL=append.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.append = void 0;\nvar append_1 = require(\"./append\");\nObject.defineProperty(exports, \"append\", { enumerable: true, get: function () { return append_1.append; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.blockElements = blockElements;\n/**\n * Return array of names of block html elements\n * @returns array of block element names\n */\nfunction blockElements() {\n return [\n 'address',\n 'article',\n 'aside',\n 'blockquote',\n 'canvas',\n 'div',\n 'dl',\n 'dt',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'li',\n 'main',\n 'nav',\n 'noscript',\n 'ol',\n 'output',\n 'p',\n 'pre',\n 'ruby',\n 'section',\n 'table',\n 'tbody',\n 'thead',\n 'tr',\n 'tfoot',\n 'ul',\n 'video',\n ];\n}\n//# sourceMappingURL=blockElements.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.blockElements = void 0;\nvar blockElements_1 = require(\"./blockElements\");\nObject.defineProperty(exports, \"blockElements\", { enumerable: true, get: function () { return blockElements_1.blockElements; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.calculateBaseline = calculateBaseline;\n/**\n * Calculates the Y coordinate of the text baseline from the top of the element's margin box,\n *\n * The calculation formula is as follows:\n *\n * 1. Calculate the baseline offset:\n * - Typically, the baseline is about 80% of the `fontSize` from the top of the text, as this is a common average for many fonts.\n *\n * 2. Calculate the additional space due to `lineHeight`:\n * - If the `lineHeight` is greater than the `fontSize`, the extra space is evenly distributed above and below the text. This extra space is `(lineHeight - fontSize) / 2`.\n *\n * 3. Calculate the total baseline Y coordinate:\n * - Sum of `marginTop`, `borderTopWidth`, `paddingTop`, the extra space due to `lineHeight`, and the baseline offset.\n * @param element - The element which baseline would be calculated\n * @returns - The Y coordinate of the text baseline from the top of the element's margin box.\n */\nfunction calculateBaseline(element) {\n var style = window.getComputedStyle(element);\n var fontSize = parseFloat(style.fontSize);\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\n var lineHeight = parseFloat(style.lineHeight) || fontSize * 1.2; // default line-height if not set\n var paddingTop = parseFloat(style.paddingTop);\n var borderTopWidth = parseFloat(style.borderTopWidth);\n var marginTop = parseFloat(style.marginTop);\n /**\n * Typically, the baseline is about 80% of the `fontSize` from the top of the text, as this is a common average for many fonts.\n */\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\n var baselineOffset = fontSize * 0.8;\n /**\n * If the `lineHeight` is greater than the `fontSize`, the extra space is evenly distributed above and below the text. This extra space is `(lineHeight - fontSize) / 2`.\n */\n var extraLineHeight = (lineHeight - fontSize) / 2;\n /**\n * Calculate the total baseline Y coordinate from the top of the margin box\n */\n var baselineY = marginTop + borderTopWidth + paddingTop + extraLineHeight + baselineOffset;\n return baselineY;\n}\n//# sourceMappingURL=calculateBaseline.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.calculateBaseline = void 0;\nvar calculateBaseline_1 = require(\"./calculateBaseline\");\nObject.defineProperty(exports, \"calculateBaseline\", { enumerable: true, get: function () { return calculateBaseline_1.calculateBaseline; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isContentEditable = isContentEditable;\n/**\n * Check if passed element is contenteditable\n * @param element - html element to check\n * @returns true if element is contentEditable, false otherwise\n */\nfunction isContentEditable(element) {\n return element.contentEditable === 'true';\n}\n//# sourceMappingURL=isContentEditable.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isContentEditable = void 0;\nvar isContentEditable_1 = require(\"./isContentEditable\");\nObject.defineProperty(exports, \"isContentEditable\", { enumerable: true, get: function () { return isContentEditable_1.isContentEditable; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.canSetCaret = canSetCaret;\nvar isNativeInput_1 = require(\"../isNativeInput\");\nvar isContentEditable_1 = require(\"../isContentEditable\");\n/**\n * Checks if we can set caret\n * @param target - target to check\n * @returns true if caret can be set in the target element, false otherwise\n */\nfunction canSetCaret(target) {\n var result = true;\n if ((0, isNativeInput_1.isNativeInput)(target)) {\n switch (target.type) {\n case 'file':\n case 'checkbox':\n case 'radio':\n case 'hidden':\n case 'submit':\n case 'button':\n case 'image':\n case 'reset':\n result = false;\n break;\n }\n }\n else {\n result = (0, isContentEditable_1.isContentEditable)(target);\n }\n return result;\n}\n//# sourceMappingURL=canSetCaret.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.canSetCaret = void 0;\nvar canSetCaret_1 = require(\"./canSetCaret\");\nObject.defineProperty(exports, \"canSetCaret\", { enumerable: true, get: function () { return canSetCaret_1.canSetCaret; } });\n//# sourceMappingURL=index.js.map","/**\n * Decorator which provides ability to cache method or accessor result\n * @param target - target instance or constructor function\n * @param propertyKey - method or accessor name\n * @param descriptor - property descriptor\n */\nexport function cacheable(target, propertyKey, descriptor) {\n const propertyToOverride = (descriptor.value !== undefined) ? 'value' : 'get';\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const originalMethod = descriptor[propertyToOverride];\n const cacheKey = `#${propertyKey}Cache`;\n /**\n * Override get or value descriptor property to cache return value\n * @param args - method args\n */\n descriptor[propertyToOverride] = function (...args) {\n /**\n * If there is no cache, create it\n */\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (this[cacheKey] === undefined) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n this[cacheKey] = originalMethod.apply(this, args);\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n return this[cacheKey];\n };\n /**\n * If get accessor has been overridden, we need to override set accessor to clear cache\n * @param value - value to set\n */\n if (propertyToOverride === 'get' && descriptor.set) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalSet = descriptor.set;\n descriptor.set = function (value) {\n delete target[cacheKey];\n originalSet.apply(this, value);\n };\n }\n return descriptor;\n}\n//# sourceMappingURL=cacheable.js.map","/**\n * Returns object with os name as key and boolean as value. Shows current user OS\n */\nexport function getUserOS() {\n const OS = {\n win: false,\n mac: false,\n x11: false,\n linux: false,\n };\n const userOS = Object.keys(OS).find((os) => window.navigator.appVersion.toLowerCase().indexOf(os) !== -1);\n if (userOS !== undefined) {\n OS[userOS] = true;\n return OS;\n }\n return OS;\n}\n//# sourceMappingURL=getUserOS.js.map","/**\n * True if passed variable is not null/undefined/''/{}\n * @param v value to check\n */\nexport function notEmpty(v) {\n return v !== undefined && v !== null && v !== '' && (typeof v !== 'object' || Object.keys(v).length > 0);\n}\n//# sourceMappingURL=notEmpty.js.map","import { notEmpty } from './notEmpty';\n/**\n * True if passed variable is null/undefined/''/{}\n * @param v value to check\n */\nexport function isEmpty(v) {\n return !notEmpty(v);\n}\n//# sourceMappingURL=isEmpty.js.map","import { notEmpty } from '../empty';\n/**\n * True if current device runs iOS\n */\nexport const isIosDevice = () => typeof window !== 'undefined'\n && window.navigator !== null\n && notEmpty(window.navigator.platform)\n && (/iP(ad|hone|od)/.test(window.navigator.platform)\n || (window.navigator.platform === 'MacIntel' && window.navigator.maxTouchPoints > 1));\n//# sourceMappingURL=isIosDevice.js.map","import { getUserOS } from '../userOS';\n/**\n * Make shortcut command more human-readable\n * @param shortcut — string like 'CMD+B'\n */\nexport function beautifyShortcut(shortcut) {\n const OS = getUserOS();\n shortcut = shortcut\n .replace(/shift/gi, '⇧')\n .replace(/backspace/gi, '⌫')\n .replace(/enter/gi, '⏎')\n .replace(/up/gi, '↑')\n .replace(/left/gi, '→')\n .replace(/down/gi, '↓')\n .replace(/right/gi, '←')\n .replace(/escape/gi, '⎋')\n .replace(/insert/gi, 'Ins')\n .replace(/delete/gi, '␡')\n .replace(/\\+/gi, '+');\n if (OS.mac) {\n shortcut = shortcut.replace(/ctrl|cmd/gi, '⌘').replace(/alt/gi, '⌥');\n }\n else {\n shortcut = shortcut.replace(/cmd/gi, 'Ctrl').replace(/windows/gi, 'WIN');\n }\n return shortcut;\n}\n//# sourceMappingURL=beautifyShortcut.js.map","/**\n * Capitalizes first letter of the string\n * @param text - text to be capitalized\n * @returns capitalized text string\n */\nexport function capitalize(text) {\n return text[0].toUpperCase() + text.slice(1);\n}\n//# sourceMappingURL=capitalize.js.map","/**\n * Copies passed text to the clipboard\n * @param text - text to be copied to clipboard\n */\nexport function copyTextToClipboard(text) {\n const el = document.createElement('div');\n el.style.position = 'absolute';\n el.style.left = '-999px';\n el.style.bottom = '-999px';\n el.innerHTML = text;\n document.body.appendChild(el);\n const selection = window.getSelection();\n const range = document.createRange();\n range.selectNode(el);\n if (selection === null) {\n throw new Error('Cannot copy text to clipboard');\n }\n selection.removeAllRanges();\n selection.addRange(range);\n document.execCommand('copy');\n document.body.removeChild(el);\n}\n//# sourceMappingURL=copyTextToClipboard.js.map","/**\n * Debouncing method\n * Call method after passed time\n *\n * Note that this method returns Function and declared variable need to be called\n * @param func - function that we're throttling\n * @param wait - time in milliseconds\n * @param immediate - call now\n * @returns void\n */\nexport function debounce(func, wait, immediate) {\n let timeout = undefined;\n return (...args) => {\n // eslint-disable-next-line @typescript-eslint/no-this-alias, @typescript-eslint/no-unsafe-assignment\n const context = this;\n // eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n const later = () => {\n timeout = undefined;\n if (immediate !== true) {\n func.apply(context, args);\n }\n };\n const callNow = immediate === true && timeout !== undefined;\n window.clearTimeout(timeout);\n timeout = window.setTimeout(later, wait);\n if (callNow) {\n func.apply(context, args);\n }\n };\n}\n//# sourceMappingURL=debounce.js.map","/**\n * Return string representation of the object type\n * @param object - object to get type\n * @returns string type name of the passed object\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function typeOf(object) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n return Object.prototype.toString.call(object).match(/\\s([a-zA-Z]+)/)[1].toLowerCase();\n}\n//# sourceMappingURL=typeOf.js.map","import { typeOf } from './typeOf';\n/**\n * Checks if passed argument is boolean\n * @param v - variable to check\n * @returns true, if passed v is of type boolean, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isBoolean(v) {\n return typeOf(v) === 'boolean';\n}\n//# sourceMappingURL=isBoolean.js.map","import { typeOf } from './typeOf';\n/**\n * Check if passed variable is a function\n * @param fn - function to check\n * @returns true, if passed v is of type funciton, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isFunction(fn) {\n return typeOf(fn) === 'function' || typeOf(fn) === 'asyncfunction';\n}\n//# sourceMappingURL=isFunction.js.map","import { isFunction } from './isFunction';\n/**\n * Check if passed function is a class\n * @param fn - function to check\n * @returns true, if passed fn is a class, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isClass(fn) {\n return isFunction(fn) && /^\\s*class\\s+/.test(fn.toString());\n}\n//# sourceMappingURL=isClass.js.map","import { typeOf } from './typeOf';\n/**\n * Checks if passed argument is number\n * @param v - variable to check\n * @returns true, if passed v is of type number, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isNumber(v) {\n return typeOf(v) === 'number';\n}\n//# sourceMappingURL=isNumber.js.map","import { typeOf } from './typeOf';\n/**\n * Checks if passed argument is an object\n * @param v - object to check\n * @returns true, if passed v is of type object, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isObject(v) {\n return typeOf(v) === 'object';\n}\n//# sourceMappingURL=isObject.js.map","/**\n * Check if passed object is a Promise\n * @param object - object to check\n * @returns true, if passed object is a promise, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isPromise(object) {\n return Promise.resolve(object) === object;\n}\n//# sourceMappingURL=isPromise.js.map","import { typeOf } from './typeOf';\n/**\n * Checks if passed argument is a string\n * @param v - variable to check\n * @returns true, if passed v is ot type string, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isString(v) {\n return typeOf(v) === 'string';\n}\n//# sourceMappingURL=isString.js.map","import { typeOf } from './typeOf';\n/**\n * Checks if passed argument is undefined\n * @param v - variable to check\n * @returns true, if passed v is of type undefined, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isUndefined(v) {\n return typeOf(v) === 'undefined';\n}\n//# sourceMappingURL=isUndefined.js.map","import { isObject } from '../typeOf';\n/**\n * Merge two objects recursively\n * @param target - target to be merged\n * @param sources - sources to be merged\n * @returns sourced merged with sources\n */\nexport function deepMerge(target, ...sources) {\n if (!sources.length) {\n return target;\n }\n const source = sources.shift();\n if (isObject(target) && isObject(source)) {\n for (const key in source) {\n if (isObject(source[key])) {\n if (target[key] === undefined) {\n Object.assign(target, { [key]: {} });\n }\n deepMerge(target[key], source[key]);\n }\n else {\n Object.assign(target, { [key]: source[key] });\n }\n }\n }\n return deepMerge(target, ...sources);\n}\n//# sourceMappingURL=deepMerge.js.map","/**\n * Common method for printing a warning about the usage of deprecated property or method.\n * @param condition - condition of the deprecation status.\n * @param oldProperty - deprecated property.\n * @param newProperty - the property that should be used instead.\n */\nexport function deprecationAssert(condition, oldProperty, newProperty) {\n const message = `«${oldProperty}» is deprecated and will be removed in the next major release. Please use the «${newProperty}» instead.`;\n if (condition) {\n console.warn(message);\n }\n}\n//# sourceMappingURL=deprecationAssert.js.map","/**\n * Returns valid URL. If it is going outside and valid, it returns itself\n * If url has `one slash`, then it concatenates with window location origin\n * or when url has `two lack` it appends only protocol\n * @param url - url to prettify\n */\nexport function getValidUrl(url) {\n try {\n const urlObject = new URL(url);\n return urlObject.href;\n }\n catch (e) {\n // do nothing but handle below\n }\n if (url.substring(0, 2) === '//') {\n return window.location.protocol + url;\n }\n else {\n return window.location.origin + url;\n }\n}\n//# sourceMappingURL=getValidUrl.js.map","/* eslint-disable @typescript-eslint/no-magic-numbers */\n/**\n * Returns true if passed key code is printable (a-Z, 0-9, etc) character.\n * @param keyCode - code of some key\n * @returns true, if passed keyCode is printable, false otherwise\n */\nexport function isPrintableKey(keyCode) {\n return (keyCode > 47 && keyCode < 58) // number keys\n || keyCode === 32 || keyCode === 13 // Space bar & return key(s)\n || keyCode === 229 // processing key input for certain languages — Chinese, Japanese, etc.\n || (keyCode > 64 && keyCode < 91) // letter keys\n || (keyCode > 95 && keyCode < 112) // Numpad keys\n || (keyCode > 185 && keyCode < 193) // ;=,-./` (in order)\n || (keyCode > 218 && keyCode < 223); // [\\]' (in order)\n}\n/* eslint-enable @typescript-eslint/no-magic-numbers */\n//# sourceMappingURL=isPrintableKey.js.map","/**\n * Returns basic key codes as constants\n * @returns {{}}\n */\nexport const keyCodes = {\n BACKSPACE: 8,\n TAB: 9,\n ENTER: 13,\n SHIFT: 16,\n CTRL: 17,\n ALT: 18,\n ESC: 27,\n SPACE: 32,\n LEFT: 37,\n UP: 38,\n DOWN: 40,\n RIGHT: 39,\n DELETE: 46,\n META: 91,\n SLASH: 191,\n};\n//# sourceMappingURL=keyCodes.js.map","/**\n * Return mouse buttons codes\n */\nexport const mouseButtons = {\n LEFT: 0,\n WHEEL: 1,\n RIGHT: 2,\n BACKWARD: 3,\n FORWARD: 4,\n};\n//# sourceMappingURL=mouseButtons.js.map","/**\n * Class allows to make a queue of async jobs and wait until they all will be finished one by one\n * @example const queue = new PromiseQueue();\n * queue.add(async () => { ... });\n * queue.add(async () => { ... });\n * await queue.completed;\n */\nexport class PromiseQueue {\n constructor() {\n /**\n * Queue of promises to be executed\n */\n this.completed = Promise.resolve();\n }\n /**\n * Add new promise to queue\n * @param operation - promise should be added to queue\n */\n add(operation) {\n return new Promise((resolve, reject) => {\n this.completed = this.completed\n .then(operation)\n .then(resolve)\n .catch(reject);\n });\n }\n}\n//# sourceMappingURL=promiseQueue.js.map","/**\n * Returns a function, that, when invoked, will only be triggered at most once during a given window of time.\n * @param func - function to throttle\n * @param wait - function will be called only once for that period\n * @param options - Normally, the throttled function will run as much as it can\n * without ever going more than once per `wait` duration;\n * but if you'd like to disable the execution on the leading edge, pass\n * `{leading: false}`. To disable execution on the trailing edge, ditto.\n */\nexport function throttle(func, wait, options = undefined) {\n let context;\n let args;\n let result;\n let timeout = null;\n let previous = 0;\n if (!options) {\n options = {};\n }\n const later = function () {\n previous = options.leading === false ? 0 : Date.now();\n timeout = null;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n result = func.apply(context, args);\n if (timeout === null) {\n context = args = null;\n }\n };\n return function () {\n const now = Date.now();\n if (!previous && options.leading === false) {\n previous = now;\n }\n const remaining = wait - (now - previous);\n // eslint-disable-next-line @typescript-eslint/no-this-alias, @typescript-eslint/no-unsafe-assignment\n context = this;\n args = arguments;\n if (remaining <= 0 || remaining > wait) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n previous = now;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n result = func.apply(context, args);\n if (timeout === null) {\n context = args = null;\n }\n }\n else if (!timeout && options.trailing !== false) {\n timeout = setTimeout(later, remaining);\n }\n return result;\n };\n}\n//# sourceMappingURL=throttle.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.containsOnlyInlineElements = containsOnlyInlineElements;\nvar helpers_1 = require(\"@editorjs/helpers\");\nvar blockElements_1 = require(\"../blockElements\");\n/**\n * Check if passed content includes only inline elements\n * @param data - element or html string\n * @returns true if data contains only inline elements, false otherwise\n */\nfunction containsOnlyInlineElements(data) {\n var wrapper;\n if ((0, helpers_1.isString)(data)) {\n wrapper = document.createElement('div');\n wrapper.innerHTML = data;\n }\n else {\n wrapper = data;\n }\n var check = function (element) {\n return !(0, blockElements_1.blockElements)().includes(element.tagName.toLowerCase())\n && Array.from(element.children).every(check);\n };\n return Array.from(wrapper.children).every(check);\n}\n//# sourceMappingURL=containsOnlyInlineElements.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.containsOnlyInlineElements = void 0;\nvar containsOnlyInlineElements_1 = require(\"./containsOnlyInlineElements\");\nObject.defineProperty(exports, \"containsOnlyInlineElements\", { enumerable: true, get: function () { return containsOnlyInlineElements_1.containsOnlyInlineElements; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.make = make;\n/**\n * Helper for making Elements with class name and attributes\n * @param tagName - new Element tag name\n * @param classNames - list or name of CSS class name(s)\n * @param attributes - any attributes\n * @returns created HTMLElement\n */\nfunction make(tagName, classNames, attributes) {\n var _a;\n if (classNames === void 0) { classNames = null; }\n if (attributes === void 0) { attributes = {}; }\n var el = document.createElement(tagName);\n if (Array.isArray(classNames)) {\n var validClassnames = classNames.filter(function (className) { return className !== undefined; });\n (_a = el.classList).add.apply(_a, validClassnames);\n }\n else if (classNames !== null) {\n el.classList.add(classNames);\n }\n for (var attrName in attributes) {\n if (Boolean(Object.prototype.hasOwnProperty.call(attributes, attrName))) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n el[attrName] = attributes[attrName];\n }\n }\n return el;\n}\n//# sourceMappingURL=make.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.make = void 0;\nvar make_1 = require(\"./make\");\nObject.defineProperty(exports, \"make\", { enumerable: true, get: function () { return make_1.make; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.fragmentToString = fragmentToString;\nvar make_1 = require(\"../make\");\n/**\n * Returns the HTML content of passed Document Fragment\n * @param fragment - document fragment to process\n * @returns the HTML content of passed Document Fragment\n */\nfunction fragmentToString(fragment) {\n var div = (0, make_1.make)('div');\n div.appendChild(fragment);\n return div.innerHTML;\n}\n//# sourceMappingURL=fragmentToString.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.fragmentToString = void 0;\nvar fragmentToString_1 = require(\"./fragmentToString\");\nObject.defineProperty(exports, \"fragmentToString\", { enumerable: true, get: function () { return fragmentToString_1.fragmentToString; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getContentLength = getContentLength;\nvar isNativeInput_1 = require(\"../isNativeInput\");\n/**\n * Return length of node`s text content\n * @param node - node with content, which length would be checked\n * @returns length of the content of the node\n */\nfunction getContentLength(node) {\n var _a, _b;\n if ((0, isNativeInput_1.isNativeInput)(node)) {\n return node.value.length;\n }\n if (node.nodeType === Node.TEXT_NODE) {\n return node.length;\n }\n return (_b = (_a = node.textContent) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;\n}\n//# sourceMappingURL=getContentLength.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getContentLength = void 0;\nvar getContentLength_1 = require(\"./getContentLength\");\nObject.defineProperty(exports, \"getContentLength\", { enumerable: true, get: function () { return getContentLength_1.getContentLength; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nvar __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getDeepestBlockElements = getDeepestBlockElements;\nvar containsOnlyInlineElements_1 = require(\"../containsOnlyInlineElements\");\n/**\n * Find and return all block elements in the passed parent (including subtree)\n * @param parent - root element\n * @returns deeperst block elements\n */\nfunction getDeepestBlockElements(parent) {\n if ((0, containsOnlyInlineElements_1.containsOnlyInlineElements)(parent)) {\n return [parent];\n }\n return Array.from(parent.children).reduce(function (result, element) {\n return __spreadArray(__spreadArray([], result, true), getDeepestBlockElements(element), true);\n }, []);\n}\n//# sourceMappingURL=getDeepestBlockElements.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getDeepestBlockElements = void 0;\nvar getDeepestBlockElements_1 = require(\"./getDeepestBlockElements\");\nObject.defineProperty(exports, \"getDeepestBlockElements\", { enumerable: true, get: function () { return getDeepestBlockElements_1.getDeepestBlockElements; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isLineBreakTag = isLineBreakTag;\n/**\n * Check if element is BR or WBR\n * @param element - element to check\n * @returns boolean that represents if element is a line break tag\n */\nfunction isLineBreakTag(element) {\n return [\n 'BR',\n 'WBR',\n ].includes(element.tagName);\n}\n//# sourceMappingURL=isLineBreakTag.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isLineBreakTag = void 0;\nvar isLineBreakTag_1 = require(\"./isLineBreakTag\");\nObject.defineProperty(exports, \"isLineBreakTag\", { enumerable: true, get: function () { return isLineBreakTag_1.isLineBreakTag; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isSingleTag = isSingleTag;\n/**\n * Check if passed tag has no closed tag\n * @param tag - element to check\n * @returns boolean that represents if element is a single tag\n */\nfunction isSingleTag(tag) {\n return [\n 'AREA',\n 'BASE',\n 'BR',\n 'COL',\n 'COMMAND',\n 'EMBED',\n 'HR',\n 'IMG',\n 'INPUT',\n 'KEYGEN',\n 'LINK',\n 'META',\n 'PARAM',\n 'SOURCE',\n 'TRACK',\n 'WBR',\n ].includes(tag.tagName);\n}\n//# sourceMappingURL=isSingleTag.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isSingleTag = void 0;\nvar isSingleTag_1 = require(\"./isSingleTag\");\nObject.defineProperty(exports, \"isSingleTag\", { enumerable: true, get: function () { return isSingleTag_1.isSingleTag; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getDeepestNode = getDeepestNode;\nvar isNativeInput_1 = require(\"../isNativeInput\");\nvar isLineBreakTag_1 = require(\"../isLineBreakTag\");\nvar isSingleTag_1 = require(\"../isSingleTag\");\n/**\n * Search for deepest node which is Leaf.\n * Leaf is the vertex that doesn't have any child nodes\n * @description Method recursively goes throw the all Node until it finds the Leaf\n * @param node - root Node. From this vertex we start Deep-first search\n * {@link https://en.wikipedia.org/wiki/Depth-first_search}\n * @param [atLast] - find last text node\n * @returns - it can be text Node or Element Node, so that caret will able to work with it\n * Can return null if node is Document or DocumentFragment, or node is not attached to the DOM\n */\nfunction getDeepestNode(node, atLast) {\n if (atLast === void 0) { atLast = false; }\n /**\n * Current function have two directions:\n * - starts from first child and every time gets first or nextSibling in special cases\n * - starts from last child and gets last or previousSibling\n */\n var child = atLast ? 'lastChild' : 'firstChild';\n var sibling = atLast ? 'previousSibling' : 'nextSibling';\n if (node.nodeType === Node.ELEMENT_NODE && node[child]) {\n var nodeChild = node[child];\n /**\n * special case when child is single tag that can't contain any content\n */\n if ((0, isSingleTag_1.isSingleTag)(nodeChild)\n && !(0, isNativeInput_1.isNativeInput)(nodeChild)\n && !(0, isLineBreakTag_1.isLineBreakTag)(nodeChild)) {\n /**\n * 1) We need to check the next sibling. If it is Node Element then continue searching for deepest\n * from sibling\n *\n * 2) If single tag's next sibling is null, then go back to parent and check his sibling\n * In case of Node Element continue searching\n *\n * 3) If none of conditions above happened return parent Node Element\n */\n if (nodeChild[sibling]) {\n nodeChild = nodeChild[sibling];\n }\n else if (nodeChild.parentNode !== null && nodeChild.parentNode[sibling]) {\n nodeChild = nodeChild.parentNode[sibling];\n }\n else {\n return nodeChild.parentNode;\n }\n }\n return getDeepestNode(nodeChild, atLast);\n }\n return node;\n}\n//# sourceMappingURL=getDeepestNode.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getDeepestNode = void 0;\nvar getDeepestNode_1 = require(\"./getDeepestNode\");\nObject.defineProperty(exports, \"getDeepestNode\", { enumerable: true, get: function () { return getDeepestNode_1.getDeepestNode; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nvar __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.findAllInputs = findAllInputs;\nvar containsOnlyInlineElements_1 = require(\"../containsOnlyInlineElements\");\nvar getDeepestBlockElements_1 = require(\"../getDeepestBlockElements\");\nvar allInputsSelector_1 = require(\"../allInputsSelector\");\nvar isNativeInput_1 = require(\"../isNativeInput\");\n/**\n * Find all contenteditable, textarea and editable input elements passed holder contains\n * @param holder - element where to find inputs\n * @returns - all inputs of the holder element\n */\nfunction findAllInputs(holder) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return Array.from(holder.querySelectorAll((0, allInputsSelector_1.allInputsSelector)()))\n /**\n * If contenteditable element contains block elements, treat them as inputs.\n */\n .reduce(function (result, input) {\n if ((0, isNativeInput_1.isNativeInput)(input) || (0, containsOnlyInlineElements_1.containsOnlyInlineElements)(input)) {\n return __spreadArray(__spreadArray([], result, true), [input], false);\n }\n return __spreadArray(__spreadArray([], result, true), (0, getDeepestBlockElements_1.getDeepestBlockElements)(input), true);\n }, []);\n}\n//# sourceMappingURL=findAllInputs.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.findAllInputs = void 0;\nvar findAllInputs_1 = require(\"./findAllInputs\");\nObject.defineProperty(exports, \"findAllInputs\", { enumerable: true, get: function () { return findAllInputs_1.findAllInputs; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isCollapsedWhitespaces = isCollapsedWhitespaces;\n/**\n * Determine whether a passed text content is a collapsed whitespace.\n *\n * In HTML, whitespaces at the start and end of elements and outside elements are ignored.\n * There are two types of whitespaces in HTML:\n * - Visible ( )\n * - Invisible (regular trailing spaces, tabs, etc)\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace\n * @see https://www.w3.org/TR/css-text-3/#white-space-processing\n * @param textContent — any string, for ex a textContent of a node\n * @returns True if passed text content is whitespace which is collapsed (invisible) in browser\n */\nfunction isCollapsedWhitespaces(textContent) {\n /**\n * Throughout, whitespace is defined as one of the characters\n * \"\\t\" TAB \\u0009\n * \"\\n\" LF \\u000A\n * \"\\r\" CR \\u000D\n * \" \" SPC \\u0020\n */\n return !/[^\\t\\n\\r ]/.test(textContent);\n}\n//# sourceMappingURL=isCollapsedWhitespaces.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isCollapsedWhitespaces = void 0;\nvar isCollapsedWhitespaces_1 = require(\"./isCollapsedWhitespaces\");\nObject.defineProperty(exports, \"isCollapsedWhitespaces\", { enumerable: true, get: function () { return isCollapsedWhitespaces_1.isCollapsedWhitespaces; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isElement = isElement;\nvar helpers_1 = require(\"@editorjs/helpers\");\n/**\n * Check if object is DOM node\n * @param node - object to check\n * @returns true if node is Element, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isElement(node) {\n if ((0, helpers_1.isNumber)(node)) {\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return (Boolean(node)) && (Boolean(node.nodeType)) && node.nodeType === Node.ELEMENT_NODE;\n}\n//# sourceMappingURL=isElement.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isElement = void 0;\nvar isElement_1 = require(\"./isElement\");\nObject.defineProperty(exports, \"isElement\", { enumerable: true, get: function () { return isElement_1.isElement; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isLeaf = isLeaf;\n/**\n * checks node if it is doesn't have any child nodes\n * @param node - node to check\n * @returns true if node is leaf of the node tree, false otherwise\n */\nfunction isLeaf(node) {\n if (node === null) {\n return false;\n }\n return node.childNodes.length === 0;\n}\n//# sourceMappingURL=isLeaf.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isLeaf = void 0;\nvar isLeaf_1 = require(\"./isLeaf\");\nObject.defineProperty(exports, \"isLeaf\", { enumerable: true, get: function () { return isLeaf_1.isLeaf; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isNodeEmpty = isNodeEmpty;\nvar isLineBreakTag_1 = require(\"../isLineBreakTag\");\nvar isElement_1 = require(\"../isElement\");\nvar isNativeInput_1 = require(\"../isNativeInput\");\nvar isSingleTag_1 = require(\"../isSingleTag\");\n/**\n * Checks node if it is empty\n * @description Method checks simple Node without any childs for emptiness\n * If you have Node with 2 or more children id depth, you better use {@link Dom#isEmpty} method\n * @param node - node to check\n * @param [ignoreChars] - char or substring to treat as empty\n * @returns true if it is empty\n */\nfunction isNodeEmpty(node, ignoreChars) {\n var nodeText = '';\n if ((0, isSingleTag_1.isSingleTag)(node) && !(0, isLineBreakTag_1.isLineBreakTag)(node)) {\n return false;\n }\n if ((0, isElement_1.isElement)(node) && (0, isNativeInput_1.isNativeInput)(node)) {\n nodeText = node.value;\n }\n else {\n if (node.textContent !== null) {\n nodeText = node.textContent.replace('\\u200B', '');\n }\n }\n if (ignoreChars !== undefined) {\n nodeText = nodeText.replace(new RegExp(ignoreChars, 'g'), '');\n }\n return nodeText.trim().length === 0;\n}\n//# sourceMappingURL=isNodeEmpty.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isNodeEmpty = void 0;\nvar isNodeEmpty_1 = require(\"./isNodeEmpty\");\nObject.defineProperty(exports, \"isNodeEmpty\", { enumerable: true, get: function () { return isNodeEmpty_1.isNodeEmpty; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isEmpty = isEmpty;\nvar isLeaf_1 = require(\"../isLeaf\");\nvar isNodeEmpty_1 = require(\"../isNodeEmpty\");\n/**\n * breadth-first search (BFS)\n * {@link https://en.wikipedia.org/wiki/Breadth-first_search}\n * @description Pushes to stack all DOM leafs and checks for emptiness\n * @param node - node to check\n * @param [ignoreChars] - char or substring to treat as empty\n * @returns true if node is empty (considering ignore chars), false otherwise\n */\nfunction isEmpty(node, ignoreChars) {\n /**\n * Normalize node to merge several text nodes to one to reduce tree walker iterations\n */\n node.normalize();\n var treeWalker = [node];\n while (treeWalker.length > 0) {\n var newNode = treeWalker.shift();\n if (!newNode) {\n continue;\n }\n node = newNode;\n if ((0, isLeaf_1.isLeaf)(node) && !(0, isNodeEmpty_1.isNodeEmpty)(node, ignoreChars)) {\n return false;\n }\n treeWalker.push.apply(treeWalker, Array.from(node.childNodes));\n }\n return true;\n}\n//# sourceMappingURL=isEmpty.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isEmpty = void 0;\nvar isEmpty_1 = require(\"./isEmpty\");\nObject.defineProperty(exports, \"isEmpty\", { enumerable: true, get: function () { return isEmpty_1.isEmpty; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isFragment = isFragment;\nvar helpers_1 = require(\"@editorjs/helpers\");\n/**\n * Check if object is DocumentFragment node\n * @param node - object to check\n * @returns true if node is DocumentFragment, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isFragment(node) {\n if ((0, helpers_1.isNumber)(node)) {\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return (Boolean(node)) && (Boolean(node.nodeType)) && node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;\n}\n//# sourceMappingURL=isFragment.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isFragment = void 0;\nvar isFragment_1 = require(\"./isFragment\");\nObject.defineProperty(exports, \"isFragment\", { enumerable: true, get: function () { return isFragment_1.isFragment; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isHTMLString = isHTMLString;\nvar make_1 = require(\"../make\");\n/**\n * Check if string contains html elements\n * @param str - string to check\n * @returns true if str is an html string, false otherwise\n */\nfunction isHTMLString(str) {\n var wrapper = (0, make_1.make)('div');\n wrapper.innerHTML = str;\n return wrapper.childElementCount > 0;\n}\n//# sourceMappingURL=isHtmlString.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isHTMLString = void 0;\nvar isHtmlString_1 = require(\"./isHtmlString\");\nObject.defineProperty(exports, \"isHTMLString\", { enumerable: true, get: function () { return isHtmlString_1.isHTMLString; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.offset = offset;\n/**\n * Return element's offset related to the document\n * @todo handle case when editor initialized in scrollable popup\n * @param el - element to compute offset\n */\nfunction offset(el) {\n var rect = el.getBoundingClientRect();\n var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n var scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n var top = rect.top + scrollTop;\n var left = rect.left + scrollLeft;\n return {\n top: top,\n left: left,\n bottom: top + rect.height,\n right: left + rect.width,\n };\n}\n//# sourceMappingURL=offset.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.offset = void 0;\nvar offset_1 = require(\"./offset\");\nObject.defineProperty(exports, \"offset\", { enumerable: true, get: function () { return offset_1.offset; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.prepend = prepend;\n/**\n * Append element or a couple to the beginning of the parent elements\n * @param parent - where to append\n * @param elements - element or elements list\n */\nfunction prepend(parent, elements) {\n if (Array.isArray(elements)) {\n elements = elements.reverse();\n elements.forEach(function (el) { return parent.prepend(el); });\n }\n else {\n parent.prepend(elements);\n }\n}\n//# sourceMappingURL=prepend.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.prepend = void 0;\nvar prepend_1 = require(\"./prepend\");\nObject.defineProperty(exports, \"prepend\", { enumerable: true, get: function () { return prepend_1.prepend; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.prepend = exports.offset = exports.make = exports.isLineBreakTag = exports.isSingleTag = exports.isNodeEmpty = exports.isLeaf = exports.isHTMLString = exports.isFragment = exports.isEmpty = exports.isElement = exports.isContentEditable = exports.isCollapsedWhitespaces = exports.findAllInputs = exports.isNativeInput = exports.allInputsSelector = exports.getDeepestNode = exports.getDeepestBlockElements = exports.getContentLength = exports.fragmentToString = exports.containsOnlyInlineElements = exports.canSetCaret = exports.calculateBaseline = exports.blockElements = exports.append = void 0;\nvar allInputsSelector_1 = require(\"./allInputsSelector\");\nObject.defineProperty(exports, \"allInputsSelector\", { enumerable: true, get: function () { return allInputsSelector_1.allInputsSelector; } });\nvar isNativeInput_1 = require(\"./isNativeInput\");\nObject.defineProperty(exports, \"isNativeInput\", { enumerable: true, get: function () { return isNativeInput_1.isNativeInput; } });\nvar append_1 = require(\"./append\");\nObject.defineProperty(exports, \"append\", { enumerable: true, get: function () { return append_1.append; } });\nvar blockElements_1 = require(\"./blockElements\");\nObject.defineProperty(exports, \"blockElements\", { enumerable: true, get: function () { return blockElements_1.blockElements; } });\nvar calculateBaseline_1 = require(\"./calculateBaseline\");\nObject.defineProperty(exports, \"calculateBaseline\", { enumerable: true, get: function () { return calculateBaseline_1.calculateBaseline; } });\nvar canSetCaret_1 = require(\"./canSetCaret\");\nObject.defineProperty(exports, \"canSetCaret\", { enumerable: true, get: function () { return canSetCaret_1.canSetCaret; } });\nvar containsOnlyInlineElements_1 = require(\"./containsOnlyInlineElements\");\nObject.defineProperty(exports, \"containsOnlyInlineElements\", { enumerable: true, get: function () { return containsOnlyInlineElements_1.containsOnlyInlineElements; } });\nvar fragmentToString_1 = require(\"./fragmentToString\");\nObject.defineProperty(exports, \"fragmentToString\", { enumerable: true, get: function () { return fragmentToString_1.fragmentToString; } });\nvar getContentLength_1 = require(\"./getContentLength\");\nObject.defineProperty(exports, \"getContentLength\", { enumerable: true, get: function () { return getContentLength_1.getContentLength; } });\nvar getDeepestBlockElements_1 = require(\"./getDeepestBlockElements\");\nObject.defineProperty(exports, \"getDeepestBlockElements\", { enumerable: true, get: function () { return getDeepestBlockElements_1.getDeepestBlockElements; } });\nvar getDeepestNode_1 = require(\"./getDeepestNode\");\nObject.defineProperty(exports, \"getDeepestNode\", { enumerable: true, get: function () { return getDeepestNode_1.getDeepestNode; } });\nvar findAllInputs_1 = require(\"./findAllInputs\");\nObject.defineProperty(exports, \"findAllInputs\", { enumerable: true, get: function () { return findAllInputs_1.findAllInputs; } });\nvar isCollapsedWhitespaces_1 = require(\"./isCollapsedWhitespaces\");\nObject.defineProperty(exports, \"isCollapsedWhitespaces\", { enumerable: true, get: function () { return isCollapsedWhitespaces_1.isCollapsedWhitespaces; } });\nvar isContentEditable_1 = require(\"./isContentEditable\");\nObject.defineProperty(exports, \"isContentEditable\", { enumerable: true, get: function () { return isContentEditable_1.isContentEditable; } });\nvar isElement_1 = require(\"./isElement\");\nObject.defineProperty(exports, \"isElement\", { enumerable: true, get: function () { return isElement_1.isElement; } });\nvar isEmpty_1 = require(\"./isEmpty\");\nObject.defineProperty(exports, \"isEmpty\", { enumerable: true, get: function () { return isEmpty_1.isEmpty; } });\nvar isFragment_1 = require(\"./isFragment\");\nObject.defineProperty(exports, \"isFragment\", { enumerable: true, get: function () { return isFragment_1.isFragment; } });\nvar isHtmlString_1 = require(\"./isHtmlString\");\nObject.defineProperty(exports, \"isHTMLString\", { enumerable: true, get: function () { return isHtmlString_1.isHTMLString; } });\nvar isLeaf_1 = require(\"./isLeaf\");\nObject.defineProperty(exports, \"isLeaf\", { enumerable: true, get: function () { return isLeaf_1.isLeaf; } });\nvar isNodeEmpty_1 = require(\"./isNodeEmpty\");\nObject.defineProperty(exports, \"isNodeEmpty\", { enumerable: true, get: function () { return isNodeEmpty_1.isNodeEmpty; } });\nvar isLineBreakTag_1 = require(\"./isLineBreakTag\");\nObject.defineProperty(exports, \"isLineBreakTag\", { enumerable: true, get: function () { return isLineBreakTag_1.isLineBreakTag; } });\nvar isSingleTag_1 = require(\"./isSingleTag\");\nObject.defineProperty(exports, \"isSingleTag\", { enumerable: true, get: function () { return isSingleTag_1.isSingleTag; } });\nvar make_1 = require(\"./make\");\nObject.defineProperty(exports, \"make\", { enumerable: true, get: function () { return make_1.make; } });\nvar offset_1 = require(\"./offset\");\nObject.defineProperty(exports, \"offset\", { enumerable: true, get: function () { return offset_1.offset; } });\nvar prepend_1 = require(\"./prepend\");\nObject.defineProperty(exports, \"prepend\", { enumerable: true, get: function () { return prepend_1.prepend; } });\n//# sourceMappingURL=index.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getContenteditableSlice = getContenteditableSlice;\nvar dom_1 = require(\"@editorjs/dom\");\n/**\n * Returns slice of the contenteditable html element from caret position to the start or end (depending on direction)\n * @param contenteditable - The contenteditable element containing the nodes.\n * @param fromNode - The starting node to check from.\n * @param offsetInsideNode - The offset inside the starting node.\n * @param direction - The direction to check ('left' or 'right').\n * @param extract - should we remove from element extracted part\n * @returns true if adjacent content is empty, false otherwise.\n */\nfunction getContenteditableSlice(contenteditable, fromNode, offsetInsideNode, direction, extract) {\n var _a;\n if (extract === void 0) { extract = false; }\n var range = document.createRange();\n /**\n * In case of \"left\":\n * Set range from the start of the contenteditable to the passed offset\n */\n if (direction === 'left') {\n range.setStart(contenteditable, 0);\n range.setEnd(fromNode, offsetInsideNode);\n /**\n * In case of \"right\":\n * Set range from the passed offset to the end of the contenteditable\n */\n }\n else {\n range.setStart(fromNode, offsetInsideNode);\n range.setEnd(contenteditable, contenteditable.childNodes.length);\n }\n /**\n * Check if we should extract content from the range\n */\n if (extract === true) {\n var textContent_1 = range.extractContents();\n return (0, dom_1.fragmentToString)(textContent_1);\n }\n /**\n * Clone the range's content and check its text content\n */\n var clonedContent = range.cloneContents();\n var tempDiv = document.createElement('div');\n tempDiv.appendChild(clonedContent);\n var textContent = (_a = tempDiv.textContent) !== null && _a !== void 0 ? _a : '';\n /**\n * In HTML there are two types of whitespaces:\n * - visible ( )\n * - invisible (trailing spaces, tabs, etc.)\n *\n * If text contains only invisible whitespaces, it is considered to be empty\n */\n return textContent;\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.checkContenteditableSliceForEmptiness = checkContenteditableSliceForEmptiness;\nvar dom_1 = require(\"@editorjs/dom\");\nvar getContenteditableSlice_1 = require(\"../getContenteditableSlice/getContenteditableSlice\");\n/**\n * Checks content at left or right of the passed node for emptiness.\n * @param contenteditable - The contenteditable element containing the nodes.\n * @param fromNode - The starting node to check from.\n * @param offsetInsideNode - The offset inside the starting node.\n * @param direction - The direction to check ('left' or 'right').\n * @returns true if adjacent content is empty, false otherwise.\n */\nfunction checkContenteditableSliceForEmptiness(contenteditable, fromNode, offsetInsideNode, direction) {\n /**\n * Get content editable slice\n */\n var textContent = (0, getContenteditableSlice_1.getContenteditableSlice)(contenteditable, fromNode, offsetInsideNode, direction);\n /**\n * Check extracted slice for emptiness\n */\n return (0, dom_1.isCollapsedWhitespaces)(textContent);\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.checkContenteditableSliceForEmptiness = void 0;\nvar checkContenteditableSliceForEmptiness_1 = require(\"./checkContenteditableSliceForEmptiness\");\nObject.defineProperty(exports, \"checkContenteditableSliceForEmptiness\", { enumerable: true, get: function () { return checkContenteditableSliceForEmptiness_1.checkContenteditableSliceForEmptiness; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getContenteditableSlice = void 0;\nvar getContenteditableSlice_1 = require(\"./getContenteditableSlice\");\nObject.defineProperty(exports, \"getContenteditableSlice\", { enumerable: true, get: function () { return getContenteditableSlice_1.getContenteditableSlice; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.focus = focus;\nvar dom_1 = require(\"@editorjs/dom\");\n/**\n * Set focus to contenteditable or native input element\n * @param element - element where to set focus\n * @param atStart - where to set focus: at the start or at the end\n */\nfunction focus(element, atStart) {\n var _a, _b;\n if (atStart === void 0) { atStart = true; }\n /** If element is native input */\n if ((0, dom_1.isNativeInput)(element)) {\n element.focus();\n var position = atStart ? 0 : element.value.length;\n element.setSelectionRange(position, position);\n }\n else {\n var range_1 = document.createRange();\n var selection = window.getSelection();\n if (!selection) {\n return;\n }\n /**\n * Helper function to create a new text node and set the caret\n * @param parent - parent element to append the text node\n * @param prepend - should the text node be prepended or appended\n */\n var createAndFocusTextNode = function (parent, prepend) {\n if (prepend === void 0) { prepend = false; }\n var textNode = document.createTextNode('');\n if (prepend) {\n parent.insertBefore(textNode, parent.firstChild);\n }\n else {\n parent.appendChild(textNode);\n }\n range_1.setStart(textNode, 0);\n range_1.setEnd(textNode, 0);\n };\n /**\n * Helper for checking for null and undefined\n * @param v - value to check\n */\n var isDefinedAndNotNull = function (v) { return v !== undefined && v !== null; };\n /**\n * We need to set focus at start/end to the text node inside an element\n */\n var childNodes = element.childNodes;\n var nodeToFocus = atStart ? childNodes[0] : childNodes[childNodes.length - 1];\n if (isDefinedAndNotNull(nodeToFocus)) {\n /**\n * Ensure the nodeToFocus is a text node,\n * if it's not, drill down to find a text node\n */\n while (isDefinedAndNotNull(nodeToFocus) && nodeToFocus.nodeType !== Node.TEXT_NODE) {\n nodeToFocus = atStart ? nodeToFocus.firstChild : nodeToFocus.lastChild;\n }\n /**\n * If a text node is found, place the caret\n */\n if (isDefinedAndNotNull(nodeToFocus) && nodeToFocus.nodeType === Node.TEXT_NODE) {\n var length_1 = (_b = (_a = nodeToFocus.textContent) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;\n var position = atStart ? 0 : length_1;\n range_1.setStart(nodeToFocus, position);\n range_1.setEnd(nodeToFocus, position);\n }\n else {\n /**\n * If no text node is found, create one and set focus\n */\n createAndFocusTextNode(element, atStart);\n }\n }\n else {\n /**\n * If the element is empty, create a text node and place the caret at the start\n */\n createAndFocusTextNode(element);\n }\n selection.removeAllRanges();\n selection.addRange(range_1);\n }\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.focus = void 0;\nvar focus_1 = require(\"./focus\");\nObject.defineProperty(exports, \"focus\", { enumerable: true, get: function () { return focus_1.focus; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getCaretNodeAndOffset = getCaretNodeAndOffset;\n/**\n * Returns TextNode containing a caret and a caret offset in it\n * Returns null if there is no caret set\n *\n * Handles a case when focusNode is an ElementNode and focusOffset is a child index,\n * returns child node with focusOffset index as a new focusNode\n */\nfunction getCaretNodeAndOffset() {\n var selection = window.getSelection();\n if (selection === null) {\n return [null, 0];\n }\n var focusNode = selection.focusNode;\n var focusOffset = selection.focusOffset;\n if (focusNode === null) {\n return [null, 0];\n }\n /**\n * Case when focusNode is an Element (or Document). In this case, focusOffset is a child index.\n * We need to return child with focusOffset index as a new focusNode.\n *\n * <div>|hello</div> <---- Selection references to <div> instead of text node\n *\n *\n */\n if (focusNode.nodeType !== Node.TEXT_NODE && focusNode.childNodes.length > 0) {\n /**\n * In normal cases, focusOffset is a child index.\n */\n if (focusNode.childNodes[focusOffset] !== undefined) {\n focusNode = focusNode.childNodes[focusOffset];\n focusOffset = 0;\n /**\n * But in Firefox, focusOffset can be 1 with the single child.\n */\n }\n else {\n focusNode = focusNode.childNodes[focusOffset - 1];\n if (focusNode.textContent !== null) {\n focusOffset = focusNode.textContent.length;\n }\n }\n }\n return [focusNode, focusOffset];\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getCaretNodeAndOffset = void 0;\nvar getCaretNodeAndOffset_1 = require(\"./getCaretNodeAndOffset\");\nObject.defineProperty(exports, \"getCaretNodeAndOffset\", { enumerable: true, get: function () { return getCaretNodeAndOffset_1.getCaretNodeAndOffset; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getRange = getRange;\n/**\n * Returns the first range\n * @returns range of the caret if it exists, null otherwise\n */\nfunction getRange() {\n var selection = window.getSelection();\n return selection && selection.rangeCount ? selection.getRangeAt(0) : null;\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getRange = void 0;\nvar getRange_1 = require(\"./getRange\");\nObject.defineProperty(exports, \"getRange\", { enumerable: true, get: function () { return getRange_1.getRange; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isCaretAtEndOfInput = isCaretAtEndOfInput;\nvar dom_1 = require(\"@editorjs/dom\");\nvar getCaretNodeAndOffset_1 = require(\"../getCaretNodeAndOffset\");\nvar checkContenteditableSliceForEmptiness_1 = require(\"../checkContenteditableSliceForEmptiness\");\n/**\n * Checks if caret is at the end of the passed input\n *\n * Cases:\n * Native input:\n * - if offset is equal to value length, caret is at the end\n * Contenteditable:\n * - caret at the last text node and offset is equal to text length — caret is at the end\n * - caret not at the last text node — we need to check right siblings for emptiness\n * - caret offset < text length, but all right part is visible (nbsp) — caret is at the end\n * - caret offset < text length, but all right part is invisible (whitespaces) — caret is at the end\n * @param input - input where caret should be checked\n */\nfunction isCaretAtEndOfInput(input) {\n var lastNode = (0, dom_1.getDeepestNode)(input, true);\n if (lastNode === null) {\n return true;\n }\n /**\n * In case of native input, we simply check if offset is equal to value length\n */\n if ((0, dom_1.isNativeInput)(lastNode)) {\n return lastNode.selectionEnd === lastNode.value.length;\n }\n var _a = (0, getCaretNodeAndOffset_1.getCaretNodeAndOffset)(), caretNode = _a[0], caretOffset = _a[1];\n /**\n * If there is no selection, caret is not at the end\n */\n if (caretNode === null) {\n return false;\n }\n /**\n * If there is nothing visible to the right of the caret, it is considered to be at the end\n */\n return (0, checkContenteditableSliceForEmptiness_1.checkContenteditableSliceForEmptiness)(input, caretNode, caretOffset, 'right');\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isCaretAtEndOfInput = void 0;\nvar isCaretAtEndOfInput_1 = require(\"./isCaretAtEndOfInput\");\nObject.defineProperty(exports, \"isCaretAtEndOfInput\", { enumerable: true, get: function () { return isCaretAtEndOfInput_1.isCaretAtEndOfInput; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isCaretAtStartOfInput = isCaretAtStartOfInput;\nvar dom_1 = require(\"@editorjs/dom\");\nvar getCaretNodeAndOffset_1 = require(\"../getCaretNodeAndOffset/getCaretNodeAndOffset\");\nvar checkContenteditableSliceForEmptiness_1 = require(\"../checkContenteditableSliceForEmptiness/checkContenteditableSliceForEmptiness\");\n/**\n * Checks if caret is at the start of the passed input\n *\n * Cases:\n * Native input:\n * - if offset is 0, caret is at the start\n * Contenteditable:\n * - caret at the first text node and offset is 0 — caret is at the start\n * - caret not at the first text node — we need to check left siblings for emptiness\n * - caret offset > 0, but all left part is visible (nbsp) — caret is not at the start\n * - caret offset > 0, but all left part is invisible (whitespaces) — caret is at the start\n * @param input - input where caret should be checked\n */\nfunction isCaretAtStartOfInput(input) {\n var firstNode = (0, dom_1.getDeepestNode)(input);\n if (firstNode === null || (0, dom_1.isEmpty)(input)) {\n return true;\n }\n /**\n * In case of native input, we simply check if offset is 0\n */\n if ((0, dom_1.isNativeInput)(firstNode)) {\n return firstNode.selectionEnd === 0;\n }\n if ((0, dom_1.isEmpty)(input)) {\n return true;\n }\n var _a = (0, getCaretNodeAndOffset_1.getCaretNodeAndOffset)(), caretNode = _a[0], caretOffset = _a[1];\n /**\n * If there is no selection, caret is not at the start\n */\n if (caretNode === null) {\n return false;\n }\n /**\n * If there is nothing visible to the left of the caret, it is considered to be at the start\n */\n return (0, checkContenteditableSliceForEmptiness_1.checkContenteditableSliceForEmptiness)(input, caretNode, caretOffset, 'left');\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isCaretAtStartOfInput = void 0;\nvar isCaretAtStartOfInput_1 = require(\"./isCaretAtStartOfInput\");\nObject.defineProperty(exports, \"isCaretAtStartOfInput\", { enumerable: true, get: function () { return isCaretAtStartOfInput_1.isCaretAtStartOfInput; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.save = save;\nvar dom_1 = require(\"@editorjs/dom\");\nvar getRange_1 = require(\"../getRange/getRange\");\n/**\n * Saves caret position using hidden <span>\n * @returns function for resoring the caret\n */\nfunction save() {\n var range = (0, getRange_1.getRange)();\n var caret = (0, dom_1.make)('span');\n caret.id = 'cursor';\n caret.hidden = true;\n if (!range) {\n return;\n }\n range.insertNode(caret);\n /**\n * Return funciton that will restore caret and delete temporary span element\n */\n return function restore() {\n var sel = window.getSelection();\n if (!sel) {\n return;\n }\n range.setStartAfter(caret);\n range.setEndAfter(caret);\n sel.removeAllRanges();\n sel.addRange(range);\n /**\n * A little timeout uses to allow browser to set caret after element before we remove it.\n */\n setTimeout(function () {\n caret.remove();\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\n }, 150);\n };\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.save = void 0;\nvar save_1 = require(\"./save\");\nObject.defineProperty(exports, \"save\", { enumerable: true, get: function () { return save_1.save; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.save = exports.isCaretAtStartOfInput = exports.isCaretAtEndOfInput = exports.getRange = exports.getCaretNodeAndOffset = exports.focus = exports.getContenteditableSlice = exports.checkContenteditableSliceForEmptiness = void 0;\nvar checkContenteditableSliceForEmptiness_1 = require(\"./checkContenteditableSliceForEmptiness\");\nObject.defineProperty(exports, \"checkContenteditableSliceForEmptiness\", { enumerable: true, get: function () { return checkContenteditableSliceForEmptiness_1.checkContenteditableSliceForEmptiness; } });\nvar getContenteditableSlice_1 = require(\"./getContenteditableSlice\");\nObject.defineProperty(exports, \"getContenteditableSlice\", { enumerable: true, get: function () { return getContenteditableSlice_1.getContenteditableSlice; } });\nvar focus_1 = require(\"./focus\");\nObject.defineProperty(exports, \"focus\", { enumerable: true, get: function () { return focus_1.focus; } });\nvar getCaretNodeAndOffset_1 = require(\"./getCaretNodeAndOffset\");\nObject.defineProperty(exports, \"getCaretNodeAndOffset\", { enumerable: true, get: function () { return getCaretNodeAndOffset_1.getCaretNodeAndOffset; } });\nvar getRange_1 = require(\"./getRange\");\nObject.defineProperty(exports, \"getRange\", { enumerable: true, get: function () { return getRange_1.getRange; } });\nvar isCaretAtEndOfInput_1 = require(\"./isCaretAtEndOfInput\");\nObject.defineProperty(exports, \"isCaretAtEndOfInput\", { enumerable: true, get: function () { return isCaretAtEndOfInput_1.isCaretAtEndOfInput; } });\nvar isCaretAtStartOfInput_1 = require(\"./isCaretAtStartOfInput\");\nObject.defineProperty(exports, \"isCaretAtStartOfInput\", { enumerable: true, get: function () { return isCaretAtStartOfInput_1.isCaretAtStartOfInput; } });\nvar save_1 = require(\"./save\");\nObject.defineProperty(exports, \"save\", { enumerable: true, get: function () { return save_1.save; } });\n","/**\r\n * Contains keyboard and mouse events bound on each Block by Block Manager\r\n */\r\nimport Module from '../__module';\r\nimport * as _ from '../utils';\r\nimport SelectionUtils from '../selection';\r\nimport Flipper from '../flipper';\r\nimport type Block from '../block';\r\nimport { areBlocksMergeable } from '../utils/blocks';\r\nimport * as caretUtils from '../utils/caret';\r\nimport { focus } from '@editorjs/caret';\r\n\r\n/**\r\n *\r\n */\r\nexport default class BlockEvents extends Module {\r\n /**\r\n * All keydowns on Block\r\n *\r\n * @param {KeyboardEvent} event - keydown\r\n */\r\n public keydown(event: KeyboardEvent): void {\r\n /**\r\n * Run common method for all keydown events\r\n */\r\n this.beforeKeydownProcessing(event);\r\n\r\n /**\r\n * Fire keydown processor by event.keyCode\r\n */\r\n switch (event.keyCode) {\r\n case _.keyCodes.BACKSPACE:\r\n this.backspace(event);\r\n break;\r\n\r\n case _.keyCodes.DELETE:\r\n this.delete(event);\r\n break;\r\n\r\n case _.keyCodes.ENTER:\r\n this.enter(event);\r\n break;\r\n\r\n case _.keyCodes.DOWN:\r\n case _.keyCodes.RIGHT:\r\n this.arrowRightAndDown(event);\r\n break;\r\n\r\n case _.keyCodes.UP:\r\n case _.keyCodes.LEFT:\r\n this.arrowLeftAndUp(event);\r\n break;\r\n\r\n case _.keyCodes.TAB:\r\n this.tabPressed(event);\r\n break;\r\n }\r\n\r\n /**\r\n * We check for \"key\" here since on different keyboard layouts \"/\" can be typed as \"Shift + 7\" etc\r\n *\r\n * @todo probably using \"beforeInput\" event would be better here\r\n */\r\n if (event.key === '/' && !event.ctrlKey && !event.metaKey) {\r\n this.slashPressed(event);\r\n }\r\n\r\n /**\r\n * If user pressed \"Ctrl + /\" or \"Cmd + /\" — open Block Settings\r\n * We check for \"code\" here since on different keyboard layouts there can be different keys in place of Slash.\r\n */\r\n if (event.code === 'Slash' && (event.ctrlKey || event.metaKey)) {\r\n event.preventDefault();\r\n this.commandSlashPressed();\r\n }\r\n }\r\n\r\n /**\r\n * Fires on keydown before event processing\r\n *\r\n * @param {KeyboardEvent} event - keydown\r\n */\r\n public beforeKeydownProcessing(event: KeyboardEvent): void {\r\n /**\r\n * Do not close Toolbox on Tabs or on Enter with opened Toolbox\r\n */\r\n if (!this.needToolbarClosing(event)) {\r\n return;\r\n }\r\n\r\n /**\r\n * When user type something:\r\n * - close Toolbar\r\n * - clear block highlighting\r\n */\r\n if (_.isPrintableKey(event.keyCode)) {\r\n this.Editor.Toolbar.close();\r\n\r\n /**\r\n * Allow to use shortcuts with selected blocks\r\n *\r\n * @type {boolean}\r\n */\r\n const isShortcut = event.ctrlKey || event.metaKey || event.altKey || event.shiftKey;\r\n\r\n if (!isShortcut) {\r\n this.Editor.BlockSelection.clearSelection(event);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Key up on Block:\r\n * - shows Inline Toolbar if something selected\r\n * - shows conversion toolbar with 85% of block selection\r\n *\r\n * @param {KeyboardEvent} event - keyup event\r\n */\r\n public keyup(event: KeyboardEvent): void {\r\n /**\r\n * If shift key was pressed some special shortcut is used (eg. cross block selection via shift + arrows)\r\n */\r\n if (event.shiftKey) {\r\n return;\r\n }\r\n\r\n /**\r\n * Check if editor is empty on each keyup and add special css class to wrapper\r\n */\r\n this.Editor.UI.checkEmptiness();\r\n }\r\n\r\n /**\r\n * Add drop target styles\r\n *\r\n * @param {DragEvent} event - drag over event\r\n */\r\n public dragOver(event: DragEvent): void {\r\n const block = this.Editor.BlockManager.getBlockByChildNode(event.target as Node);\r\n\r\n block.dropTarget = true;\r\n }\r\n\r\n /**\r\n * Remove drop target style\r\n *\r\n * @param {DragEvent} event - drag leave event\r\n */\r\n public dragLeave(event: DragEvent): void {\r\n const block = this.Editor.BlockManager.getBlockByChildNode(event.target as Node);\r\n\r\n block.dropTarget = false;\r\n }\r\n\r\n /**\r\n * Copying selected blocks\r\n * Before putting to the clipboard we sanitize all blocks and then copy to the clipboard\r\n *\r\n * @param {ClipboardEvent} event - clipboard event\r\n */\r\n public handleCommandC(event: ClipboardEvent): void {\r\n const { BlockSelection } = this.Editor;\r\n\r\n if (!BlockSelection.anyBlockSelected) {\r\n return;\r\n }\r\n\r\n // Copy Selected Blocks\r\n BlockSelection.copySelectedBlocks(event);\r\n }\r\n\r\n /**\r\n * Copy and Delete selected Blocks\r\n *\r\n * @param {ClipboardEvent} event - clipboard event\r\n */\r\n public handleCommandX(event: ClipboardEvent): void {\r\n const { BlockSelection, BlockManager, Caret } = this.Editor;\r\n\r\n if (!BlockSelection.anyBlockSelected) {\r\n return;\r\n }\r\n\r\n BlockSelection.copySelectedBlocks(event).then(() => {\r\n const selectionPositionIndex = BlockManager.removeSelectedBlocks();\r\n\r\n /**\r\n * Insert default block in place of removed ones\r\n */\r\n const insertedBlock = BlockManager.insertDefaultBlockAtIndex(selectionPositionIndex, true);\r\n\r\n Caret.setToBlock(insertedBlock, Caret.positions.START);\r\n\r\n /** Clear selection */\r\n BlockSelection.clearSelection(event);\r\n });\r\n }\r\n\r\n /**\r\n * Tab pressed inside a Block.\r\n *\r\n * @param {KeyboardEvent} event - keydown\r\n */\r\n private tabPressed(event: KeyboardEvent): void {\r\n const { InlineToolbar, Caret } = this.Editor;\r\n\r\n const isFlipperActivated = InlineToolbar.opened;\r\n\r\n if (isFlipperActivated) {\r\n return;\r\n }\r\n\r\n const isNavigated = event.shiftKey ? Caret.navigatePrevious(true) : Caret.navigateNext(true);\r\n\r\n /**\r\n * If we have next Block/input to focus, then focus it. Otherwise, leave native Tab behaviour\r\n */\r\n if (isNavigated) {\r\n event.preventDefault();\r\n }\r\n }\r\n\r\n /**\r\n * '/' + 'command' keydown inside a Block\r\n */\r\n private commandSlashPressed(): void {\r\n if (this.Editor.BlockSelection.selectedBlocks.length > 1) {\r\n return;\r\n }\r\n\r\n this.activateBlockSettings();\r\n }\r\n\r\n /**\r\n * '/' keydown inside a Block\r\n *\r\n * @param event - keydown\r\n */\r\n private slashPressed(event: KeyboardEvent): void {\r\n const wasEventTriggeredInsideEditor = this.Editor.UI.nodes.wrapper.contains(event.target as Node);\r\n\r\n if (!wasEventTriggeredInsideEditor) {\r\n return;\r\n }\r\n\r\n const currentBlock = this.Editor.BlockManager.currentBlock;\r\n const canOpenToolbox = currentBlock.isEmpty;\r\n\r\n /**\r\n * @todo Handle case when slash pressed when several blocks are selected\r\n */\r\n\r\n /**\r\n * Toolbox will be opened only if Block is empty\r\n */\r\n if (!canOpenToolbox) {\r\n return;\r\n }\r\n\r\n /**\r\n * The Toolbox will be opened with immediate focus on the Search input,\r\n * and '/' will be added in the search input by default — we need to prevent it and add '/' manually\r\n */\r\n event.preventDefault();\r\n this.Editor.Caret.insertContentAtCaretPosition('/');\r\n\r\n this.activateToolbox();\r\n }\r\n\r\n /**\r\n * ENTER pressed on block\r\n *\r\n * @param {KeyboardEvent} event - keydown\r\n */\r\n private enter(event: KeyboardEvent): void {\r\n const { BlockManager, UI } = this.Editor;\r\n const currentBlock = BlockManager.currentBlock;\r\n\r\n if (currentBlock === undefined) {\r\n return;\r\n }\r\n\r\n /**\r\n * Don't handle Enter keydowns when Tool sets enableLineBreaks to true.\r\n * Uses for Tools like <code> where line breaks should be handled by default behaviour.\r\n */\r\n if (currentBlock.tool.isLineBreaksEnabled) {\r\n return;\r\n }\r\n\r\n /**\r\n * Opened Toolbars uses Flipper with own Enter handling\r\n * Allow split block when no one button in Flipper is focused\r\n */\r\n if (UI.someToolbarOpened && UI.someFlipperButtonFocused) {\r\n return;\r\n }\r\n\r\n /**\r\n * Allow to create line breaks by Shift+Enter\r\n *\r\n * Note. On iOS devices, Safari automatically treats enter after a period+space (\". |\") as Shift+Enter\r\n * (it used for capitalizing of the first letter of the next sentence)\r\n * We don't need to lead soft line break in this case — new block should be created\r\n */\r\n if (event.shiftKey && !_.isIosDevice) {\r\n return;\r\n }\r\n\r\n let blockToFocus = currentBlock;\r\n\r\n /**\r\n * If enter has been pressed at the start of the text, just insert paragraph Block above\r\n */\r\n if (currentBlock.currentInput !== undefined && caretUtils.isCaretAtStartOfInput(currentBlock.currentInput) && !currentBlock.hasMedia) {\r\n this.Editor.BlockManager.insertDefaultBlockAtIndex(this.Editor.BlockManager.currentBlockIndex);\r\n\r\n /**\r\n * If caret is at very end of the block, just append the new block without splitting\r\n * to prevent unnecessary dom mutation observing\r\n */\r\n } else if (currentBlock.currentInput && caretUtils.isCaretAtEndOfInput(currentBlock.currentInput)) {\r\n blockToFocus = this.Editor.BlockManager.insertDefaultBlockAtIndex(this.Editor.BlockManager.currentBlockIndex + 1);\r\n } else {\r\n /**\r\n * Split the Current Block into two blocks\r\n * Renew local current node after split\r\n */\r\n blockToFocus = this.Editor.BlockManager.split();\r\n }\r\n\r\n this.Editor.Caret.setToBlock(blockToFocus);\r\n\r\n /**\r\n * Show Toolbar\r\n */\r\n this.Editor.Toolbar.moveAndOpen(blockToFocus);\r\n\r\n event.preventDefault();\r\n }\r\n\r\n /**\r\n * Handle backspace keydown on Block\r\n *\r\n * @param {KeyboardEvent} event - keydown\r\n */\r\n private backspace(event: KeyboardEvent): void {\r\n const { BlockManager, Caret } = this.Editor;\r\n const { currentBlock, previousBlock } = BlockManager;\r\n\r\n if (currentBlock === undefined) {\r\n return;\r\n }\r\n\r\n /**\r\n * If some fragment is selected, leave native behaviour\r\n */\r\n if (!SelectionUtils.isCollapsed) {\r\n return;\r\n }\r\n\r\n /**\r\n * If caret is not at the start, leave native behaviour\r\n */\r\n if (!currentBlock.currentInput || !caretUtils.isCaretAtStartOfInput(currentBlock.currentInput)) {\r\n return;\r\n }\r\n /**\r\n * All the cases below have custom behaviour, so we don't need a native one\r\n */\r\n event.preventDefault();\r\n this.Editor.Toolbar.close();\r\n\r\n const isFirstInputFocused = currentBlock.currentInput === currentBlock.firstInput;\r\n\r\n /**\r\n * For example, caret at the start of the Quote second input (caption) — just navigate previous input\r\n */\r\n if (!isFirstInputFocused) {\r\n Caret.navigatePrevious();\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Backspace at the start of the first Block should do nothing\r\n */\r\n if (previousBlock === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * If prev Block is empty, it should be removed just like a character\r\n */\r\n if (previousBlock.isEmpty) {\r\n BlockManager.removeBlock(previousBlock);\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * If current Block is empty, just remove it and set cursor to the previous Block (like we're removing line break char)\r\n */\r\n if (currentBlock.isEmpty) {\r\n BlockManager.removeBlock(currentBlock);\r\n\r\n const newCurrentBlock = BlockManager.currentBlock;\r\n\r\n Caret.setToBlock(newCurrentBlock, Caret.positions.END);\r\n\r\n return;\r\n }\r\n\r\n const bothBlocksMergeable = areBlocksMergeable(previousBlock, currentBlock);\r\n\r\n /**\r\n * If Blocks could be merged, do it\r\n * Otherwise, just navigate previous block\r\n */\r\n if (bothBlocksMergeable) {\r\n this.mergeBlocks(previousBlock, currentBlock);\r\n } else {\r\n Caret.setToBlock(previousBlock, Caret.positions.END);\r\n }\r\n }\r\n\r\n /**\r\n * Handles delete keydown on Block\r\n * Removes char after the caret.\r\n * If caret is at the end of the block, merge next block with current\r\n *\r\n * @param {KeyboardEvent} event - keydown\r\n */\r\n private delete(event: KeyboardEvent): void {\r\n const { BlockManager, Caret } = this.Editor;\r\n const { currentBlock, nextBlock } = BlockManager;\r\n\r\n /**\r\n * If some fragment is selected, leave native behaviour\r\n */\r\n if (!SelectionUtils.isCollapsed) {\r\n return;\r\n }\r\n\r\n /**\r\n * If caret is not at the end, leave native behaviour\r\n */\r\n if (!caretUtils.isCaretAtEndOfInput(currentBlock.currentInput)) {\r\n return;\r\n }\r\n\r\n /**\r\n * All the cases below have custom behaviour, so we don't need a native one\r\n */\r\n event.preventDefault();\r\n this.Editor.Toolbar.close();\r\n\r\n const isLastInputFocused = currentBlock.currentInput === currentBlock.lastInput;\r\n\r\n /**\r\n * For example, caret at the end of the Quote first input (quote text) — just navigate next input (caption)\r\n */\r\n if (!isLastInputFocused) {\r\n Caret.navigateNext();\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Delete at the end of the last Block should do nothing\r\n */\r\n if (nextBlock === null) {\r\n return;\r\n }\r\n\r\n /**\r\n * If next Block is empty, it should be removed just like a character\r\n */\r\n if (nextBlock.isEmpty) {\r\n BlockManager.removeBlock(nextBlock);\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * If current Block is empty, just remove it and set cursor to the next Block (like we're removing line break char)\r\n */\r\n if (currentBlock.isEmpty) {\r\n BlockManager.removeBlock(currentBlock);\r\n\r\n Caret.setToBlock(nextBlock, Caret.positions.START);\r\n\r\n return;\r\n }\r\n\r\n const bothBlocksMergeable = areBlocksMergeable(currentBlock, nextBlock);\r\n\r\n /**\r\n * If Blocks could be merged, do it\r\n * Otherwise, just navigate to the next block\r\n */\r\n if (bothBlocksMergeable) {\r\n this.mergeBlocks(currentBlock, nextBlock);\r\n } else {\r\n Caret.setToBlock(nextBlock, Caret.positions.START);\r\n }\r\n }\r\n\r\n /**\r\n * Merge passed Blocks\r\n *\r\n * @param targetBlock - to which Block we want to merge\r\n * @param blockToMerge - what Block we want to merge\r\n */\r\n private mergeBlocks(targetBlock: Block, blockToMerge: Block): void {\r\n const { BlockManager, Toolbar } = this.Editor;\r\n\r\n if (targetBlock.lastInput === undefined) {\r\n return;\r\n }\r\n\r\n focus(targetBlock.lastInput, false);\r\n\r\n BlockManager\r\n .mergeBlocks(targetBlock, blockToMerge)\r\n .then(() => {\r\n Toolbar.close();\r\n });\r\n }\r\n\r\n /**\r\n * Handle right and down keyboard keys\r\n *\r\n * @param {KeyboardEvent} event - keyboard event\r\n */\r\n private arrowRightAndDown(event: KeyboardEvent): void {\r\n const isFlipperCombination = Flipper.usedKeys.includes(event.keyCode) &&\r\n (!event.shiftKey || event.keyCode === _.keyCodes.TAB);\r\n\r\n /**\r\n * Arrows might be handled on toolbars by flipper\r\n * Check for Flipper.usedKeys to allow navigate by DOWN and disallow by RIGHT\r\n */\r\n if (this.Editor.UI.someToolbarOpened && isFlipperCombination) {\r\n return;\r\n }\r\n\r\n /**\r\n * Close Toolbar when user moves cursor\r\n */\r\n this.Editor.Toolbar.close();\r\n\r\n const { currentBlock } = this.Editor.BlockManager;\r\n const caretAtEnd = currentBlock?.currentInput !== undefined ? caretUtils.isCaretAtEndOfInput(currentBlock.currentInput) : undefined;\r\n const shouldEnableCBS = caretAtEnd || this.Editor.BlockSelection.anyBlockSelected;\r\n\r\n if (event.shiftKey && event.keyCode === _.keyCodes.DOWN && shouldEnableCBS) {\r\n this.Editor.CrossBlockSelection.toggleBlockSelectedState();\r\n\r\n return;\r\n }\r\n\r\n const navigateNext = event.keyCode === _.keyCodes.DOWN || (event.keyCode === _.keyCodes.RIGHT && !this.isRtl);\r\n const isNavigated = navigateNext ? this.Editor.Caret.navigateNext() : this.Editor.Caret.navigatePrevious();\r\n\r\n if (isNavigated) {\r\n /**\r\n * Default behaviour moves cursor by 1 character, we need to prevent it\r\n */\r\n event.preventDefault();\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * After caret is set, update Block input index\r\n */\r\n _.delay(() => {\r\n /** Check currentBlock for case when user moves selection out of Editor */\r\n if (this.Editor.BlockManager.currentBlock) {\r\n this.Editor.BlockManager.currentBlock.updateCurrentInput();\r\n }\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n }, 20)();\r\n\r\n /**\r\n * Clear blocks selection by arrows\r\n */\r\n this.Editor.BlockSelection.clearSelection(event);\r\n }\r\n\r\n /**\r\n * Handle left and up keyboard keys\r\n *\r\n * @param {KeyboardEvent} event - keyboard event\r\n */\r\n private arrowLeftAndUp(event: KeyboardEvent): void {\r\n /**\r\n * Arrows might be handled on toolbars by flipper\r\n * Check for Flipper.usedKeys to allow navigate by UP and disallow by LEFT\r\n */\r\n if (this.Editor.UI.someToolbarOpened) {\r\n if (Flipper.usedKeys.includes(event.keyCode) && (!event.shiftKey || event.keyCode === _.keyCodes.TAB)) {\r\n return;\r\n }\r\n\r\n this.Editor.UI.closeAllToolbars();\r\n }\r\n\r\n /**\r\n * Close Toolbar when user moves cursor\r\n */\r\n this.Editor.Toolbar.close();\r\n\r\n const { currentBlock } = this.Editor.BlockManager;\r\n const caretAtStart = currentBlock?.currentInput !== undefined ? caretUtils.isCaretAtStartOfInput(currentBlock.currentInput) : undefined;\r\n const shouldEnableCBS = caretAtStart || this.Editor.BlockSelection.anyBlockSelected;\r\n\r\n if (event.shiftKey && event.keyCode === _.keyCodes.UP && shouldEnableCBS) {\r\n this.Editor.CrossBlockSelection.toggleBlockSelectedState(false);\r\n\r\n return;\r\n }\r\n\r\n const navigatePrevious = event.keyCode === _.keyCodes.UP || (event.keyCode === _.keyCodes.LEFT && !this.isRtl);\r\n const isNavigated = navigatePrevious ? this.Editor.Caret.navigatePrevious() : this.Editor.Caret.navigateNext();\r\n\r\n if (isNavigated) {\r\n /**\r\n * Default behaviour moves cursor by 1 character, we need to prevent it\r\n */\r\n event.preventDefault();\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * After caret is set, update Block input index\r\n */\r\n _.delay(() => {\r\n /** Check currentBlock for case when user ends selection out of Editor and then press arrow-key */\r\n if (this.Editor.BlockManager.currentBlock) {\r\n this.Editor.BlockManager.currentBlock.updateCurrentInput();\r\n }\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n }, 20)();\r\n\r\n /**\r\n * Clear blocks selection by arrows\r\n */\r\n this.Editor.BlockSelection.clearSelection(event);\r\n }\r\n\r\n /**\r\n * Cases when we need to close Toolbar\r\n *\r\n * @param {KeyboardEvent} event - keyboard event\r\n */\r\n private needToolbarClosing(event: KeyboardEvent): boolean {\r\n const toolboxItemSelected = (event.keyCode === _.keyCodes.ENTER && this.Editor.Toolbar.toolbox.opened),\r\n blockSettingsItemSelected = (event.keyCode === _.keyCodes.ENTER && this.Editor.BlockSettings.opened),\r\n inlineToolbarItemSelected = (event.keyCode === _.keyCodes.ENTER && this.Editor.InlineToolbar.opened),\r\n flippingToolbarItems = event.keyCode === _.keyCodes.TAB;\r\n\r\n /**\r\n * Do not close Toolbar in cases:\r\n * 1. ShiftKey pressed (or combination with shiftKey)\r\n * 2. When Toolbar is opened and Tab leafs its Tools\r\n * 3. When Toolbar's component is opened and some its item selected\r\n */\r\n return !(event.shiftKey ||\r\n flippingToolbarItems ||\r\n toolboxItemSelected ||\r\n blockSettingsItemSelected ||\r\n inlineToolbarItemSelected\r\n );\r\n }\r\n\r\n /**\r\n * If Toolbox is not open, then just open it and show plus button\r\n */\r\n private activateToolbox(): void {\r\n if (!this.Editor.Toolbar.opened) {\r\n this.Editor.Toolbar.moveAndOpen();\r\n } // else Flipper will leaf through it\r\n\r\n this.Editor.Toolbar.toolbox.open();\r\n }\r\n\r\n /**\r\n * Open Toolbar and show BlockSettings before flipping Tools\r\n */\r\n private activateBlockSettings(): void {\r\n if (!this.Editor.Toolbar.opened) {\r\n this.Editor.Toolbar.moveAndOpen();\r\n }\r\n\r\n /**\r\n * If BlockSettings is not open, then open BlockSettings\r\n * Next Tab press will leaf Settings Buttons\r\n */\r\n if (!this.Editor.BlockSettings.opened) {\r\n /**\r\n * @todo Debug the case when we set caret to some block, hovering another block\r\n * — wrong settings will be opened.\r\n * To fix it, we should refactor the Block Settings module — make it a standalone class, like the Toolbox\r\n */\r\n this.Editor.BlockSettings.open();\r\n }\r\n }\r\n}\r\n","import * as _ from './utils';\r\nimport $ from './dom';\r\nimport type Block from './block';\r\nimport { BlockToolAPI } from './block';\r\nimport type { MoveEvent } from '../../types/tools';\r\n\r\n/**\r\n * @class Blocks\r\n * @classdesc Class to work with Block instances array\r\n * @private\r\n * @property {HTMLElement} workingArea — editor`s working node\r\n */\r\nexport default class Blocks {\r\n /**\r\n * Array of Block instances in order of addition\r\n */\r\n public blocks: Block[];\r\n\r\n /**\r\n * Editor`s area where to add Block`s HTML\r\n */\r\n public workingArea: HTMLElement;\r\n\r\n /**\r\n * @class\r\n * @param {HTMLElement} workingArea — editor`s working node\r\n */\r\n constructor(workingArea: HTMLElement) {\r\n this.blocks = [];\r\n this.workingArea = workingArea;\r\n }\r\n\r\n /**\r\n * Get length of Block instances array\r\n *\r\n * @returns {number}\r\n */\r\n public get length(): number {\r\n return this.blocks.length;\r\n }\r\n\r\n /**\r\n * Get Block instances array\r\n *\r\n * @returns {Block[]}\r\n */\r\n public get array(): Block[] {\r\n return this.blocks;\r\n }\r\n\r\n /**\r\n * Get blocks html elements array\r\n *\r\n * @returns {HTMLElement[]}\r\n */\r\n public get nodes(): HTMLElement[] {\r\n return _.array(this.workingArea.children);\r\n }\r\n\r\n /**\r\n * Proxy trap to implement array-like setter\r\n *\r\n * @example\r\n * blocks[0] = new Block(...)\r\n * @param {Blocks} instance — Blocks instance\r\n * @param {PropertyKey} property — block index or any Blocks class property key to set\r\n * @param {Block} value — value to set\r\n * @returns {boolean}\r\n */\r\n public static set(instance: Blocks, property: PropertyKey, value: Block | unknown): boolean {\r\n /**\r\n * If property name is not a number (method or other property, access it via reflect\r\n */\r\n if (isNaN(Number(property))) {\r\n Reflect.set(instance, property, value);\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * If property is number, call insert method to emulate array behaviour\r\n *\r\n * @example\r\n * blocks[0] = new Block();\r\n */\r\n instance.insert(+(property as number), value as Block);\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Proxy trap to implement array-like getter\r\n *\r\n * @param {Blocks} instance — Blocks instance\r\n * @param {PropertyKey} property — Blocks class property key\r\n * @returns {Block|*}\r\n */\r\n public static get(instance: Blocks, property: PropertyKey): Block | unknown {\r\n /**\r\n * If property is not a number, get it via Reflect object\r\n */\r\n if (isNaN(Number(property))) {\r\n return Reflect.get(instance, property);\r\n }\r\n\r\n /**\r\n * If property is a number (Block index) return Block by passed index\r\n */\r\n return instance.get(+(property as number));\r\n }\r\n\r\n /**\r\n * Push new Block to the blocks array and append it to working area\r\n *\r\n * @param {Block} block - Block to add\r\n */\r\n public push(block: Block): void {\r\n this.blocks.push(block);\r\n this.insertToDOM(block);\r\n }\r\n\r\n /**\r\n * Swaps blocks with indexes first and second\r\n *\r\n * @param {number} first - first block index\r\n * @param {number} second - second block index\r\n * @deprecated — use 'move' instead\r\n */\r\n public swap(first: number, second: number): void {\r\n const secondBlock = this.blocks[second];\r\n\r\n /**\r\n * Change in DOM\r\n */\r\n $.swap(this.blocks[first].holder, secondBlock.holder);\r\n\r\n /**\r\n * Change in array\r\n */\r\n this.blocks[second] = this.blocks[first];\r\n this.blocks[first] = secondBlock;\r\n }\r\n\r\n /**\r\n * Move a block from one to another index\r\n *\r\n * @param {number} toIndex - new index of the block\r\n * @param {number} fromIndex - block to move\r\n */\r\n public move(toIndex: number, fromIndex: number): void {\r\n /**\r\n * cut out the block, move the DOM element and insert at the desired index\r\n * again (the shifting within the blocks array will happen automatically).\r\n *\r\n * @see https://stackoverflow.com/a/44932690/1238150\r\n */\r\n const block = this.blocks.splice(fromIndex, 1)[0];\r\n\r\n // manipulate DOM\r\n const prevIndex = toIndex - 1;\r\n const previousBlockIndex = Math.max(0, prevIndex);\r\n const previousBlock = this.blocks[previousBlockIndex];\r\n\r\n if (toIndex > 0) {\r\n this.insertToDOM(block, 'afterend', previousBlock);\r\n } else {\r\n this.insertToDOM(block, 'beforebegin', previousBlock);\r\n }\r\n\r\n // move in array\r\n this.blocks.splice(toIndex, 0, block);\r\n\r\n // invoke hook\r\n const event: MoveEvent = this.composeBlockEvent('move', {\r\n fromIndex,\r\n toIndex,\r\n });\r\n\r\n block.call(BlockToolAPI.MOVED, event);\r\n }\r\n\r\n /**\r\n * Insert new Block at passed index\r\n *\r\n * @param {number} index — index to insert Block\r\n * @param {Block} block — Block to insert\r\n * @param {boolean} replace — it true, replace block on given index\r\n */\r\n public insert(index: number, block: Block, replace = false): void {\r\n if (!this.length) {\r\n this.push(block);\r\n\r\n return;\r\n }\r\n\r\n if (index > this.length) {\r\n index = this.length;\r\n }\r\n\r\n if (replace) {\r\n this.blocks[index].holder.remove();\r\n this.blocks[index].call(BlockToolAPI.REMOVED);\r\n }\r\n\r\n const deleteCount = replace ? 1 : 0;\r\n\r\n this.blocks.splice(index, deleteCount, block);\r\n\r\n if (index > 0) {\r\n const previousBlock = this.blocks[index - 1];\r\n\r\n this.insertToDOM(block, 'afterend', previousBlock);\r\n } else {\r\n const nextBlock = this.blocks[index + 1];\r\n\r\n if (nextBlock) {\r\n this.insertToDOM(block, 'beforebegin', nextBlock);\r\n } else {\r\n this.insertToDOM(block);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Replaces block under passed index with passed block\r\n *\r\n * @param index - index of existed block\r\n * @param block - new block\r\n */\r\n public replace(index: number, block: Block): void {\r\n if (this.blocks[index] === undefined) {\r\n throw Error('Incorrect index');\r\n }\r\n\r\n const prevBlock = this.blocks[index];\r\n\r\n prevBlock.holder.replaceWith(block.holder);\r\n\r\n this.blocks[index] = block;\r\n }\r\n\r\n /**\r\n * Inserts several blocks at once\r\n *\r\n * @param blocks - blocks to insert\r\n * @param index - index to insert blocks at\r\n */\r\n public insertMany(blocks: Block[], index: number ): void {\r\n const fragment = new DocumentFragment();\r\n\r\n for (const block of blocks) {\r\n fragment.appendChild(block.holder);\r\n }\r\n\r\n if (this.length > 0) {\r\n if (index > 0) {\r\n const previousBlockIndex = Math.min(index - 1, this.length - 1);\r\n const previousBlock = this.blocks[previousBlockIndex];\r\n\r\n previousBlock.holder.after(fragment);\r\n } else if (index === 0) {\r\n this.workingArea.prepend(fragment);\r\n }\r\n\r\n /**\r\n * Insert blocks to the array at the specified index\r\n */\r\n this.blocks.splice(index, 0, ...blocks);\r\n } else {\r\n this.blocks.push(...blocks);\r\n this.workingArea.appendChild(fragment);\r\n }\r\n\r\n /**\r\n * Call Rendered event for each block\r\n */\r\n blocks.forEach((block) => block.call(BlockToolAPI.RENDERED));\r\n }\r\n\r\n /**\r\n * Remove block\r\n *\r\n * @param {number} index - index of Block to remove\r\n */\r\n public remove(index: number): void {\r\n if (isNaN(index)) {\r\n index = this.length - 1;\r\n }\r\n\r\n this.blocks[index].holder.remove();\r\n\r\n this.blocks[index].call(BlockToolAPI.REMOVED);\r\n\r\n this.blocks.splice(index, 1);\r\n }\r\n\r\n /**\r\n * Remove all blocks\r\n */\r\n public removeAll(): void {\r\n this.workingArea.innerHTML = '';\r\n\r\n this.blocks.forEach((block) => block.call(BlockToolAPI.REMOVED));\r\n\r\n this.blocks.length = 0;\r\n }\r\n\r\n /**\r\n * Insert Block after passed target\r\n *\r\n * @todo decide if this method is necessary\r\n * @param {Block} targetBlock — target after which Block should be inserted\r\n * @param {Block} newBlock — Block to insert\r\n */\r\n public insertAfter(targetBlock: Block, newBlock: Block): void {\r\n const index = this.blocks.indexOf(targetBlock);\r\n\r\n this.insert(index + 1, newBlock);\r\n }\r\n\r\n /**\r\n * Get Block by index\r\n *\r\n * @param {number} index — Block index\r\n * @returns {Block}\r\n */\r\n public get(index: number): Block | undefined {\r\n return this.blocks[index];\r\n }\r\n\r\n /**\r\n * Return index of passed Block\r\n *\r\n * @param {Block} block - Block to find\r\n * @returns {number}\r\n */\r\n public indexOf(block: Block): number {\r\n return this.blocks.indexOf(block);\r\n }\r\n\r\n /**\r\n * Insert new Block into DOM\r\n *\r\n * @param {Block} block - Block to insert\r\n * @param {InsertPosition} position — insert position (if set, will use insertAdjacentElement)\r\n * @param {Block} target — Block related to position\r\n */\r\n private insertToDOM(block: Block, position?: InsertPosition, target?: Block): void {\r\n if (position) {\r\n target.holder.insertAdjacentElement(position, block.holder);\r\n } else {\r\n this.workingArea.appendChild(block.holder);\r\n }\r\n\r\n block.call(BlockToolAPI.RENDERED);\r\n }\r\n\r\n /**\r\n * Composes Block event with passed type and details\r\n *\r\n * @param {string} type - event type\r\n * @param {object} detail - event detail\r\n */\r\n private composeBlockEvent(type: string, detail: object): MoveEvent {\r\n return new CustomEvent(type, {\r\n detail,\r\n }) as MoveEvent;\r\n }\r\n}\r\n","import type { BlockMutationEventDetail } from './Base';\r\n\r\n/**\r\n * Type name of CustomEvent related to block removed event\r\n */\r\nexport const BlockRemovedMutationType = 'block-removed';\r\n\r\n/**\r\n * Information about removed block\r\n */\r\ninterface BlockRemovedEventDetail extends BlockMutationEventDetail {\r\n /**\r\n * Index of removed block\r\n */\r\n index: number;\r\n}\r\n\r\n/**\r\n * Event will be fired when some block is removed\r\n */\r\nexport type BlockRemovedEvent = CustomEvent<BlockRemovedEventDetail>;\r\n","import type { BlockMutationEventDetail } from './Base';\r\n\r\n/**\r\n * Type name of CustomEvent related to block added event\r\n */\r\nexport const BlockAddedMutationType = 'block-added';\r\n\r\n/**\r\n * Information about added block\r\n */\r\ninterface BlockAddedEventDetail extends BlockMutationEventDetail {\r\n /**\r\n * Index of added block\r\n */\r\n index: number;\r\n}\r\n\r\n/**\r\n * Event will be fired when the new block is added to the editor\r\n */\r\nexport type BlockAddedEvent = CustomEvent<BlockAddedEventDetail>;\r\n","import type { BlockMutationEventDetail } from './Base';\r\n\r\n/**\r\n * Type name of CustomEvent related to block moved event\r\n */\r\nexport const BlockMovedMutationType = 'block-moved';\r\n\r\n/**\r\n * Information about moved block\r\n */\r\ninterface BlockMovedEventDetail extends BlockMutationEventDetail {\r\n /**\r\n * Previous block position\r\n */\r\n fromIndex: number;\r\n\r\n /**\r\n * New block position\r\n */\r\n toIndex: number;\r\n}\r\n\r\n/**\r\n * Event will be fired when some block is moved to another position\r\n */\r\nexport type BlockMovedEvent = CustomEvent<BlockMovedEventDetail>;\r\n","import type { BlockMutationEventDetail } from './Base';\r\n\r\n/**\r\n * Type name of CustomEvent related to block changed event\r\n */\r\nexport const BlockChangedMutationType = 'block-changed';\r\n\r\n/**\r\n * Information about changed block\r\n */\r\ninterface BlockChangedEventDetail extends BlockMutationEventDetail {\r\n /**\r\n * Index of changed block\r\n */\r\n index: number;\r\n}\r\n\r\n/**\r\n * Event will be fired when some block is changed\r\n */\r\nexport type BlockChangedEvent = CustomEvent<BlockChangedEventDetail>;\r\n","/**\r\n * Class allows to make a queue of async jobs and wait until they all will be finished one by one\r\n *\r\n * @example const queue = new PromiseQueue();\r\n * queue.add(async () => { ... });\r\n * queue.add(async () => { ... });\r\n * await queue.completed;\r\n */\r\nexport default class PromiseQueue {\r\n /**\r\n * Queue of promises to be executed\r\n */\r\n public completed = Promise.resolve();\r\n\r\n /**\r\n * Add new promise to queue\r\n *\r\n * @param operation - promise should be added to queue\r\n */\r\n public add(operation: (value: void) => void | PromiseLike<void>): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n this.completed = this.completed\r\n .then(operation)\r\n .then(resolve)\r\n .catch(reject);\r\n });\r\n }\r\n}\r\n","/**\r\n * @class BlockManager\r\n * @classdesc Manage editor`s blocks storage and appearance\r\n * @module BlockManager\r\n * @version 2.0.0\r\n */\r\nimport Block, { BlockToolAPI } from '../block';\r\nimport Module from '../__module';\r\nimport $ from '../dom';\r\nimport * as _ from '../utils';\r\nimport Blocks from '../blocks';\r\nimport type { BlockToolData, PasteEvent } from '../../../types';\r\nimport type { BlockTuneData } from '../../../types/block-tunes/block-tune-data';\r\nimport BlockAPI from '../block/api';\r\nimport type { BlockMutationEventMap, BlockMutationType } from '../../../types/events/block';\r\nimport { BlockRemovedMutationType } from '../../../types/events/block/BlockRemoved';\r\nimport { BlockAddedMutationType } from '../../../types/events/block/BlockAdded';\r\nimport { BlockMovedMutationType } from '../../../types/events/block/BlockMoved';\r\nimport { BlockChangedMutationType } from '../../../types/events/block/BlockChanged';\r\nimport { BlockChanged } from '../events';\r\nimport { clean, sanitizeBlocks } from '../utils/sanitizer';\r\nimport { convertStringToBlockData, isBlockConvertable } from '../utils/blocks';\r\nimport PromiseQueue from '../utils/promise-queue';\r\n\r\n/**\r\n * @typedef {BlockManager} BlockManager\r\n * @property {number} currentBlockIndex - Index of current working block\r\n * @property {Proxy} _blocks - Proxy for Blocks instance {@link Blocks}\r\n */\r\nexport default class BlockManager extends Module {\r\n /**\r\n * Returns current Block index\r\n *\r\n * @returns {number}\r\n */\r\n public get currentBlockIndex(): number {\r\n return this._currentBlockIndex;\r\n }\r\n\r\n /**\r\n * Set current Block index and fire Block lifecycle callbacks\r\n *\r\n * @param {number} newIndex - index of Block to set as current\r\n */\r\n public set currentBlockIndex(newIndex: number) {\r\n this._currentBlockIndex = newIndex;\r\n }\r\n\r\n /**\r\n * returns first Block\r\n *\r\n * @returns {Block}\r\n */\r\n public get firstBlock(): Block {\r\n return this._blocks[0];\r\n }\r\n\r\n /**\r\n * returns last Block\r\n *\r\n * @returns {Block}\r\n */\r\n public get lastBlock(): Block {\r\n return this._blocks[this._blocks.length - 1];\r\n }\r\n\r\n /**\r\n * Get current Block instance\r\n *\r\n * @returns {Block}\r\n */\r\n public get currentBlock(): Block | undefined {\r\n return this._blocks[this.currentBlockIndex];\r\n }\r\n\r\n /**\r\n * Set passed Block as a current\r\n *\r\n * @param block - block to set as a current\r\n */\r\n public set currentBlock(block: Block) {\r\n this.currentBlockIndex = this.getBlockIndex(block);\r\n }\r\n\r\n /**\r\n * Returns next Block instance\r\n *\r\n * @returns {Block|null}\r\n */\r\n public get nextBlock(): Block | null {\r\n const isLastBlock = this.currentBlockIndex === (this._blocks.length - 1);\r\n\r\n if (isLastBlock) {\r\n return null;\r\n }\r\n\r\n return this._blocks[this.currentBlockIndex + 1];\r\n }\r\n\r\n /**\r\n * Return first Block with inputs after current Block\r\n *\r\n * @returns {Block | undefined}\r\n */\r\n public get nextContentfulBlock(): Block {\r\n const nextBlocks = this.blocks.slice(this.currentBlockIndex + 1);\r\n\r\n return nextBlocks.find((block) => !!block.inputs.length);\r\n }\r\n\r\n /**\r\n * Return first Block with inputs before current Block\r\n *\r\n * @returns {Block | undefined}\r\n */\r\n public get previousContentfulBlock(): Block {\r\n const previousBlocks = this.blocks.slice(0, this.currentBlockIndex).reverse();\r\n\r\n return previousBlocks.find((block) => !!block.inputs.length);\r\n }\r\n\r\n /**\r\n * Returns previous Block instance\r\n *\r\n * @returns {Block|null}\r\n */\r\n public get previousBlock(): Block | null {\r\n const isFirstBlock = this.currentBlockIndex === 0;\r\n\r\n if (isFirstBlock) {\r\n return null;\r\n }\r\n\r\n return this._blocks[this.currentBlockIndex - 1];\r\n }\r\n\r\n /**\r\n * Get array of Block instances\r\n *\r\n * @returns {Block[]} {@link Blocks#array}\r\n */\r\n public get blocks(): Block[] {\r\n return this._blocks.array;\r\n }\r\n\r\n /**\r\n * Check if each Block is empty\r\n *\r\n * @returns {boolean}\r\n */\r\n public get isEditorEmpty(): boolean {\r\n return this.blocks.every((block) => block.isEmpty);\r\n }\r\n\r\n /**\r\n * Index of current working block\r\n *\r\n * @type {number}\r\n */\r\n private _currentBlockIndex = -1;\r\n\r\n /**\r\n * Proxy for Blocks instance {@link Blocks}\r\n *\r\n * @type {Proxy}\r\n * @private\r\n */\r\n private _blocks: Blocks = null;\r\n\r\n /**\r\n * Should be called after Editor.UI preparation\r\n * Define this._blocks property\r\n */\r\n public prepare(): void {\r\n const blocks = new Blocks(this.Editor.UI.nodes.redactor);\r\n\r\n /**\r\n * We need to use Proxy to overload set/get [] operator.\r\n * So we can use array-like syntax to access blocks\r\n *\r\n * @example\r\n * this._blocks[0] = new Block(...);\r\n *\r\n * block = this._blocks[0];\r\n * @todo proxy the enumerate method\r\n * @type {Proxy}\r\n * @private\r\n */\r\n this._blocks = new Proxy(blocks, {\r\n set: Blocks.set,\r\n get: Blocks.get,\r\n });\r\n\r\n /** Copy event */\r\n this.listeners.on(\r\n document,\r\n 'copy',\r\n (e: ClipboardEvent) => this.Editor.BlockEvents.handleCommandC(e)\r\n );\r\n }\r\n\r\n /**\r\n * Toggle read-only state\r\n *\r\n * If readOnly is true:\r\n * - Unbind event handlers from created Blocks\r\n *\r\n * if readOnly is false:\r\n * - Bind event handlers to all existing Blocks\r\n *\r\n * @param {boolean} readOnlyEnabled - \"read only\" state\r\n */\r\n public toggleReadOnly(readOnlyEnabled: boolean): void {\r\n if (!readOnlyEnabled) {\r\n this.enableModuleBindings();\r\n } else {\r\n this.disableModuleBindings();\r\n }\r\n }\r\n\r\n /**\r\n * Creates Block instance by tool name\r\n *\r\n * @param {object} options - block creation options\r\n * @param {string} options.tool - tools passed in editor config {@link EditorConfig#tools}\r\n * @param {string} [options.id] - unique id for this block\r\n * @param {BlockToolData} [options.data] - constructor params\r\n * @returns {Block}\r\n */\r\n public composeBlock({\r\n tool: name,\r\n data = {},\r\n id = undefined,\r\n tunes: tunesData = {},\r\n }: {tool: string; id?: string; data?: BlockToolData; tunes?: {[name: string]: BlockTuneData}}): Block {\r\n const readOnly = this.Editor.ReadOnly.isEnabled;\r\n const tool = this.Editor.Tools.blockTools.get(name);\r\n const block = new Block({\r\n id,\r\n data,\r\n tool,\r\n api: this.Editor.API,\r\n readOnly,\r\n tunesData,\r\n }, this.eventsDispatcher);\r\n\r\n if (!readOnly) {\r\n window.requestIdleCallback(() => {\r\n this.bindBlockEvents(block);\r\n }, { timeout: 2000 });\r\n }\r\n\r\n return block;\r\n }\r\n\r\n /**\r\n * Insert new block into _blocks\r\n *\r\n * @param {object} options - insert options\r\n * @param {string} [options.id] - block's unique id\r\n * @param {string} [options.tool] - plugin name, by default method inserts the default block type\r\n * @param {object} [options.data] - plugin data\r\n * @param {number} [options.index] - index where to insert new Block\r\n * @param {boolean} [options.needToFocus] - flag shows if needed to update current Block index\r\n * @param {boolean} [options.replace] - flag shows if block by passed index should be replaced with inserted one\r\n * @returns {Block}\r\n */\r\n public insert({\r\n id = undefined,\r\n tool = this.config.defaultBlock,\r\n data = {},\r\n index,\r\n needToFocus = true,\r\n replace = false,\r\n tunes = {},\r\n }: {\r\n id?: string;\r\n tool?: string;\r\n data?: BlockToolData;\r\n index?: number;\r\n needToFocus?: boolean;\r\n replace?: boolean;\r\n tunes?: {[name: string]: BlockTuneData};\r\n } = {}): Block {\r\n let newIndex = index;\r\n\r\n if (newIndex === undefined) {\r\n newIndex = this.currentBlockIndex + (replace ? 0 : 1);\r\n }\r\n\r\n const block = this.composeBlock({\r\n id,\r\n tool,\r\n data,\r\n tunes,\r\n });\r\n\r\n /**\r\n * In case of block replacing (Converting OR from Toolbox or Shortcut on empty block OR on-paste to empty block)\r\n * we need to dispatch the 'block-removing' event for the replacing block\r\n */\r\n if (replace) {\r\n this.blockDidMutated(BlockRemovedMutationType, this.getBlockByIndex(newIndex), {\r\n index: newIndex,\r\n });\r\n }\r\n\r\n this._blocks.insert(newIndex, block, replace);\r\n\r\n /**\r\n * Force call of didMutated event on Block insertion\r\n */\r\n this.blockDidMutated(BlockAddedMutationType, block, {\r\n index: newIndex,\r\n });\r\n\r\n if (needToFocus) {\r\n this.currentBlockIndex = newIndex;\r\n } else if (newIndex <= this.currentBlockIndex) {\r\n this.currentBlockIndex++;\r\n }\r\n\r\n return block;\r\n }\r\n\r\n /**\r\n * Inserts several blocks at once\r\n *\r\n * @param blocks - blocks to insert\r\n * @param index - index where to insert\r\n */\r\n public insertMany(blocks: Block[], index = 0): void {\r\n this._blocks.insertMany(blocks, index);\r\n }\r\n\r\n /**\r\n * Update Block data.\r\n *\r\n * Currently we don't have an 'update' method in the Tools API, so we just create a new block with the same id and type\r\n * Should not trigger 'block-removed' or 'block-added' events.\r\n *\r\n * If neither data nor tunes is provided, return the provided block instead.\r\n *\r\n * @param block - block to update\r\n * @param data - (optional) new data\r\n * @param tunes - (optional) tune data\r\n */\r\n public async update(block: Block, data?: Partial<BlockToolData>, tunes?: {[name: string]: BlockTuneData}): Promise<Block> {\r\n if (!data && !tunes) {\r\n return block;\r\n }\r\n\r\n const existingData = await block.data;\r\n\r\n const newBlock = this.composeBlock({\r\n id: block.id,\r\n tool: block.name,\r\n data: Object.assign({}, existingData, data ?? {}),\r\n tunes: tunes ?? block.tunes,\r\n });\r\n\r\n const blockIndex = this.getBlockIndex(block);\r\n\r\n this._blocks.replace(blockIndex, newBlock);\r\n\r\n this.blockDidMutated(BlockChangedMutationType, newBlock, {\r\n index: blockIndex,\r\n });\r\n\r\n return newBlock;\r\n }\r\n\r\n /**\r\n * Replace passed Block with the new one with specified Tool and data\r\n *\r\n * @param block - block to replace\r\n * @param newTool - new Tool name\r\n * @param data - new Tool data\r\n */\r\n public replace(block: Block, newTool: string, data: BlockToolData): Block {\r\n const blockIndex = this.getBlockIndex(block);\r\n\r\n return this.insert({\r\n tool: newTool,\r\n data,\r\n index: blockIndex,\r\n replace: true,\r\n });\r\n }\r\n\r\n /**\r\n * Insert pasted content. Call onPaste callback after insert.\r\n *\r\n * @param {string} toolName - name of Tool to insert\r\n * @param {PasteEvent} pasteEvent - pasted data\r\n * @param {boolean} replace - should replace current block\r\n */\r\n public paste(\r\n toolName: string,\r\n pasteEvent: PasteEvent,\r\n replace = false\r\n ): Block {\r\n const block = this.insert({\r\n tool: toolName,\r\n replace,\r\n });\r\n\r\n try {\r\n /**\r\n * We need to call onPaste after Block will be ready\r\n * because onPaste could change tool's root element, and we need to do that after block.watchBlockMutations() bound\r\n * to detect tool root element change\r\n *\r\n * @todo make this.insert() awaitable and remove requestIdleCallback\r\n */\r\n window.requestIdleCallback(() => {\r\n block.call(BlockToolAPI.ON_PASTE, pasteEvent);\r\n });\r\n } catch (e) {\r\n _.log(`${toolName}: onPaste callback call is failed`, 'error', e);\r\n }\r\n\r\n return block;\r\n }\r\n\r\n /**\r\n * Insert new default block at passed index\r\n *\r\n * @param {number} index - index where Block should be inserted\r\n * @param {boolean} needToFocus - if true, updates current Block index\r\n *\r\n * TODO: Remove method and use insert() with index instead (?)\r\n * @returns {Block} inserted Block\r\n */\r\n public insertDefaultBlockAtIndex(index: number, needToFocus = false): Block {\r\n const block = this.composeBlock({ tool: this.config.defaultBlock });\r\n\r\n this._blocks[index] = block;\r\n\r\n /**\r\n * Force call of didMutated event on Block insertion\r\n */\r\n this.blockDidMutated(BlockAddedMutationType, block, {\r\n index,\r\n });\r\n\r\n if (needToFocus) {\r\n this.currentBlockIndex = index;\r\n } else if (index <= this.currentBlockIndex) {\r\n this.currentBlockIndex++;\r\n }\r\n\r\n return block;\r\n }\r\n\r\n /**\r\n * Always inserts at the end\r\n *\r\n * @returns {Block}\r\n */\r\n public insertAtEnd(): Block {\r\n /**\r\n * Define new value for current block index\r\n */\r\n this.currentBlockIndex = this.blocks.length - 1;\r\n\r\n /**\r\n * Insert the default typed block\r\n */\r\n return this.insert();\r\n }\r\n\r\n /**\r\n * Merge two blocks\r\n *\r\n * @param {Block} targetBlock - previous block will be append to this block\r\n * @param {Block} blockToMerge - block that will be merged with target block\r\n * @returns {Promise} - the sequence that can be continued\r\n */\r\n public async mergeBlocks(targetBlock: Block, blockToMerge: Block): Promise<void> {\r\n let blockToMergeData: BlockToolData | undefined;\r\n\r\n /**\r\n * We can merge:\r\n * 1) Blocks with the same Tool if tool provides merge method\r\n */\r\n if (targetBlock.name === blockToMerge.name && targetBlock.mergeable) {\r\n const blockToMergeDataRaw = await blockToMerge.data;\r\n\r\n if (_.isEmpty(blockToMergeDataRaw)) {\r\n console.error('Could not merge Block. Failed to extract original Block data.');\r\n\r\n return;\r\n }\r\n\r\n const [ cleanData ] = sanitizeBlocks([ blockToMergeDataRaw ], targetBlock.tool.sanitizeConfig);\r\n\r\n blockToMergeData = cleanData;\r\n\r\n /**\r\n * 2) Blocks with different Tools if they provides conversionConfig\r\n */\r\n } else if (targetBlock.mergeable && isBlockConvertable(blockToMerge, 'export') && isBlockConvertable(targetBlock, 'import')) {\r\n const blockToMergeDataStringified = await blockToMerge.exportDataAsString();\r\n const cleanData = clean(blockToMergeDataStringified, targetBlock.tool.sanitizeConfig);\r\n\r\n blockToMergeData = convertStringToBlockData(cleanData, targetBlock.tool.conversionConfig);\r\n }\r\n\r\n if (blockToMergeData === undefined) {\r\n return;\r\n }\r\n\r\n await targetBlock.mergeWith(blockToMergeData);\r\n this.removeBlock(blockToMerge);\r\n this.currentBlockIndex = this._blocks.indexOf(targetBlock);\r\n }\r\n\r\n /**\r\n * Remove passed Block\r\n *\r\n * @param block - Block to remove\r\n * @param addLastBlock - if true, adds new default block at the end. @todo remove this logic and use event-bus instead\r\n */\r\n public removeBlock(block: Block, addLastBlock = true): Promise<void> {\r\n return new Promise((resolve) => {\r\n const index = this._blocks.indexOf(block);\r\n\r\n /**\r\n * If index is not passed and there is no block selected, show a warning\r\n */\r\n if (!this.validateIndex(index)) {\r\n throw new Error('Can\\'t find a Block to remove');\r\n }\r\n\r\n this._blocks.remove(index);\r\n block.destroy();\r\n\r\n /**\r\n * Force call of didMutated event on Block removal\r\n */\r\n this.blockDidMutated(BlockRemovedMutationType, block, {\r\n index,\r\n });\r\n\r\n if (this.currentBlockIndex >= index) {\r\n this.currentBlockIndex--;\r\n }\r\n\r\n /**\r\n * If first Block was removed, insert new Initial Block and set focus on it`s first input\r\n */\r\n if (!this.blocks.length) {\r\n this.unsetCurrentBlock();\r\n\r\n if (addLastBlock) {\r\n this.insert();\r\n }\r\n } else if (index === 0) {\r\n this.currentBlockIndex = 0;\r\n }\r\n\r\n resolve();\r\n });\r\n }\r\n\r\n /**\r\n * Remove only selected Blocks\r\n * and returns first Block index where started removing...\r\n *\r\n * @returns {number|undefined}\r\n */\r\n public removeSelectedBlocks(): number | undefined {\r\n let firstSelectedBlockIndex;\r\n\r\n /**\r\n * Remove selected Blocks from the end\r\n */\r\n for (let index = this.blocks.length - 1; index >= 0; index--) {\r\n if (!this.blocks[index].selected) {\r\n continue;\r\n }\r\n\r\n this.removeBlock(this.blocks[index]);\r\n firstSelectedBlockIndex = index;\r\n }\r\n\r\n return firstSelectedBlockIndex;\r\n }\r\n\r\n /**\r\n * Attention!\r\n * After removing insert the new default typed Block and focus on it\r\n * Removes all blocks\r\n */\r\n public removeAllBlocks(): void {\r\n for (let index = this.blocks.length - 1; index >= 0; index--) {\r\n this._blocks.remove(index);\r\n }\r\n\r\n this.unsetCurrentBlock();\r\n this.insert();\r\n this.currentBlock.firstInput.focus();\r\n }\r\n\r\n /**\r\n * Split current Block\r\n * 1. Extract content from Caret position to the Block`s end\r\n * 2. Insert a new Block below current one with extracted content\r\n *\r\n * @returns {Block}\r\n */\r\n public split(): Block {\r\n const extractedFragment = this.Editor.Caret.extractFragmentFromCaretPosition();\r\n const wrapper = $.make('div');\r\n\r\n wrapper.appendChild(extractedFragment as DocumentFragment);\r\n\r\n /**\r\n * @todo make object in accordance with Tool\r\n */\r\n const data = {\r\n text: $.isEmpty(wrapper) ? '' : wrapper.innerHTML,\r\n };\r\n\r\n /**\r\n * Renew current Block\r\n *\r\n * @type {Block}\r\n */\r\n return this.insert({ data });\r\n }\r\n\r\n /**\r\n * Returns Block by passed index\r\n *\r\n * If we pass -1 as index, the last block will be returned\r\n * There shouldn't be a case when there is no blocks at all — at least one always should exist\r\n */\r\n public getBlockByIndex(index: -1): Block;\r\n\r\n /**\r\n * Returns Block by passed index.\r\n *\r\n * Could return undefined if there is no block with such index\r\n */\r\n public getBlockByIndex(index: number): Block | undefined;\r\n\r\n /**\r\n * Returns Block by passed index\r\n *\r\n * @param {number} index - index to get. -1 to get last\r\n * @returns {Block}\r\n */\r\n public getBlockByIndex(index: number): Block | undefined {\r\n if (index === -1) {\r\n index = this._blocks.length - 1;\r\n }\r\n\r\n return this._blocks[index];\r\n }\r\n\r\n /**\r\n * Returns an index for passed Block\r\n *\r\n * @param block - block to find index\r\n */\r\n public getBlockIndex(block: Block): number {\r\n return this._blocks.indexOf(block);\r\n }\r\n\r\n /**\r\n * Returns the Block by passed id\r\n *\r\n * @param id - id of block to get\r\n * @returns {Block}\r\n */\r\n public getBlockById(id): Block | undefined {\r\n return this._blocks.array.find(block => block.id === id);\r\n }\r\n\r\n /**\r\n * Get Block instance by html element\r\n *\r\n * @param {Node} element - html element to get Block by\r\n */\r\n public getBlock(element: HTMLElement): Block | undefined {\r\n if (!$.isElement(element) as boolean) {\r\n element = element.parentNode as HTMLElement;\r\n }\r\n\r\n const nodes = this._blocks.nodes,\r\n firstLevelBlock = element.closest(`.${Block.CSS.wrapper}`),\r\n index = nodes.indexOf(firstLevelBlock as HTMLElement);\r\n\r\n if (index >= 0) {\r\n return this._blocks[index];\r\n }\r\n }\r\n\r\n /**\r\n * 1) Find first-level Block from passed child Node\r\n * 2) Mark it as current\r\n *\r\n * @param {Node} childNode - look ahead from this node.\r\n * @returns {Block | undefined} can return undefined in case when the passed child note is not a part of the current editor instance\r\n */\r\n public setCurrentBlockByChildNode(childNode: Node): Block | undefined {\r\n /**\r\n * If node is Text TextNode\r\n */\r\n if (!$.isElement(childNode)) {\r\n childNode = childNode.parentNode;\r\n }\r\n\r\n const parentFirstLevelBlock = (childNode as HTMLElement).closest(`.${Block.CSS.wrapper}`);\r\n\r\n if (!parentFirstLevelBlock) {\r\n return;\r\n }\r\n\r\n /**\r\n * Support multiple Editor.js instances,\r\n * by checking whether the found block belongs to the current instance\r\n *\r\n * @see {@link Ui#documentTouched}\r\n */\r\n const editorWrapper = parentFirstLevelBlock.closest(`.${this.Editor.UI.CSS.editorWrapper}`);\r\n const isBlockBelongsToCurrentInstance = editorWrapper?.isEqualNode(this.Editor.UI.nodes.wrapper);\r\n\r\n if (!isBlockBelongsToCurrentInstance) {\r\n return;\r\n }\r\n\r\n /**\r\n * Update current Block's index\r\n *\r\n * @type {number}\r\n */\r\n this.currentBlockIndex = this._blocks.nodes.indexOf(parentFirstLevelBlock as HTMLElement);\r\n\r\n /**\r\n * Update current block active input\r\n */\r\n this.currentBlock.updateCurrentInput();\r\n\r\n return this.currentBlock;\r\n }\r\n\r\n /**\r\n * Return block which contents passed node\r\n *\r\n * @param {Node} childNode - node to get Block by\r\n * @returns {Block}\r\n */\r\n public getBlockByChildNode(childNode: Node): Block | undefined {\r\n if (!childNode || childNode instanceof Node === false) {\r\n return undefined;\r\n }\r\n\r\n /**\r\n * If node is Text TextNode\r\n */\r\n if (!$.isElement(childNode)) {\r\n childNode = childNode.parentNode;\r\n }\r\n\r\n const firstLevelBlock = (childNode as HTMLElement).closest(`.${Block.CSS.wrapper}`);\r\n\r\n return this.blocks.find((block) => block.holder === firstLevelBlock);\r\n }\r\n\r\n /**\r\n * Swap Blocks Position\r\n *\r\n * @param {number} fromIndex - index of first block\r\n * @param {number} toIndex - index of second block\r\n * @deprecated — use 'move' instead\r\n */\r\n public swap(fromIndex, toIndex): void {\r\n /** Move up current Block */\r\n this._blocks.swap(fromIndex, toIndex);\r\n\r\n /** Now actual block moved up so that current block index decreased */\r\n this.currentBlockIndex = toIndex;\r\n }\r\n\r\n /**\r\n * Move a block to a new index\r\n *\r\n * @param {number} toIndex - index where to move Block\r\n * @param {number} fromIndex - index of Block to move\r\n */\r\n public move(toIndex, fromIndex = this.currentBlockIndex): void {\r\n // make sure indexes are valid and within a valid range\r\n if (isNaN(toIndex) || isNaN(fromIndex)) {\r\n _.log(`Warning during 'move' call: incorrect indices provided.`, 'warn');\r\n\r\n return;\r\n }\r\n\r\n if (!this.validateIndex(toIndex) || !this.validateIndex(fromIndex)) {\r\n _.log(`Warning during 'move' call: indices cannot be lower than 0 or greater than the amount of blocks.`, 'warn');\r\n\r\n return;\r\n }\r\n\r\n /** Move up current Block */\r\n this._blocks.move(toIndex, fromIndex);\r\n\r\n /** Now actual block moved so that current block index changed */\r\n this.currentBlockIndex = toIndex;\r\n\r\n /**\r\n * Force call of didMutated event on Block movement\r\n */\r\n this.blockDidMutated(BlockMovedMutationType, this.currentBlock, {\r\n fromIndex,\r\n toIndex,\r\n });\r\n }\r\n\r\n /**\r\n * Converts passed Block to the new Tool\r\n * Uses Conversion Config\r\n *\r\n * @param blockToConvert - Block that should be converted\r\n * @param targetToolName - name of the Tool to convert to\r\n * @param blockDataOverrides - optional new Block data overrides\r\n */\r\n public async convert(blockToConvert: Block, targetToolName: string, blockDataOverrides?: BlockToolData): Promise<Block> {\r\n /**\r\n * At first, we get current Block data\r\n */\r\n const savedBlock = await blockToConvert.save();\r\n\r\n if (!savedBlock) {\r\n throw new Error('Could not convert Block. Failed to extract original Block data.');\r\n }\r\n\r\n /**\r\n * Getting a class of the replacing Tool\r\n */\r\n const replacingTool = this.Editor.Tools.blockTools.get(targetToolName);\r\n\r\n if (!replacingTool) {\r\n throw new Error(`Could not convert Block. Tool «${targetToolName}» not found.`);\r\n }\r\n\r\n /**\r\n * Using Conversion Config \"export\" we get a stringified version of the Block data\r\n */\r\n const exportedData = await blockToConvert.exportDataAsString();\r\n\r\n /**\r\n * Clean exported data with replacing sanitizer config\r\n */\r\n const cleanData: string = clean(\r\n exportedData,\r\n replacingTool.sanitizeConfig\r\n );\r\n\r\n /**\r\n * Now using Conversion Config \"import\" we compose a new Block data\r\n */\r\n let newBlockData = convertStringToBlockData(cleanData, replacingTool.conversionConfig, replacingTool.settings);\r\n\r\n /**\r\n * Optional data overrides.\r\n * Used for example, by the Multiple Toolbox Items feature, where a single Tool provides several Toolbox items with \"data\" overrides\r\n */\r\n if (blockDataOverrides) {\r\n newBlockData = Object.assign(newBlockData, blockDataOverrides);\r\n }\r\n\r\n return this.replace(blockToConvert, replacingTool.name, newBlockData);\r\n }\r\n\r\n /**\r\n * Sets current Block Index -1 which means unknown\r\n * and clear highlights\r\n */\r\n public unsetCurrentBlock(): void {\r\n this.currentBlockIndex = -1;\r\n }\r\n\r\n /**\r\n * Clears Editor\r\n *\r\n * @param {boolean} needToAddDefaultBlock - 1) in internal calls (for example, in api.blocks.render)\r\n * we don't need to add an empty default block\r\n * 2) in api.blocks.clear we should add empty block\r\n */\r\n public async clear(needToAddDefaultBlock = false): Promise<void> {\r\n const queue = new PromiseQueue();\r\n\r\n // Create a copy of the blocks array to avoid issues with array modification during iteration\r\n const blocksToRemove = [...this.blocks];\r\n \r\n blocksToRemove.forEach((block) => {\r\n queue.add(async () => {\r\n await this.removeBlock(block, false);\r\n });\r\n });\r\n\r\n await queue.completed;\r\n\r\n this.unsetCurrentBlock();\r\n\r\n if (needToAddDefaultBlock) {\r\n this.insert();\r\n }\r\n\r\n /**\r\n * Add empty modifier\r\n */\r\n this.Editor.UI.checkEmptiness();\r\n }\r\n\r\n /**\r\n * Cleans up all the block tools' resources\r\n * This is called when editor is destroyed\r\n */\r\n public async destroy(): Promise<void> {\r\n await Promise.all(this.blocks.map((block) => {\r\n return block.destroy();\r\n }));\r\n }\r\n\r\n /**\r\n * Bind Block events\r\n *\r\n * @param {Block} block - Block to which event should be bound\r\n */\r\n private bindBlockEvents(block: Block): void {\r\n const { BlockEvents } = this.Editor;\r\n\r\n this.readOnlyMutableListeners.on(block.holder, 'keydown', (event: KeyboardEvent) => {\r\n BlockEvents.keydown(event);\r\n });\r\n\r\n this.readOnlyMutableListeners.on(block.holder, 'keyup', (event: KeyboardEvent) => {\r\n BlockEvents.keyup(event);\r\n });\r\n\r\n this.readOnlyMutableListeners.on(block.holder, 'dragover', (event: DragEvent) => {\r\n BlockEvents.dragOver(event);\r\n });\r\n\r\n this.readOnlyMutableListeners.on(block.holder, 'dragleave', (event: DragEvent) => {\r\n BlockEvents.dragLeave(event);\r\n });\r\n\r\n block.on('didMutated', (affectedBlock: Block) => {\r\n return this.blockDidMutated(BlockChangedMutationType, affectedBlock, {\r\n index: this.getBlockIndex(affectedBlock),\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Disable mutable handlers and bindings\r\n */\r\n private disableModuleBindings(): void {\r\n this.readOnlyMutableListeners.clearAll();\r\n }\r\n\r\n /**\r\n * Enables all module handlers and bindings for all Blocks\r\n */\r\n private enableModuleBindings(): void {\r\n /** Cut event */\r\n this.readOnlyMutableListeners.on(\r\n document,\r\n 'cut',\r\n (e: ClipboardEvent) => this.Editor.BlockEvents.handleCommandX(e)\r\n );\r\n\r\n this.blocks.forEach((block: Block) => {\r\n this.bindBlockEvents(block);\r\n });\r\n }\r\n\r\n /**\r\n * Validates that the given index is not lower than 0 or higher than the amount of blocks\r\n *\r\n * @param {number} index - index of blocks array to validate\r\n * @returns {boolean}\r\n */\r\n private validateIndex(index: number): boolean {\r\n return !(index < 0 || index >= this._blocks.length);\r\n }\r\n\r\n /**\r\n * Block mutation callback\r\n *\r\n * @param mutationType - what happened with block\r\n * @param block - mutated block\r\n * @param detailData - additional data to pass with change event\r\n */\r\n private blockDidMutated<Type extends BlockMutationType>(mutationType: Type, block: Block, detailData: BlockMutationEventDetailWithoutTarget<Type>): Block {\r\n const event = new CustomEvent(mutationType, {\r\n detail: {\r\n target: new BlockAPI(block),\r\n ...detailData as BlockMutationEventDetailWithoutTarget<Type>,\r\n },\r\n });\r\n\r\n this.eventsDispatcher.emit(BlockChanged, {\r\n event: event as BlockMutationEventMap[Type],\r\n });\r\n\r\n return block;\r\n }\r\n}\r\n\r\n/**\r\n * Type alias for Block Mutation event without 'target' field, used in 'blockDidMutated' method\r\n */\r\ntype BlockMutationEventDetailWithoutTarget<Type extends BlockMutationType> = Omit<BlockMutationEventMap[Type]['detail'], 'target'>;\r\n","/**\r\n * @class BlockSelection\r\n * @classdesc Manages Block selection with shortcut CMD+A\r\n * @module BlockSelection\r\n * @version 1.0.0\r\n */\r\nimport Module from '../__module';\r\nimport type Block from '../block';\r\nimport * as _ from '../utils';\r\nimport $ from '../dom';\r\nimport Shortcuts from '../utils/shortcuts';\r\n\r\nimport SelectionUtils from '../selection';\r\nimport type { SanitizerConfig } from '../../../types/configs';\r\nimport { clean } from '../utils/sanitizer';\r\n\r\n/**\r\n *\r\n */\r\nexport default class BlockSelection extends Module {\r\n /**\r\n * Sometimes .anyBlockSelected can be called frequently,\r\n * for example at ui@selectionChange (to clear native browser selection in CBS)\r\n * We use cache to prevent multiple iterations through all the blocks\r\n *\r\n * @private\r\n */\r\n private anyBlockSelectedCache: boolean | null = null;\r\n\r\n /**\r\n * Sanitizer Config\r\n *\r\n * @returns {SanitizerConfig}\r\n */\r\n private get sanitizerConfig(): SanitizerConfig {\r\n return {\r\n p: {},\r\n h1: {},\r\n h2: {},\r\n h3: {},\r\n h4: {},\r\n h5: {},\r\n h6: {},\r\n ol: {},\r\n ul: {},\r\n li: {},\r\n br: true,\r\n img: {\r\n src: true,\r\n width: true,\r\n height: true,\r\n },\r\n a: {\r\n href: true,\r\n },\r\n b: {},\r\n i: {},\r\n u: {},\r\n };\r\n }\r\n\r\n /**\r\n * Flag that identifies all Blocks selection\r\n *\r\n * @returns {boolean}\r\n */\r\n public get allBlocksSelected(): boolean {\r\n const { BlockManager } = this.Editor;\r\n\r\n return BlockManager.blocks.every((block) => block.selected === true);\r\n }\r\n\r\n /**\r\n * Set selected all blocks\r\n *\r\n * @param {boolean} state - state to set\r\n */\r\n public set allBlocksSelected(state: boolean) {\r\n const { BlockManager } = this.Editor;\r\n\r\n BlockManager.blocks.forEach((block) => {\r\n block.selected = state;\r\n });\r\n\r\n this.clearCache();\r\n }\r\n\r\n /**\r\n * Flag that identifies any Block selection\r\n *\r\n * @returns {boolean}\r\n */\r\n public get anyBlockSelected(): boolean {\r\n const { BlockManager } = this.Editor;\r\n\r\n if (this.anyBlockSelectedCache === null) {\r\n this.anyBlockSelectedCache = BlockManager.blocks.some((block) => block.selected === true);\r\n }\r\n\r\n return this.anyBlockSelectedCache;\r\n }\r\n\r\n /**\r\n * Return selected Blocks array\r\n *\r\n * @returns {Block[]}\r\n */\r\n public get selectedBlocks(): Block[] {\r\n return this.Editor.BlockManager.blocks.filter((block: Block) => block.selected);\r\n }\r\n\r\n /**\r\n * Flag used to define block selection\r\n * First CMD+A defines it as true and then second CMD+A selects all Blocks\r\n *\r\n * @type {boolean}\r\n */\r\n private needToSelectAll = false;\r\n\r\n /**\r\n * Flag used to define native input selection\r\n * In this case we allow double CMD+A to select Block\r\n *\r\n * @type {boolean}\r\n */\r\n private nativeInputSelected = false;\r\n\r\n /**\r\n * Flag identifies any input selection\r\n * That means we can select whole Block\r\n *\r\n * @type {boolean}\r\n */\r\n private readyToBlockSelection = false;\r\n\r\n /**\r\n * SelectionUtils instance\r\n *\r\n * @type {SelectionUtils}\r\n */\r\n private selection: SelectionUtils;\r\n\r\n /**\r\n * Module Preparation\r\n * Registers Shortcuts CMD+A and CMD+C\r\n * to select all and copy them\r\n */\r\n public prepare(): void {\r\n this.selection = new SelectionUtils();\r\n\r\n /**\r\n * CMD/CTRL+A selection shortcut\r\n */\r\n Shortcuts.add({\r\n name: 'CMD+A',\r\n handler: (event) => {\r\n const { BlockManager, ReadOnly } = this.Editor;\r\n\r\n /**\r\n * We use Editor's Block selection on CMD+A ShortCut instead of Browsers\r\n */\r\n if (ReadOnly.isEnabled) {\r\n event.preventDefault();\r\n this.selectAllBlocks();\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * When one page consist of two or more EditorJS instances\r\n * Shortcut module tries to handle all events.\r\n * Thats why Editor's selection works inside the target Editor, but\r\n * for others error occurs because nothing to select.\r\n *\r\n * Prevent such actions if focus is not inside the Editor\r\n */\r\n if (!BlockManager.currentBlock) {\r\n return;\r\n }\r\n\r\n this.handleCommandA(event);\r\n },\r\n on: this.Editor.UI.nodes.redactor,\r\n });\r\n }\r\n\r\n /**\r\n * Toggle read-only state\r\n *\r\n * - Remove all ranges\r\n * - Unselect all Blocks\r\n */\r\n public toggleReadOnly(): void {\r\n SelectionUtils.get()\r\n .removeAllRanges();\r\n\r\n this.allBlocksSelected = false;\r\n }\r\n\r\n /**\r\n * Remove selection of Block\r\n *\r\n * @param {number?} index - Block index according to the BlockManager's indexes\r\n */\r\n public unSelectBlockByIndex(index?): void {\r\n const { BlockManager } = this.Editor;\r\n\r\n let block;\r\n\r\n if (isNaN(index)) {\r\n block = BlockManager.currentBlock;\r\n } else {\r\n block = BlockManager.getBlockByIndex(index);\r\n }\r\n\r\n block.selected = false;\r\n\r\n this.clearCache();\r\n }\r\n\r\n /**\r\n * Clear selection from Blocks\r\n *\r\n * @param {Event} reason - event caused clear of selection\r\n * @param {boolean} restoreSelection - if true, restore saved selection\r\n */\r\n public clearSelection(reason?: Event, restoreSelection = false): void {\r\n const { BlockManager, Caret, RectangleSelection } = this.Editor;\r\n\r\n this.needToSelectAll = false;\r\n this.nativeInputSelected = false;\r\n this.readyToBlockSelection = false;\r\n\r\n const isKeyboard = reason && (reason instanceof KeyboardEvent);\r\n const isPrintableKey = isKeyboard && _.isPrintableKey((reason as KeyboardEvent).keyCode);\r\n\r\n /**\r\n * If reason caused clear of the selection was printable key and any block is selected,\r\n * remove selected blocks and insert pressed key\r\n */\r\n if (this.anyBlockSelected && isKeyboard && isPrintableKey && !SelectionUtils.isSelectionExists) {\r\n const indexToInsert = BlockManager.removeSelectedBlocks();\r\n\r\n BlockManager.insertDefaultBlockAtIndex(indexToInsert, true);\r\n Caret.setToBlock(BlockManager.currentBlock);\r\n _.delay(() => {\r\n const eventKey = (reason as KeyboardEvent).key;\r\n\r\n /**\r\n * If event.key length >1 that means key is special (e.g. Enter or Dead or Unidentified).\r\n * So we use empty string\r\n *\r\n * @see https://developer.mozilla.org/ru/docs/Web/API/KeyboardEvent/key\r\n */\r\n Caret.insertContentAtCaretPosition(eventKey.length > 1 ? '' : eventKey);\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n }, 20)();\r\n }\r\n\r\n this.Editor.CrossBlockSelection.clear(reason);\r\n\r\n if (!this.anyBlockSelected || RectangleSelection.isRectActivated()) {\r\n this.Editor.RectangleSelection.clearSelection();\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Restore selection when Block is already selected\r\n * but someone tries to write something.\r\n */\r\n if (restoreSelection) {\r\n this.selection.restore();\r\n }\r\n\r\n /** Now all blocks cleared */\r\n this.allBlocksSelected = false;\r\n }\r\n\r\n /**\r\n * Reduce each Block and copy its content\r\n *\r\n * @param {ClipboardEvent} e - copy/cut event\r\n * @returns {Promise<void>}\r\n */\r\n public copySelectedBlocks(e: ClipboardEvent): Promise<void> {\r\n /**\r\n * Prevent default copy\r\n */\r\n e.preventDefault();\r\n\r\n const fakeClipboard = $.make('div');\r\n\r\n this.selectedBlocks.forEach((block) => {\r\n /**\r\n * Make <p> tag that holds clean HTML\r\n */\r\n const cleanHTML = clean(block.holder.innerHTML, this.sanitizerConfig);\r\n const fragment = $.make('p');\r\n\r\n fragment.innerHTML = cleanHTML;\r\n fakeClipboard.appendChild(fragment);\r\n });\r\n\r\n const textPlain = Array.from(fakeClipboard.childNodes).map((node) => node.textContent)\r\n .join('\\n\\n');\r\n const textHTML = fakeClipboard.innerHTML;\r\n\r\n e.clipboardData.setData('text/plain', textPlain);\r\n e.clipboardData.setData('text/html', textHTML);\r\n\r\n return Promise\r\n .all(this.selectedBlocks.map((block) => block.save()))\r\n .then(savedData => {\r\n try {\r\n e.clipboardData.setData(this.Editor.Paste.MIME_TYPE, JSON.stringify(savedData));\r\n } catch (err) {\r\n // In Firefox we can't set data in async function\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Select Block by its index\r\n *\r\n * @param {number?} index - Block index according to the BlockManager's indexes\r\n */\r\n public selectBlockByIndex(index: number): void {\r\n const { BlockManager } = this.Editor;\r\n\r\n const block = BlockManager.getBlockByIndex(index);\r\n\r\n if (block === undefined) {\r\n return;\r\n }\r\n\r\n this.selectBlock(block);\r\n }\r\n\r\n /**\r\n * Select passed Block\r\n *\r\n * @param {Block} block - Block to select\r\n */\r\n public selectBlock(block: Block): void {\r\n /** Save selection */\r\n this.selection.save();\r\n SelectionUtils.get()\r\n .removeAllRanges();\r\n\r\n block.selected = true;\r\n\r\n this.clearCache();\r\n\r\n /** close InlineToolbar when we selected any Block */\r\n this.Editor.InlineToolbar.close();\r\n }\r\n\r\n /**\r\n * Remove selection from passed Block\r\n *\r\n * @param {Block} block - Block to unselect\r\n */\r\n public unselectBlock(block: Block): void {\r\n block.selected = false;\r\n\r\n this.clearCache();\r\n }\r\n\r\n /**\r\n * Clear anyBlockSelected cache\r\n */\r\n public clearCache(): void {\r\n this.anyBlockSelectedCache = null;\r\n }\r\n\r\n /**\r\n * Module destruction\r\n * De-registers Shortcut CMD+A\r\n */\r\n public destroy(): void {\r\n /** Selection shortcut */\r\n Shortcuts.remove(this.Editor.UI.nodes.redactor, 'CMD+A');\r\n }\r\n\r\n /**\r\n * First CMD+A selects all input content by native behaviour,\r\n * next CMD+A keypress selects all blocks\r\n *\r\n * @param {KeyboardEvent} event - keyboard event\r\n */\r\n private handleCommandA(event: KeyboardEvent): void {\r\n this.Editor.RectangleSelection.clearSelection();\r\n\r\n /** allow default selection on native inputs */\r\n if ($.isNativeInput(event.target) && !this.readyToBlockSelection) {\r\n this.readyToBlockSelection = true;\r\n\r\n return;\r\n }\r\n\r\n const workingBlock = this.Editor.BlockManager.getBlock(event.target as HTMLElement);\r\n const inputs = workingBlock.inputs;\r\n\r\n /**\r\n * If Block has more than one editable element allow native selection\r\n * Second cmd+a will select whole Block\r\n */\r\n if (inputs.length > 1 && !this.readyToBlockSelection) {\r\n this.readyToBlockSelection = true;\r\n\r\n return;\r\n }\r\n\r\n if (inputs.length === 1 && !this.needToSelectAll) {\r\n this.needToSelectAll = true;\r\n\r\n return;\r\n }\r\n\r\n if (this.needToSelectAll) {\r\n /**\r\n * Prevent default selection\r\n */\r\n event.preventDefault();\r\n\r\n this.selectAllBlocks();\r\n\r\n /**\r\n * Disable any selection after all Blocks selected\r\n */\r\n this.needToSelectAll = false;\r\n this.readyToBlockSelection = false;\r\n } else if (this.readyToBlockSelection) {\r\n /**\r\n * prevent default selection when we use custom selection\r\n */\r\n event.preventDefault();\r\n\r\n /**\r\n * select working Block\r\n */\r\n this.selectBlock(workingBlock);\r\n\r\n /**\r\n * Enable all Blocks selection if current Block is selected\r\n */\r\n this.needToSelectAll = true;\r\n }\r\n }\r\n\r\n /**\r\n * Select All Blocks\r\n * Each Block has selected setter that makes Block copyable\r\n */\r\n private selectAllBlocks(): void {\r\n /**\r\n * Save selection\r\n * Will be restored when closeSelection fired\r\n */\r\n this.selection.save();\r\n\r\n /**\r\n * Remove Ranges from Selection\r\n */\r\n SelectionUtils.get()\r\n .removeAllRanges();\r\n\r\n this.allBlocksSelected = true;\r\n\r\n /** close InlineToolbar if we selected all Blocks */\r\n this.Editor.InlineToolbar.close();\r\n }\r\n}\r\n","import Selection from '../selection';\r\nimport Module from '../__module';\r\nimport type Block from '../block';\r\nimport * as caretUtils from '../utils/caret';\r\nimport $ from '../dom';\r\n\r\n/**\r\n * Caret\r\n * Contains methods for working Caret\r\n *\r\n * @todo get rid of this module and separate it for utility functions\r\n */\r\nexport default class Caret extends Module {\r\n /**\r\n * Allowed caret positions in input\r\n *\r\n * @static\r\n * @returns {{START: string, END: string, DEFAULT: string}}\r\n */\r\n public get positions(): {START: string; END: string; DEFAULT: string} {\r\n return {\r\n START: 'start',\r\n END: 'end',\r\n DEFAULT: 'default',\r\n };\r\n }\r\n\r\n /**\r\n * Elements styles that can be useful for Caret Module\r\n */\r\n private static get CSS(): {shadowCaret: string} {\r\n return {\r\n shadowCaret: 'cdx-shadow-caret',\r\n };\r\n }\r\n\r\n /**\r\n * Method gets Block instance and puts caret to the text node with offset\r\n * There two ways that method applies caret position:\r\n * - first found text node: sets at the beginning, but you can pass an offset\r\n * - last found text node: sets at the end of the node. Also, you can customize the behaviour\r\n *\r\n * @param {Block} block - Block class\r\n * @param {string} position - position where to set caret.\r\n * If default - leave default behaviour and apply offset if it's passed\r\n * @param {number} offset - caret offset regarding to the block content\r\n */\r\n public setToBlock(block: Block, position: string = this.positions.DEFAULT, offset = 0): void {\r\n const { BlockManager, BlockSelection } = this.Editor;\r\n\r\n /**\r\n * Clear previous selection since we possible will select the new Block\r\n */\r\n BlockSelection.clearSelection();\r\n\r\n /**\r\n * If Block is not focusable, just select (highlight) it\r\n */\r\n if (!block.focusable) {\r\n /**\r\n * Hide current cursor\r\n */\r\n window.getSelection()?.removeAllRanges();\r\n\r\n /**\r\n * Highlight Block\r\n */\r\n BlockSelection.selectBlock(block);\r\n BlockManager.currentBlock = block;\r\n\r\n return;\r\n }\r\n\r\n let element;\r\n\r\n switch (position) {\r\n case this.positions.START:\r\n element = block.firstInput;\r\n break;\r\n case this.positions.END:\r\n element = block.lastInput;\r\n break;\r\n default:\r\n element = block.currentInput;\r\n }\r\n\r\n if (!element) {\r\n return;\r\n }\r\n\r\n let nodeToSet: Node;\r\n let offsetToSet = offset;\r\n\r\n if (position === this.positions.START) {\r\n nodeToSet = $.getDeepestNode(element, false) as Node;\r\n offsetToSet = 0;\r\n } else if (position === this.positions.END) {\r\n nodeToSet = $.getDeepestNode(element, true) as Node;\r\n offsetToSet = $.getContentLength(nodeToSet);\r\n } else {\r\n const { node, offset: nodeOffset } = $.getNodeByOffset(element, offset);\r\n\r\n if (node) {\r\n nodeToSet = node;\r\n offsetToSet = nodeOffset;\r\n } else { // case for empty block's input\r\n nodeToSet = $.getDeepestNode(element, false) as Node;\r\n offsetToSet = 0;\r\n }\r\n }\r\n\r\n this.set(nodeToSet as HTMLElement, offsetToSet);\r\n\r\n BlockManager.setCurrentBlockByChildNode(block.holder);\r\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\r\n BlockManager.currentBlock!.currentInput = element;\r\n }\r\n\r\n /**\r\n * Set caret to the current input of current Block.\r\n *\r\n * @param {HTMLElement} input - input where caret should be set\r\n * @param {string} position - position of the caret.\r\n * If default - leave default behaviour and apply offset if it's passed\r\n * @param {number} offset - caret offset regarding to the text node\r\n */\r\n public setToInput(input: HTMLElement, position: string = this.positions.DEFAULT, offset = 0): void {\r\n const { currentBlock } = this.Editor.BlockManager;\r\n const nodeToSet = $.getDeepestNode(input);\r\n\r\n switch (position) {\r\n case this.positions.START:\r\n this.set(nodeToSet as HTMLElement, 0);\r\n break;\r\n\r\n case this.positions.END:\r\n this.set(nodeToSet as HTMLElement, $.getContentLength(nodeToSet));\r\n break;\r\n\r\n default:\r\n if (offset) {\r\n this.set(nodeToSet as HTMLElement, offset);\r\n }\r\n }\r\n\r\n currentBlock.currentInput = input;\r\n }\r\n\r\n /**\r\n * Creates Document Range and sets caret to the element with offset\r\n *\r\n * @param {HTMLElement} element - target node.\r\n * @param {number} offset - offset\r\n */\r\n public set(element: HTMLElement, offset = 0): void {\r\n const scrollOffset = 30;\r\n const { top, bottom } = Selection.setCursor(element, offset);\r\n const { innerHeight } = window;\r\n\r\n /**\r\n * If new cursor position is not visible, scroll to it\r\n */\r\n if (top < 0) {\r\n window.scrollBy(0, top - scrollOffset);\r\n } else if (bottom > innerHeight) {\r\n window.scrollBy(0, bottom - innerHeight + scrollOffset);\r\n }\r\n }\r\n\r\n /**\r\n * Set Caret to the last Block\r\n * If last block is not empty, append another empty block\r\n */\r\n public setToTheLastBlock(): void {\r\n const lastBlock = this.Editor.BlockManager.lastBlock;\r\n\r\n if (!lastBlock) {\r\n return;\r\n }\r\n\r\n /**\r\n * If last block is empty and it is an defaultBlock, set to that.\r\n * Otherwise, append new empty block and set to that\r\n */\r\n if (lastBlock.tool.isDefault && lastBlock.isEmpty) {\r\n this.setToBlock(lastBlock);\r\n } else {\r\n const newBlock = this.Editor.BlockManager.insertAtEnd();\r\n\r\n this.setToBlock(newBlock);\r\n }\r\n }\r\n\r\n /**\r\n * Extract content fragment of current Block from Caret position to the end of the Block\r\n */\r\n public extractFragmentFromCaretPosition(): void|DocumentFragment {\r\n const selection = Selection.get();\r\n\r\n if (selection.rangeCount) {\r\n const selectRange = selection.getRangeAt(0);\r\n const currentBlockInput = this.Editor.BlockManager.currentBlock.currentInput;\r\n\r\n selectRange.deleteContents();\r\n\r\n if (currentBlockInput) {\r\n if ($.isNativeInput(currentBlockInput)) {\r\n /**\r\n * If input is native text input we need to use it's value\r\n * Text before the caret stays in the input,\r\n * while text after the caret is returned as a fragment to be inserted after the block.\r\n */\r\n const input = currentBlockInput as HTMLInputElement | HTMLTextAreaElement;\r\n const newFragment = document.createDocumentFragment();\r\n\r\n const inputRemainingText = input.value.substring(0, input.selectionStart);\r\n const fragmentText = input.value.substring(input.selectionStart);\r\n\r\n newFragment.textContent = fragmentText;\r\n input.value = inputRemainingText;\r\n\r\n return newFragment;\r\n } else {\r\n const range = selectRange.cloneRange();\r\n\r\n range.selectNodeContents(currentBlockInput);\r\n range.setStart(selectRange.endContainer, selectRange.endOffset);\r\n\r\n return range.extractContents();\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Set's caret to the next Block or Tool`s input\r\n * Before moving caret, we should check if caret position is at the end of Plugins node\r\n * Using {@link Dom#getDeepestNode} to get a last node and match with current selection\r\n *\r\n * @param {boolean} force - pass true to skip check for caret position\r\n */\r\n public navigateNext(force = false): boolean {\r\n const { BlockManager } = this.Editor;\r\n const { currentBlock, nextBlock } = BlockManager;\r\n\r\n if (currentBlock === undefined) {\r\n return false;\r\n }\r\n\r\n const { nextInput, currentInput } = currentBlock;\r\n const isAtEnd = currentInput !== undefined ? caretUtils.isCaretAtEndOfInput(currentInput) : undefined;\r\n\r\n let blockToNavigate = nextBlock;\r\n\r\n /**\r\n * We should jump to the next block if:\r\n * - 'force' is true (Tab-navigation)\r\n * - caret is at the end of the current block\r\n * - block does not contain any inputs (e.g. to allow go next when Delimiter is focused)\r\n */\r\n const navigationAllowed = force || isAtEnd || !currentBlock.focusable;\r\n\r\n /** If next Tool`s input exists, focus on it. Otherwise set caret to the next Block */\r\n if (nextInput && navigationAllowed) {\r\n this.setToInput(nextInput, this.positions.START);\r\n\r\n return true;\r\n }\r\n\r\n if (blockToNavigate === null) {\r\n /**\r\n * This code allows to exit from the last non-initial tool:\r\n * https://github.com/codex-team/editor.js/issues/1103\r\n */\r\n\r\n /**\r\n * 1. If there is a last block and it is default, do nothing\r\n * 2. If there is a last block and it is non-default --> and caret not at the end <--, do nothing\r\n * (https://github.com/codex-team/editor.js/issues/1414)\r\n */\r\n if (currentBlock.tool.isDefault || !navigationAllowed) {\r\n return false;\r\n }\r\n\r\n /**\r\n * If there is no nextBlock, but currentBlock is not default,\r\n * insert new default block at the end and navigate to it\r\n */\r\n blockToNavigate = BlockManager.insertAtEnd() as Block;\r\n }\r\n\r\n if (navigationAllowed) {\r\n this.setToBlock(blockToNavigate, this.positions.START);\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Set's caret to the previous Tool`s input or Block\r\n * Before moving caret, we should check if caret position is start of the Plugins node\r\n * Using {@link Dom#getDeepestNode} to get a last node and match with current selection\r\n *\r\n * @param {boolean} force - pass true to skip check for caret position\r\n */\r\n public navigatePrevious(force = false): boolean {\r\n const { currentBlock, previousBlock } = this.Editor.BlockManager;\r\n\r\n if (!currentBlock) {\r\n return false;\r\n }\r\n\r\n const { previousInput, currentInput } = currentBlock;\r\n\r\n /**\r\n * We should jump to the previous block if:\r\n * - 'force' is true (Tab-navigation)\r\n * - caret is at the start of the current block\r\n * - block does not contain any inputs (e.g. to allow go back when Delimiter is focused)\r\n */\r\n const caretAtStart = currentInput !== undefined ? caretUtils.isCaretAtStartOfInput(currentInput) : undefined;\r\n const navigationAllowed = force || caretAtStart || !currentBlock.focusable;\r\n\r\n /** If previous Tool`s input exists, focus on it. Otherwise set caret to the previous Block */\r\n if (previousInput && navigationAllowed) {\r\n this.setToInput(previousInput, this.positions.END);\r\n\r\n return true;\r\n }\r\n\r\n if (previousBlock !== null && navigationAllowed) {\r\n this.setToBlock(previousBlock as Block, this.positions.END);\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Inserts shadow element after passed element where caret can be placed\r\n *\r\n * @param {Element} element - element after which shadow caret should be inserted\r\n */\r\n public createShadow(element: Element): void {\r\n const shadowCaret = document.createElement('span');\r\n\r\n shadowCaret.classList.add(Caret.CSS.shadowCaret);\r\n element.insertAdjacentElement('beforeend', shadowCaret);\r\n }\r\n\r\n /**\r\n * Restores caret position\r\n *\r\n * @param {HTMLElement} element - element where caret should be restored\r\n */\r\n public restoreCaret(element: HTMLElement): void {\r\n const shadowCaret = element.querySelector(`.${Caret.CSS.shadowCaret}`);\r\n\r\n if (!shadowCaret) {\r\n return;\r\n }\r\n\r\n /**\r\n * After we set the caret to the required place\r\n * we need to clear shadow caret\r\n *\r\n * - make new range\r\n * - select shadowed span\r\n * - use extractContent to remove it from DOM\r\n */\r\n const sel = new Selection();\r\n\r\n sel.expandToTag(shadowCaret as HTMLElement);\r\n\r\n const newRange = document.createRange();\r\n\r\n newRange.selectNode(shadowCaret);\r\n newRange.extractContents();\r\n }\r\n\r\n /**\r\n * Inserts passed content at caret position\r\n *\r\n * @param {string} content - content to insert\r\n */\r\n public insertContentAtCaretPosition(content: string): void {\r\n const fragment = document.createDocumentFragment();\r\n const wrapper = document.createElement('div');\r\n const selection = Selection.get();\r\n const range = Selection.range;\r\n\r\n wrapper.innerHTML = content;\r\n\r\n Array.from(wrapper.childNodes).forEach((child: Node) => fragment.appendChild(child));\r\n\r\n /**\r\n * If there is no child node, append empty one\r\n */\r\n if (fragment.childNodes.length === 0) {\r\n fragment.appendChild(new Text());\r\n }\r\n\r\n const lastChild = fragment.lastChild as ChildNode;\r\n\r\n range.deleteContents();\r\n range.insertNode(fragment);\r\n\r\n /** Cross-browser caret insertion */\r\n const newRange = document.createRange();\r\n\r\n const nodeToSetCaret = lastChild.nodeType === Node.TEXT_NODE ? lastChild : lastChild.firstChild;\r\n\r\n if (nodeToSetCaret !== null && nodeToSetCaret.textContent !== null) {\r\n newRange.setStart(nodeToSetCaret, nodeToSetCaret.textContent.length);\r\n }\r\n\r\n selection.removeAllRanges();\r\n selection.addRange(newRange);\r\n }\r\n}\r\n","import Module from '../__module';\r\nimport type Block from '../block';\r\nimport SelectionUtils from '../selection';\r\nimport * as _ from '../utils';\r\n\r\n/**\r\n *\r\n */\r\nexport default class CrossBlockSelection extends Module {\r\n /**\r\n * Block where selection is started\r\n */\r\n private firstSelectedBlock: Block;\r\n\r\n /**\r\n * Last selected Block\r\n */\r\n private lastSelectedBlock: Block;\r\n\r\n /**\r\n * Module preparation\r\n *\r\n * @returns {Promise}\r\n */\r\n public async prepare(): Promise<void> {\r\n this.listeners.on(document, 'mousedown', (event: MouseEvent) => {\r\n this.enableCrossBlockSelection(event);\r\n });\r\n }\r\n\r\n /**\r\n * Sets up listeners\r\n *\r\n * @param {MouseEvent} event - mouse down event\r\n */\r\n public watchSelection(event: MouseEvent): void {\r\n if (event.button !== _.mouseButtons.LEFT) {\r\n return;\r\n }\r\n\r\n const { BlockManager } = this.Editor;\r\n\r\n this.firstSelectedBlock = BlockManager.getBlock(event.target as HTMLElement);\r\n this.lastSelectedBlock = this.firstSelectedBlock;\r\n\r\n this.listeners.on(document, 'mouseover', this.onMouseOver);\r\n this.listeners.on(document, 'mouseup', this.onMouseUp);\r\n }\r\n\r\n /**\r\n * Return boolean is cross block selection started:\r\n * there should be at least 2 selected blocks\r\n */\r\n public get isCrossBlockSelectionStarted(): boolean {\r\n return !!this.firstSelectedBlock && !!this.lastSelectedBlock && this.firstSelectedBlock !== this.lastSelectedBlock;\r\n }\r\n\r\n /**\r\n * Change selection state of the next Block\r\n * Used for CBS via Shift + arrow keys\r\n *\r\n * @param {boolean} next - if true, toggle next block. Previous otherwise\r\n */\r\n public toggleBlockSelectedState(next = true): void {\r\n const { BlockManager, BlockSelection } = this.Editor;\r\n\r\n if (!this.lastSelectedBlock) {\r\n this.lastSelectedBlock = this.firstSelectedBlock = BlockManager.currentBlock;\r\n }\r\n\r\n if (this.firstSelectedBlock === this.lastSelectedBlock) {\r\n this.firstSelectedBlock.selected = true;\r\n\r\n BlockSelection.clearCache();\r\n SelectionUtils.get().removeAllRanges();\r\n }\r\n\r\n const nextBlockIndex = BlockManager.blocks.indexOf(this.lastSelectedBlock) + (next ? 1 : -1);\r\n const nextBlock = BlockManager.blocks[nextBlockIndex];\r\n\r\n if (!nextBlock) {\r\n return;\r\n }\r\n\r\n if (this.lastSelectedBlock.selected !== nextBlock.selected) {\r\n nextBlock.selected = true;\r\n\r\n BlockSelection.clearCache();\r\n } else {\r\n this.lastSelectedBlock.selected = false;\r\n\r\n BlockSelection.clearCache();\r\n }\r\n\r\n this.lastSelectedBlock = nextBlock;\r\n\r\n /** close InlineToolbar when Blocks selected */\r\n this.Editor.InlineToolbar.close();\r\n\r\n nextBlock.holder.scrollIntoView({\r\n block: 'nearest',\r\n });\r\n }\r\n\r\n /**\r\n * Clear saved state\r\n *\r\n * @param {Event} reason - event caused clear of selection\r\n */\r\n public clear(reason?: Event): void {\r\n const { BlockManager, BlockSelection, Caret } = this.Editor;\r\n const fIndex = BlockManager.blocks.indexOf(this.firstSelectedBlock);\r\n const lIndex = BlockManager.blocks.indexOf(this.lastSelectedBlock);\r\n\r\n if (BlockSelection.anyBlockSelected && fIndex > -1 && lIndex > -1) {\r\n if (reason && reason instanceof KeyboardEvent) {\r\n /**\r\n * Set caret depending on pressed key if pressed key is an arrow.\r\n */\r\n switch (reason.keyCode) {\r\n case _.keyCodes.DOWN:\r\n case _.keyCodes.RIGHT:\r\n Caret.setToBlock(BlockManager.blocks[Math.max(fIndex, lIndex)], Caret.positions.END);\r\n break;\r\n\r\n case _.keyCodes.UP:\r\n case _.keyCodes.LEFT:\r\n Caret.setToBlock(BlockManager.blocks[Math.min(fIndex, lIndex)], Caret.positions.START);\r\n break;\r\n default:\r\n Caret.setToBlock(BlockManager.blocks[Math.max(fIndex, lIndex)], Caret.positions.END);\r\n }\r\n }\r\n }\r\n\r\n this.firstSelectedBlock = this.lastSelectedBlock = null;\r\n }\r\n\r\n /**\r\n * Enables Cross Block Selection\r\n *\r\n * @param {MouseEvent} event - mouse down event\r\n */\r\n private enableCrossBlockSelection(event: MouseEvent): void {\r\n const { UI } = this.Editor;\r\n\r\n /**\r\n * Each mouse down on must disable selectAll state\r\n */\r\n if (!SelectionUtils.isCollapsed) {\r\n this.Editor.BlockSelection.clearSelection(event);\r\n }\r\n\r\n /**\r\n * If mouse down is performed inside the editor, we should watch CBS\r\n */\r\n if (UI.nodes.redactor.contains(event.target as Node)) {\r\n this.watchSelection(event);\r\n } else {\r\n /**\r\n * Otherwise, clear selection\r\n */\r\n this.Editor.BlockSelection.clearSelection(event);\r\n }\r\n }\r\n\r\n /**\r\n * Mouse up event handler.\r\n * Removes the listeners\r\n */\r\n private onMouseUp = (): void => {\r\n this.listeners.off(document, 'mouseover', this.onMouseOver);\r\n this.listeners.off(document, 'mouseup', this.onMouseUp);\r\n };\r\n\r\n /**\r\n * Mouse over event handler\r\n * Gets target and related blocks and change selected state for blocks in between\r\n *\r\n * @param {MouseEvent} event - mouse over event\r\n */\r\n private onMouseOver = (event: MouseEvent): void => {\r\n const { BlockManager, BlockSelection } = this.Editor;\r\n\r\n /**\r\n * Probably, editor is not initialized yet\r\n */\r\n if (event.relatedTarget === null && event.target === null) {\r\n return;\r\n }\r\n\r\n const relatedBlock = BlockManager.getBlockByChildNode(event.relatedTarget as Node) || this.lastSelectedBlock;\r\n const targetBlock = BlockManager.getBlockByChildNode(event.target as Node);\r\n\r\n if (!relatedBlock || !targetBlock) {\r\n return;\r\n }\r\n\r\n if (targetBlock === relatedBlock) {\r\n return;\r\n }\r\n\r\n if (relatedBlock === this.firstSelectedBlock) {\r\n SelectionUtils.get().removeAllRanges();\r\n\r\n relatedBlock.selected = true;\r\n targetBlock.selected = true;\r\n\r\n BlockSelection.clearCache();\r\n\r\n return;\r\n }\r\n\r\n if (targetBlock === this.firstSelectedBlock) {\r\n relatedBlock.selected = false;\r\n targetBlock.selected = false;\r\n\r\n BlockSelection.clearCache();\r\n\r\n return;\r\n }\r\n\r\n this.Editor.InlineToolbar.close();\r\n\r\n this.toggleBlocksSelectedState(relatedBlock, targetBlock);\r\n this.lastSelectedBlock = targetBlock;\r\n };\r\n\r\n /**\r\n * Change blocks selection state between passed two blocks.\r\n *\r\n * @param {Block} firstBlock - first block in range\r\n * @param {Block} lastBlock - last block in range\r\n */\r\n private toggleBlocksSelectedState(firstBlock: Block, lastBlock: Block): void {\r\n const { BlockManager, BlockSelection } = this.Editor;\r\n const fIndex = BlockManager.blocks.indexOf(firstBlock);\r\n const lIndex = BlockManager.blocks.indexOf(lastBlock);\r\n\r\n /**\r\n * If first and last block have the different selection state\r\n * it means we should't toggle selection of the first selected block.\r\n * In the other case we shouldn't toggle the last selected block.\r\n */\r\n const shouldntSelectFirstBlock = firstBlock.selected !== lastBlock.selected;\r\n\r\n for (let i = Math.min(fIndex, lIndex); i <= Math.max(fIndex, lIndex); i++) {\r\n const block = BlockManager.blocks[i];\r\n\r\n if (\r\n block !== this.firstSelectedBlock &&\r\n block !== (shouldntSelectFirstBlock ? firstBlock : lastBlock)\r\n ) {\r\n BlockManager.blocks[i].selected = !BlockManager.blocks[i].selected;\r\n\r\n BlockSelection.clearCache();\r\n }\r\n }\r\n }\r\n}\r\n","import SelectionUtils from '../selection';\r\n\r\nimport Module from '../__module';\r\n/**\r\n *\r\n */\r\nexport default class DragNDrop extends Module {\r\n /**\r\n * If drag has been started at editor, we save it\r\n *\r\n * @type {boolean}\r\n * @private\r\n */\r\n private isStartedAtEditor = false;\r\n\r\n /**\r\n * Toggle read-only state\r\n *\r\n * if state is true:\r\n * - disable all drag-n-drop event handlers\r\n *\r\n * if state is false:\r\n * - restore drag-n-drop event handlers\r\n *\r\n * @param {boolean} readOnlyEnabled - \"read only\" state\r\n */\r\n public toggleReadOnly(readOnlyEnabled: boolean): void {\r\n if (readOnlyEnabled) {\r\n this.disableModuleBindings();\r\n } else {\r\n this.enableModuleBindings();\r\n }\r\n }\r\n\r\n /**\r\n * Add drag events listeners to editor zone\r\n */\r\n private enableModuleBindings(): void {\r\n const { UI } = this.Editor;\r\n\r\n this.readOnlyMutableListeners.on(UI.nodes.holder, 'drop', async (dropEvent: DragEvent) => {\r\n await this.processDrop(dropEvent);\r\n }, true);\r\n\r\n this.readOnlyMutableListeners.on(UI.nodes.holder, 'dragstart', () => {\r\n this.processDragStart();\r\n });\r\n\r\n /**\r\n * Prevent default browser behavior to allow drop on non-contenteditable elements\r\n */\r\n this.readOnlyMutableListeners.on(UI.nodes.holder, 'dragover', (dragEvent: DragEvent) => {\r\n this.processDragOver(dragEvent);\r\n }, true);\r\n }\r\n\r\n /**\r\n * Unbind drag-n-drop event handlers\r\n */\r\n private disableModuleBindings(): void {\r\n this.readOnlyMutableListeners.clearAll();\r\n }\r\n\r\n /**\r\n * Handle drop event\r\n *\r\n * @param {DragEvent} dropEvent - drop event\r\n */\r\n private async processDrop(dropEvent: DragEvent): Promise<void> {\r\n const {\r\n BlockManager,\r\n Paste,\r\n Caret,\r\n } = this.Editor;\r\n\r\n dropEvent.preventDefault();\r\n\r\n BlockManager.blocks.forEach((block) => {\r\n block.dropTarget = false;\r\n });\r\n\r\n if (SelectionUtils.isAtEditor && !SelectionUtils.isCollapsed && this.isStartedAtEditor) {\r\n document.execCommand('delete');\r\n }\r\n\r\n this.isStartedAtEditor = false;\r\n\r\n /**\r\n * Try to set current block by drop target.\r\n * If drop target is not part of the Block, set last Block as current.\r\n */\r\n const targetBlock = BlockManager.setCurrentBlockByChildNode(dropEvent.target as Node);\r\n\r\n if (targetBlock) {\r\n this.Editor.Caret.setToBlock(targetBlock, Caret.positions.END);\r\n } else {\r\n const lastBlock = BlockManager.setCurrentBlockByChildNode(BlockManager.lastBlock.holder);\r\n\r\n this.Editor.Caret.setToBlock(lastBlock, Caret.positions.END);\r\n }\r\n\r\n await Paste.processDataTransfer(dropEvent.dataTransfer, true);\r\n }\r\n\r\n /**\r\n * Handle drag start event\r\n */\r\n private processDragStart(): void {\r\n if (SelectionUtils.isAtEditor && !SelectionUtils.isCollapsed) {\r\n this.isStartedAtEditor = true;\r\n }\r\n\r\n this.Editor.InlineToolbar.close();\r\n }\r\n\r\n /**\r\n * @param {DragEvent} dragEvent - drag event\r\n */\r\n private processDragOver(dragEvent: DragEvent): void {\r\n dragEvent.preventDefault();\r\n }\r\n}\r\n","/**\r\n * Debounce timeout for selection change event\r\n * {@link modules/ui.ts}\r\n */\r\nexport const selectionChangeDebounceTimeout = 180;\r\n\r\n/**\r\n * Timeout for batching of DOM changes used by the ModificationObserver\r\n * {@link modules/modificationsObserver.ts}\r\n */\r\nexport const modificationsObserverBatchTimeout = 400;\r\n","import type { BlockId } from '../../../types';\r\nimport type { BlockMutationEvent, BlockMutationType } from '../../../types/events/block';\r\nimport type { ModuleConfig } from '../../types-internal/module-config';\r\nimport Module from '../__module';\r\nimport { modificationsObserverBatchTimeout } from '../constants';\r\nimport { BlockChanged, FakeCursorAboutToBeToggled, FakeCursorHaveBeenSet, RedactorDomChanged } from '../events';\r\nimport * as _ from '../utils';\r\n\r\n/**\r\n * We use map of block mutations to filter only unique events\r\n */\r\ntype UniqueBlockMutationKey = `block:${BlockId}:event:${BlockMutationType}`;\r\n\r\n/**\r\n * Single entry point for Block mutation events\r\n */\r\nexport default class ModificationsObserver extends Module {\r\n /**\r\n * Flag shows onChange event is disabled\r\n */\r\n private disabled = false;\r\n\r\n /**\r\n * Blocks wrapper mutation observer instance\r\n */\r\n private readonly mutationObserver: MutationObserver;\r\n\r\n /**\r\n * Timeout used to batched several events in a single onChange call\r\n */\r\n private batchingTimeout: null | ReturnType<typeof setTimeout> = null;\r\n\r\n /**\r\n * Array of onChange events used to batch them\r\n *\r\n * Map is used to filter duplicated events related to the same block\r\n */\r\n private batchingOnChangeQueue = new Map<UniqueBlockMutationKey, BlockMutationEvent>();\r\n\r\n /**\r\n * Fired onChange events will be batched by this time\r\n */\r\n private readonly batchTime = modificationsObserverBatchTimeout;\r\n\r\n /**\r\n * Prepare the module\r\n *\r\n * @param options - options used by the modification observer module\r\n * @param options.config - Editor configuration object\r\n * @param options.eventsDispatcher - common Editor event bus\r\n */\r\n constructor({ config, eventsDispatcher }: ModuleConfig) {\r\n super({\r\n config,\r\n eventsDispatcher,\r\n });\r\n\r\n this.mutationObserver = new MutationObserver((mutations) => {\r\n this.redactorChanged(mutations);\r\n });\r\n\r\n this.eventsDispatcher.on(BlockChanged, (payload) => {\r\n this.particularBlockChanged(payload.event);\r\n });\r\n\r\n /**\r\n * Mutex for fake cursor setting/removing operation\r\n */\r\n this.eventsDispatcher.on(FakeCursorAboutToBeToggled, () => {\r\n this.disable();\r\n });\r\n\r\n this.eventsDispatcher.on(FakeCursorHaveBeenSet, () => {\r\n this.enable();\r\n });\r\n }\r\n\r\n /**\r\n * Enables onChange event\r\n */\r\n public enable(): void {\r\n this.mutationObserver.observe(\r\n this.Editor.UI.nodes.redactor,\r\n {\r\n childList: true,\r\n subtree: true,\r\n characterData: true,\r\n attributes: true,\r\n }\r\n );\r\n this.disabled = false;\r\n }\r\n\r\n /**\r\n * Disables onChange event\r\n */\r\n public disable(): void {\r\n this.mutationObserver.disconnect();\r\n this.disabled = true;\r\n }\r\n\r\n /**\r\n * Call onChange event passed to Editor.js configuration\r\n *\r\n * @param event - some of our custom change events\r\n */\r\n private particularBlockChanged(event: BlockMutationEvent): void {\r\n if (this.disabled || !_.isFunction(this.config.onChange)) {\r\n return;\r\n }\r\n\r\n this.batchingOnChangeQueue.set(`block:${event.detail.target.id}:event:${event.type as BlockMutationType}`, event);\r\n\r\n if (this.batchingTimeout) {\r\n clearTimeout(this.batchingTimeout);\r\n }\r\n\r\n this.batchingTimeout = setTimeout(() => {\r\n let eventsToEmit;\r\n\r\n /**\r\n * Ih we have only 1 event in a queue, unwrap it\r\n */\r\n if (this.batchingOnChangeQueue.size === 1) {\r\n eventsToEmit = this.batchingOnChangeQueue.values().next().value;\r\n } else {\r\n eventsToEmit = Array.from(this.batchingOnChangeQueue.values());\r\n }\r\n\r\n if (this.config.onChange) {\r\n this.config.onChange(this.Editor.API.methods, eventsToEmit);\r\n }\r\n\r\n this.batchingOnChangeQueue.clear();\r\n }, this.batchTime);\r\n }\r\n\r\n /**\r\n * Fired on every blocks wrapper dom change\r\n *\r\n * @param mutations - mutations happened\r\n */\r\n private redactorChanged(mutations: MutationRecord[]): void {\r\n this.eventsDispatcher.emit(RedactorDomChanged, {\r\n mutations,\r\n });\r\n }\r\n}\r\n","import Module from '../__module';\r\nimport $ from '../dom';\r\nimport * as _ from '../utils';\r\nimport type {\r\n BlockAPI,\r\n PasteEvent,\r\n PasteEventDetail,\r\n SanitizerConfig,\r\n SanitizerRule\r\n} from '../../../types';\r\nimport type Block from '../block';\r\nimport type { SavedData } from '../../../types/data-formats';\r\nimport { clean, sanitizeBlocks } from '../utils/sanitizer';\r\nimport type BlockToolAdapter from '../tools/block';\r\n\r\n/**\r\n * Tag substitute object.\r\n */\r\ninterface TagSubstitute {\r\n /**\r\n * Name of related Tool\r\n *\r\n */\r\n tool: BlockToolAdapter;\r\n\r\n /**\r\n * If a Tool specifies just a tag name, all the attributes will be sanitized.\r\n * But Tool can explicitly specify sanitizer configuration for supported tags\r\n */\r\n sanitizationConfig?: SanitizerRule;\r\n}\r\n\r\n/**\r\n * Pattern substitute object.\r\n */\r\ninterface PatternSubstitute {\r\n /**\r\n * Pattern`s key\r\n */\r\n key: string;\r\n\r\n /**\r\n * Pattern regexp\r\n */\r\n pattern: RegExp;\r\n\r\n /**\r\n * Name of related Tool\r\n */\r\n tool: BlockToolAdapter;\r\n}\r\n\r\n/**\r\n * Files` types substitutions object.\r\n */\r\ninterface FilesSubstitution {\r\n /**\r\n * Array of file extensions Tool can handle\r\n *\r\n * @type {string[]}\r\n */\r\n extensions: string[];\r\n\r\n /**\r\n * Array of MIME types Tool can handle\r\n *\r\n * @type {string[]}\r\n */\r\n mimeTypes: string[];\r\n}\r\n\r\n/**\r\n * Processed paste data object.\r\n *\r\n * @interface PasteData\r\n */\r\ninterface PasteData {\r\n /**\r\n * Name of related Tool\r\n *\r\n * @type {string}\r\n */\r\n tool: string;\r\n\r\n /**\r\n * Pasted data. Processed and wrapped to HTML element\r\n *\r\n * @type {HTMLElement}\r\n */\r\n content: HTMLElement;\r\n\r\n /**\r\n * Pasted data\r\n */\r\n event: PasteEvent;\r\n\r\n /**\r\n * True if content should be inserted as new Block\r\n *\r\n * @type {boolean}\r\n */\r\n isBlock: boolean;\r\n}\r\n\r\n/**\r\n * @class Paste\r\n * @classdesc Contains methods to handle paste on editor\r\n * @module Paste\r\n * @version 2.0.0\r\n */\r\nexport default class Paste extends Module {\r\n /** If string`s length is greater than this number we don't check paste patterns */\r\n public static readonly PATTERN_PROCESSING_MAX_LENGTH = 450;\r\n\r\n /** Custom EditorJS mime-type to handle in-editor copy/paste actions */\r\n public readonly MIME_TYPE = 'application/x-editor-js';\r\n\r\n /**\r\n * Tags` substitutions parameters\r\n */\r\n private toolsTags: { [tag: string]: TagSubstitute } = {};\r\n\r\n /**\r\n * Store tags to substitute by tool name\r\n */\r\n private tagsByTool: { [tools: string]: string[] } = {};\r\n\r\n /** Patterns` substitutions parameters */\r\n private toolsPatterns: PatternSubstitute[] = [];\r\n\r\n /** Files` substitutions parameters */\r\n private toolsFiles: {\r\n [tool: string]: FilesSubstitution;\r\n } = {};\r\n\r\n /**\r\n * List of tools which do not need a paste handling\r\n */\r\n private exceptionList: string[] = [];\r\n\r\n /**\r\n * Set onPaste callback and collect tools` paste configurations\r\n */\r\n public async prepare(): Promise<void> {\r\n this.processTools();\r\n }\r\n\r\n /**\r\n * Set read-only state\r\n *\r\n * @param {boolean} readOnlyEnabled - read only flag value\r\n */\r\n public toggleReadOnly(readOnlyEnabled: boolean): void {\r\n if (!readOnlyEnabled) {\r\n this.setCallback();\r\n } else {\r\n this.unsetCallback();\r\n }\r\n }\r\n\r\n /**\r\n * Handle pasted or dropped data transfer object\r\n *\r\n * @param {DataTransfer} dataTransfer - pasted or dropped data transfer object\r\n * @param {boolean} isDragNDrop - true if data transfer comes from drag'n'drop events\r\n */\r\n public async processDataTransfer(dataTransfer: DataTransfer, isDragNDrop = false): Promise<void> {\r\n const { Tools } = this.Editor;\r\n const types = dataTransfer.types;\r\n\r\n /**\r\n * In Microsoft Edge types is DOMStringList. So 'contains' is used to check if 'Files' type included\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const includesFiles = types.includes ? types.includes('Files') : (types as any).contains('Files');\r\n\r\n if (includesFiles && !_.isEmpty(this.toolsFiles)) {\r\n await this.processFiles(dataTransfer.files);\r\n\r\n return;\r\n }\r\n\r\n const editorJSData = dataTransfer.getData(this.MIME_TYPE);\r\n const plainData = dataTransfer.getData('text/plain');\r\n let htmlData = dataTransfer.getData('text/html');\r\n\r\n /**\r\n * If EditorJS json is passed, insert it\r\n */\r\n if (editorJSData) {\r\n try {\r\n this.insertEditorJSData(JSON.parse(editorJSData));\r\n\r\n return;\r\n } catch (e) { } // Do nothing and continue execution as usual if error appears\r\n }\r\n\r\n /**\r\n * If text was drag'n'dropped, wrap content with P tag to insert it as the new Block\r\n */\r\n if (isDragNDrop && plainData.trim() && htmlData.trim()) {\r\n htmlData = '<p>' + (htmlData.trim() ? htmlData : plainData) + '</p>';\r\n }\r\n\r\n /** Add all tags that can be substituted to sanitizer configuration */\r\n const toolsTags = Object.keys(this.toolsTags).reduce((result, tag) => {\r\n /**\r\n * If Tool explicitly specifies sanitizer configuration for the tag, use it.\r\n * Otherwise, remove all attributes\r\n */\r\n result[tag.toLowerCase()] = this.toolsTags[tag].sanitizationConfig ?? {};\r\n\r\n return result;\r\n }, {});\r\n\r\n const customConfig = Object.assign({}, toolsTags, Tools.getAllInlineToolsSanitizeConfig(), { br: {} });\r\n const cleanData = clean(htmlData, customConfig);\r\n\r\n /** If there is no HTML or HTML string is equal to plain one, process it as plain text */\r\n if (!cleanData.trim() || cleanData.trim() === plainData || !$.isHTMLString(cleanData)) {\r\n await this.processText(plainData);\r\n } else {\r\n await this.processText(cleanData, true);\r\n }\r\n }\r\n\r\n /**\r\n * Process pasted text and divide them into Blocks\r\n *\r\n * @param {string} data - text to process. Can be HTML or plain.\r\n * @param {boolean} isHTML - if passed string is HTML, this parameter should be true\r\n */\r\n public async processText(data: string, isHTML = false): Promise<void> {\r\n const { Caret, BlockManager } = this.Editor;\r\n const dataToInsert = isHTML ? this.processHTML(data) : this.processPlain(data);\r\n\r\n if (!dataToInsert.length) {\r\n return;\r\n }\r\n\r\n if (dataToInsert.length === 1) {\r\n if (!dataToInsert[0].isBlock) {\r\n this.processInlinePaste(dataToInsert.pop());\r\n } else {\r\n this.processSingleBlock(dataToInsert.pop());\r\n }\r\n\r\n return;\r\n }\r\n\r\n const isCurrentBlockDefault = BlockManager.currentBlock && BlockManager.currentBlock.tool.isDefault;\r\n const needToReplaceCurrentBlock = isCurrentBlockDefault && BlockManager.currentBlock.isEmpty;\r\n\r\n dataToInsert.map(\r\n async (content, i) => this.insertBlock(content, i === 0 && needToReplaceCurrentBlock)\r\n );\r\n\r\n if (BlockManager.currentBlock) {\r\n Caret.setToBlock(BlockManager.currentBlock, Caret.positions.END);\r\n }\r\n }\r\n\r\n /**\r\n * Set onPaste callback handler\r\n */\r\n private setCallback(): void {\r\n this.listeners.on(this.Editor.UI.nodes.holder, 'paste', this.handlePasteEvent);\r\n }\r\n\r\n /**\r\n * Unset onPaste callback handler\r\n */\r\n private unsetCallback(): void {\r\n this.listeners.off(this.Editor.UI.nodes.holder, 'paste', this.handlePasteEvent);\r\n }\r\n\r\n /**\r\n * Get and process tool`s paste configs\r\n */\r\n private processTools(): void {\r\n const tools = this.Editor.Tools.blockTools;\r\n\r\n Array\r\n .from(tools.values())\r\n .forEach(this.processTool);\r\n }\r\n\r\n /**\r\n * Process paste config for each tool\r\n *\r\n * @param tool - BlockTool object\r\n */\r\n private processTool = (tool: BlockToolAdapter): void => {\r\n try {\r\n const toolInstance = tool.create({}, {} as BlockAPI, false);\r\n\r\n if (tool.pasteConfig === false) {\r\n this.exceptionList.push(tool.name);\r\n\r\n return;\r\n }\r\n\r\n if (!_.isFunction(toolInstance.onPaste)) {\r\n return;\r\n }\r\n\r\n this.getTagsConfig(tool);\r\n this.getFilesConfig(tool);\r\n this.getPatternsConfig(tool);\r\n } catch (e) {\r\n _.log(\r\n `Paste handling for «${tool.name}» Tool hasn't been set up because of the error`,\r\n 'warn',\r\n e\r\n );\r\n }\r\n };\r\n\r\n /**\r\n * Get tags name list from either tag name or sanitization config.\r\n *\r\n * @param {string | object} tagOrSanitizeConfig - tag name or sanitize config object.\r\n * @returns {string[]} array of tags.\r\n */\r\n private collectTagNames(tagOrSanitizeConfig: string | SanitizerConfig): string[] {\r\n /**\r\n * If string, then it is a tag name.\r\n */\r\n if (_.isString(tagOrSanitizeConfig)) {\r\n return [ tagOrSanitizeConfig ];\r\n }\r\n /**\r\n * If object, then its keys are tags.\r\n */\r\n if (_.isObject(tagOrSanitizeConfig)) {\r\n return Object.keys(tagOrSanitizeConfig);\r\n }\r\n\r\n /** Return empty tag list */\r\n return [];\r\n }\r\n\r\n /**\r\n * Get tags to substitute by Tool\r\n *\r\n * @param tool - BlockTool object\r\n */\r\n private getTagsConfig(tool: BlockToolAdapter): void {\r\n if (tool.pasteConfig === false) {\r\n return;\r\n }\r\n\r\n const tagsOrSanitizeConfigs = tool.pasteConfig.tags || [];\r\n const toolTags = [];\r\n\r\n tagsOrSanitizeConfigs.forEach((tagOrSanitizeConfig) => {\r\n const tags = this.collectTagNames(tagOrSanitizeConfig);\r\n\r\n /**\r\n * Add tags to toolTags array\r\n */\r\n toolTags.push(...tags);\r\n tags.forEach((tag) => {\r\n if (Object.prototype.hasOwnProperty.call(this.toolsTags, tag)) {\r\n _.log(\r\n `Paste handler for «${tool.name}» Tool on «${tag}» tag is skipped ` +\r\n `because it is already used by «${this.toolsTags[tag].tool.name}» Tool.`,\r\n 'warn'\r\n );\r\n\r\n return;\r\n }\r\n /**\r\n * Get sanitize config for tag.\r\n */\r\n const sanitizationConfig = _.isObject(tagOrSanitizeConfig) ? tagOrSanitizeConfig[tag] : null;\r\n\r\n this.toolsTags[tag.toUpperCase()] = {\r\n tool,\r\n sanitizationConfig,\r\n };\r\n });\r\n });\r\n\r\n this.tagsByTool[tool.name] = toolTags.map((t) => t.toUpperCase());\r\n }\r\n\r\n /**\r\n * Get files` types and extensions to substitute by Tool\r\n *\r\n * @param tool - BlockTool object\r\n */\r\n private getFilesConfig(tool: BlockToolAdapter): void {\r\n if (tool.pasteConfig === false) {\r\n return;\r\n }\r\n\r\n const { files = {} } = tool.pasteConfig;\r\n let { extensions, mimeTypes } = files;\r\n\r\n if (!extensions && !mimeTypes) {\r\n return;\r\n }\r\n\r\n if (extensions && !Array.isArray(extensions)) {\r\n _.log(`«extensions» property of the onDrop config for «${tool.name}» Tool should be an array`);\r\n extensions = [];\r\n }\r\n\r\n if (mimeTypes && !Array.isArray(mimeTypes)) {\r\n _.log(`«mimeTypes» property of the onDrop config for «${tool.name}» Tool should be an array`);\r\n mimeTypes = [];\r\n }\r\n\r\n if (mimeTypes) {\r\n mimeTypes = mimeTypes.filter((type) => {\r\n if (!_.isValidMimeType(type)) {\r\n _.log(`MIME type value «${type}» for the «${tool.name}» Tool is not a valid MIME type`, 'warn');\r\n\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n }\r\n\r\n this.toolsFiles[tool.name] = {\r\n extensions: extensions || [],\r\n mimeTypes: mimeTypes || [],\r\n };\r\n }\r\n\r\n /**\r\n * Get RegExp patterns to substitute by Tool\r\n *\r\n * @param tool - BlockTool object\r\n */\r\n private getPatternsConfig(tool: BlockToolAdapter): void {\r\n if (\r\n tool.pasteConfig === false ||\r\n !tool.pasteConfig.patterns ||\r\n _.isEmpty(tool.pasteConfig.patterns)\r\n ) {\r\n return;\r\n }\r\n\r\n Object.entries(tool.pasteConfig.patterns).forEach(([key, pattern]: [string, RegExp]) => {\r\n /** Still need to validate pattern as it provided by user */\r\n if (!(pattern instanceof RegExp)) {\r\n _.log(\r\n `Pattern ${pattern} for «${tool.name}» Tool is skipped because it should be a Regexp instance.`,\r\n 'warn'\r\n );\r\n }\r\n\r\n this.toolsPatterns.push({\r\n key,\r\n pattern,\r\n tool,\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Check if browser behavior suits better\r\n *\r\n * @param {EventTarget} element - element where content has been pasted\r\n * @returns {boolean}\r\n */\r\n private isNativeBehaviour(element: EventTarget): boolean {\r\n return $.isNativeInput(element);\r\n }\r\n\r\n /**\r\n * Check if Editor should process pasted data and pass data transfer object to handler\r\n *\r\n * @param {ClipboardEvent} event - clipboard event\r\n */\r\n private handlePasteEvent = async (event: ClipboardEvent): Promise<void> => {\r\n const { BlockManager, Toolbar } = this.Editor;\r\n\r\n /**\r\n * When someone pasting into a block, its more stable to set current block by event target, instead of relying on current block set before\r\n */\r\n const currentBlock = BlockManager.setCurrentBlockByChildNode(event.target as HTMLElement);\r\n\r\n /** If target is native input or is not Block, use browser behaviour */\r\n if (\r\n !currentBlock || (this.isNativeBehaviour(event.target) && !event.clipboardData.types.includes('Files'))\r\n ) {\r\n return;\r\n }\r\n\r\n /**\r\n * If Tools is in list of errors, skip processing of paste event\r\n */\r\n if (currentBlock && this.exceptionList.includes(currentBlock.name)) {\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n this.processDataTransfer(event.clipboardData);\r\n\r\n Toolbar.close();\r\n };\r\n\r\n /**\r\n * Get files from data transfer object and insert related Tools\r\n *\r\n * @param {FileList} items - pasted or dropped items\r\n */\r\n private async processFiles(items: FileList): Promise<void> {\r\n const { BlockManager } = this.Editor;\r\n\r\n let dataToInsert: { type: string; event: PasteEvent }[];\r\n\r\n dataToInsert = await Promise.all(\r\n Array\r\n .from(items)\r\n .map((item) => this.processFile(item))\r\n );\r\n dataToInsert = dataToInsert.filter((data) => !!data);\r\n\r\n const isCurrentBlockDefault = BlockManager.currentBlock.tool.isDefault;\r\n const needToReplaceCurrentBlock = isCurrentBlockDefault && BlockManager.currentBlock.isEmpty;\r\n\r\n dataToInsert.forEach(\r\n (data, i) => {\r\n BlockManager.paste(data.type, data.event, i === 0 && needToReplaceCurrentBlock);\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Get information about file and find Tool to handle it\r\n *\r\n * @param {File} file - file to process\r\n */\r\n private async processFile(file: File): Promise<{ event: PasteEvent; type: string }> {\r\n const extension = _.getFileExtension(file);\r\n\r\n const foundConfig = Object\r\n .entries(this.toolsFiles)\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars\r\n .find(([toolName, { mimeTypes, extensions } ]) => {\r\n const [fileType, fileSubtype] = file.type.split('/');\r\n\r\n const foundExt = extensions.find((ext) => ext.toLowerCase() === extension.toLowerCase());\r\n const foundMimeType = mimeTypes.find((mime) => {\r\n const [type, subtype] = mime.split('/');\r\n\r\n return type === fileType && (subtype === fileSubtype || subtype === '*');\r\n });\r\n\r\n return !!foundExt || !!foundMimeType;\r\n });\r\n\r\n if (!foundConfig) {\r\n return;\r\n }\r\n\r\n const [ tool ] = foundConfig;\r\n const pasteEvent = this.composePasteEvent('file', {\r\n file,\r\n });\r\n\r\n return {\r\n event: pasteEvent,\r\n type: tool,\r\n };\r\n }\r\n\r\n /**\r\n * Split HTML string to blocks and return it as array of Block data\r\n *\r\n * @param {string} innerHTML - html string to process\r\n * @returns {PasteData[]}\r\n */\r\n private processHTML(innerHTML: string): PasteData[] {\r\n const { Tools } = this.Editor;\r\n\r\n /**\r\n * @todo Research, do we really need to always wrap innerHTML to a div:\r\n * - <img> tag could be processed separately, but for now it becomes div-wrapped\r\n * and then .getNodes() returns strange: [document-fragment, img]\r\n * (description of the method says that it should should return only block tags or fragments,\r\n * but there are inline-block element along with redundant empty fragment)\r\n * - probably this is a reason of bugs with unexpected new block creation instead of inline pasting:\r\n * - https://github.com/codex-team/editor.js/issues/1427\r\n * - https://github.com/codex-team/editor.js/issues/1244\r\n * - https://github.com/codex-team/editor.js/issues/740\r\n */\r\n const wrapper = $.make('DIV');\r\n\r\n wrapper.innerHTML = innerHTML;\r\n\r\n const nodes = this.getNodes(wrapper);\r\n\r\n return nodes\r\n .map((node) => {\r\n let content, tool = Tools.defaultTool, isBlock = false;\r\n\r\n switch (node.nodeType) {\r\n /** If node is a document fragment, use temp wrapper to get innerHTML */\r\n case Node.DOCUMENT_FRAGMENT_NODE:\r\n content = $.make('div');\r\n content.appendChild(node);\r\n break;\r\n\r\n /** If node is an element, then there might be a substitution */\r\n case Node.ELEMENT_NODE:\r\n content = node as HTMLElement;\r\n isBlock = true;\r\n\r\n if (this.toolsTags[content.tagName]) {\r\n tool = this.toolsTags[content.tagName].tool;\r\n }\r\n break;\r\n }\r\n\r\n /**\r\n * Returns empty array if there is no paste config\r\n */\r\n const { tags: tagsOrSanitizeConfigs } = tool.pasteConfig || { tags: [] };\r\n\r\n /**\r\n * Reduce the tags or sanitize configs to a single array of sanitize config.\r\n * For example:\r\n * If sanitize config is\r\n * [ 'tbody',\r\n * {\r\n * table: {\r\n * width: true,\r\n * height: true,\r\n * },\r\n * },\r\n * {\r\n * td: {\r\n * colspan: true,\r\n * rowspan: true,\r\n * },\r\n * tr: { // <-- the second tag\r\n * height: true,\r\n * },\r\n * },\r\n * ]\r\n * then sanitize config will be\r\n * [\r\n * 'table':{},\r\n * 'tbody':{width: true, height: true}\r\n * 'td':{colspan: true, rowspan: true},\r\n * 'tr':{height: true}\r\n * ]\r\n */\r\n const toolTags = tagsOrSanitizeConfigs.reduce((result, tagOrSanitizeConfig) => {\r\n const tags = this.collectTagNames(tagOrSanitizeConfig);\r\n\r\n tags.forEach((tag) => {\r\n const sanitizationConfig = _.isObject(tagOrSanitizeConfig) ? tagOrSanitizeConfig[tag] : null;\r\n\r\n result[tag.toLowerCase()] = sanitizationConfig || {};\r\n });\r\n\r\n return result;\r\n }, {});\r\n\r\n const customConfig = Object.assign({}, toolTags, tool.baseSanitizeConfig);\r\n\r\n /**\r\n * A workaround for the HTMLJanitor bug with Tables (incorrect sanitizing of table.innerHTML)\r\n * https://github.com/guardian/html-janitor/issues/3\r\n */\r\n if (content.tagName.toLowerCase() === 'table') {\r\n const cleanTableHTML = clean(content.outerHTML, customConfig);\r\n const tmpWrapper = $.make('div', undefined, {\r\n innerHTML: cleanTableHTML,\r\n });\r\n\r\n content = tmpWrapper.firstChild;\r\n } else {\r\n content.innerHTML = clean(content.innerHTML, customConfig);\r\n }\r\n\r\n const event = this.composePasteEvent('tag', {\r\n data: content,\r\n });\r\n\r\n return {\r\n content,\r\n isBlock,\r\n tool: tool.name,\r\n event,\r\n };\r\n })\r\n .filter((data) => {\r\n const isEmpty = $.isEmpty(data.content);\r\n const isSingleTag = $.isSingleTag(data.content);\r\n\r\n return !isEmpty || isSingleTag;\r\n });\r\n }\r\n\r\n /**\r\n * Split plain text by new line symbols and return it as array of Block data\r\n *\r\n * @param {string} plain - string to process\r\n * @returns {PasteData[]}\r\n */\r\n private processPlain(plain: string): PasteData[] {\r\n const { defaultBlock } = this.config as { defaultBlock: string };\r\n\r\n if (!plain) {\r\n return [];\r\n }\r\n\r\n const tool = defaultBlock;\r\n\r\n return plain\r\n .split(/\\r?\\n/)\r\n .filter((text) => text.trim())\r\n .map((text) => {\r\n const content = $.make('div');\r\n\r\n content.textContent = text;\r\n\r\n const event = this.composePasteEvent('tag', {\r\n data: content,\r\n });\r\n\r\n return {\r\n content,\r\n tool,\r\n isBlock: false,\r\n event,\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Process paste of single Block tool content\r\n *\r\n * @param {PasteData} dataToInsert - data of Block to insert\r\n */\r\n private async processSingleBlock(dataToInsert: PasteData): Promise<void> {\r\n const { Caret, BlockManager } = this.Editor;\r\n const { currentBlock } = BlockManager;\r\n\r\n /**\r\n * If pasted tool isn`t equal current Block or if pasted content contains block elements, insert it as new Block\r\n */\r\n if (\r\n !currentBlock ||\r\n dataToInsert.tool !== currentBlock.name ||\r\n !$.containsOnlyInlineElements(dataToInsert.content.innerHTML)\r\n ) {\r\n this.insertBlock(dataToInsert, currentBlock?.tool.isDefault && currentBlock.isEmpty);\r\n\r\n return;\r\n }\r\n\r\n Caret.insertContentAtCaretPosition(dataToInsert.content.innerHTML);\r\n }\r\n\r\n /**\r\n * Process paste to single Block:\r\n * 1. Find patterns` matches\r\n * 2. Insert new block if it is not the same type as current one\r\n * 3. Just insert text if there is no substitutions\r\n *\r\n * @param {PasteData} dataToInsert - data of Block to insert\r\n */\r\n private async processInlinePaste(dataToInsert: PasteData): Promise<void> {\r\n const { BlockManager, Caret } = this.Editor;\r\n const { content } = dataToInsert;\r\n\r\n const currentBlockIsDefault = BlockManager.currentBlock && BlockManager.currentBlock.tool.isDefault;\r\n\r\n if (currentBlockIsDefault && content.textContent.length < Paste.PATTERN_PROCESSING_MAX_LENGTH) {\r\n const blockData = await this.processPattern(content.textContent);\r\n\r\n if (blockData) {\r\n const needToReplaceCurrentBlock = BlockManager.currentBlock &&\r\n BlockManager.currentBlock.tool.isDefault &&\r\n BlockManager.currentBlock.isEmpty;\r\n\r\n const insertedBlock = BlockManager.paste(blockData.tool, blockData.event, needToReplaceCurrentBlock);\r\n\r\n Caret.setToBlock(insertedBlock, Caret.positions.END);\r\n\r\n return;\r\n }\r\n }\r\n\r\n /** If there is no pattern substitute - insert string as it is */\r\n if (BlockManager.currentBlock && BlockManager.currentBlock.currentInput) {\r\n const currentToolSanitizeConfig = BlockManager.currentBlock.tool.baseSanitizeConfig;\r\n\r\n document.execCommand(\r\n 'insertHTML',\r\n false,\r\n clean(content.innerHTML, currentToolSanitizeConfig)\r\n );\r\n } else {\r\n this.insertBlock(dataToInsert);\r\n }\r\n }\r\n\r\n /**\r\n * Get patterns` matches\r\n *\r\n * @param {string} text - text to process\r\n * @returns {Promise<{event: PasteEvent, tool: string}>}\r\n */\r\n private async processPattern(text: string): Promise<{ event: PasteEvent; tool: string }> {\r\n const pattern = this.toolsPatterns.find((substitute) => {\r\n const execResult = substitute.pattern.exec(text);\r\n\r\n if (!execResult) {\r\n return false;\r\n }\r\n\r\n return text === execResult.shift();\r\n });\r\n\r\n if (!pattern) {\r\n return;\r\n }\r\n\r\n const event = this.composePasteEvent('pattern', {\r\n key: pattern.key,\r\n data: text,\r\n });\r\n\r\n return {\r\n event,\r\n tool: pattern.tool.name,\r\n };\r\n }\r\n\r\n /**\r\n * Insert pasted Block content to Editor\r\n *\r\n * @param {PasteData} data - data to insert\r\n * @param {boolean} canReplaceCurrentBlock - if true and is current Block is empty, will replace current Block\r\n * @returns {void}\r\n */\r\n private insertBlock(data: PasteData, canReplaceCurrentBlock = false): void {\r\n const { BlockManager, Caret } = this.Editor;\r\n const { currentBlock } = BlockManager;\r\n let block: Block;\r\n\r\n if (canReplaceCurrentBlock && currentBlock && currentBlock.isEmpty) {\r\n block = BlockManager.paste(data.tool, data.event, true);\r\n Caret.setToBlock(block, Caret.positions.END);\r\n\r\n return;\r\n }\r\n\r\n block = BlockManager.paste(data.tool, data.event);\r\n\r\n Caret.setToBlock(block, Caret.positions.END);\r\n }\r\n\r\n /**\r\n * Insert data passed as application/x-editor-js JSON\r\n *\r\n * @param {Array} blocks — Blocks' data to insert\r\n * @returns {void}\r\n */\r\n private insertEditorJSData(blocks: Pick<SavedData, 'id' | 'data' | 'tool'>[]): void {\r\n const { BlockManager, Caret, Tools } = this.Editor;\r\n const sanitizedBlocks = sanitizeBlocks(blocks, (name) =>\r\n Tools.blockTools.get(name).sanitizeConfig\r\n );\r\n\r\n sanitizedBlocks.forEach(({ tool, data }, i) => {\r\n let needToReplaceCurrentBlock = false;\r\n\r\n if (i === 0) {\r\n const isCurrentBlockDefault = BlockManager.currentBlock && BlockManager.currentBlock.tool.isDefault;\r\n\r\n needToReplaceCurrentBlock = isCurrentBlockDefault && BlockManager.currentBlock.isEmpty;\r\n }\r\n\r\n const block = BlockManager.insert({\r\n tool,\r\n data,\r\n replace: needToReplaceCurrentBlock,\r\n });\r\n\r\n Caret.setToBlock(block, Caret.positions.END);\r\n });\r\n }\r\n\r\n /**\r\n * Fetch nodes from Element node\r\n *\r\n * @param {Node} node - current node\r\n * @param {Node[]} nodes - processed nodes\r\n * @param {Node} destNode - destination node\r\n */\r\n private processElementNode(node: Node, nodes: Node[], destNode: Node): Node[] | void {\r\n const tags = Object.keys(this.toolsTags);\r\n\r\n const element = node as HTMLElement;\r\n\r\n const { tool } = this.toolsTags[element.tagName] || {};\r\n const toolTags = this.tagsByTool[tool?.name] || [];\r\n\r\n const isSubstitutable = tags.includes(element.tagName);\r\n const isBlockElement = $.blockElements.includes(element.tagName.toLowerCase());\r\n const containsAnotherToolTags = Array\r\n .from(element.children)\r\n .some(\r\n ({ tagName }) => tags.includes(tagName) && !toolTags.includes(tagName)\r\n );\r\n\r\n const containsBlockElements = Array.from(element.children).some(\r\n ({ tagName }) => $.blockElements.includes(tagName.toLowerCase())\r\n );\r\n\r\n /** Append inline elements to previous fragment */\r\n if (!isBlockElement && !isSubstitutable && !containsAnotherToolTags) {\r\n destNode.appendChild(element);\r\n\r\n return [...nodes, destNode];\r\n }\r\n\r\n if (\r\n (isSubstitutable && !containsAnotherToolTags) ||\r\n (isBlockElement && !containsBlockElements && !containsAnotherToolTags)\r\n ) {\r\n return [...nodes, destNode, element];\r\n }\r\n }\r\n\r\n /**\r\n * Recursively divide HTML string to two types of nodes:\r\n * 1. Block element\r\n * 2. Document Fragments contained text and markup tags like a, b, i etc.\r\n *\r\n * @param {Node} wrapper - wrapper of paster HTML content\r\n * @returns {Node[]}\r\n */\r\n private getNodes(wrapper: Node): Node[] {\r\n const children = Array.from(wrapper.childNodes);\r\n let elementNodeProcessingResult: Node[] | void;\r\n\r\n const reducer = (nodes: Node[], node: Node): Node[] => {\r\n if ($.isEmpty(node) && !$.isSingleTag(node as HTMLElement)) {\r\n return nodes;\r\n }\r\n\r\n const lastNode = nodes[nodes.length - 1];\r\n\r\n let destNode: Node = new DocumentFragment();\r\n\r\n if (lastNode && $.isFragment(lastNode)) {\r\n destNode = nodes.pop();\r\n }\r\n\r\n switch (node.nodeType) {\r\n /**\r\n * If node is HTML element:\r\n * 1. Check if it is inline element\r\n * 2. Check if it contains another block or substitutable elements\r\n */\r\n case Node.ELEMENT_NODE:\r\n elementNodeProcessingResult = this.processElementNode(node, nodes, destNode);\r\n\r\n if (elementNodeProcessingResult) {\r\n return elementNodeProcessingResult;\r\n }\r\n break;\r\n\r\n /**\r\n * If node is text node, wrap it with DocumentFragment\r\n */\r\n case Node.TEXT_NODE:\r\n destNode.appendChild(node);\r\n\r\n return [...nodes, destNode];\r\n\r\n default:\r\n return [...nodes, destNode];\r\n }\r\n\r\n return [...nodes, ...Array.from(node.childNodes).reduce(reducer, [])];\r\n };\r\n\r\n return children.reduce(reducer, []);\r\n }\r\n\r\n /**\r\n * Compose paste event with passed type and detail\r\n *\r\n * @param {string} type - event type\r\n * @param {PasteEventDetail} detail - event detail\r\n */\r\n private composePasteEvent(type: string, detail: PasteEventDetail): PasteEvent {\r\n return new CustomEvent(type, {\r\n detail,\r\n }) as PasteEvent;\r\n }\r\n}\r\n\r\n","import Module from '../__module';\r\nimport { CriticalError } from '../errors/critical';\r\n\r\n/**\r\n * @module ReadOnly\r\n *\r\n * Has one important method:\r\n * - {Function} toggleReadonly - Set read-only mode or toggle current state\r\n * @version 1.0.0\r\n * @typedef {ReadOnly} ReadOnly\r\n * @property {boolean} readOnlyEnabled - read-only state\r\n */\r\nexport default class ReadOnly extends Module {\r\n /**\r\n * Array of tools name which don't support read-only mode\r\n */\r\n private toolsDontSupportReadOnly: string[] = [];\r\n\r\n /**\r\n * Value to track read-only state\r\n *\r\n * @type {boolean}\r\n */\r\n private readOnlyEnabled = false;\r\n\r\n /**\r\n * Returns state of read only mode\r\n */\r\n public get isEnabled(): boolean {\r\n return this.readOnlyEnabled;\r\n }\r\n\r\n /**\r\n * Set initial state\r\n */\r\n public async prepare(): Promise<void> {\r\n const { Tools } = this.Editor;\r\n const { blockTools } = Tools;\r\n const toolsDontSupportReadOnly: string[] = [];\r\n\r\n Array\r\n .from(blockTools.entries())\r\n .forEach(([name, tool]) => {\r\n if (!tool.isReadOnlySupported) {\r\n toolsDontSupportReadOnly.push(name);\r\n }\r\n });\r\n\r\n this.toolsDontSupportReadOnly = toolsDontSupportReadOnly;\r\n\r\n if (this.config.readOnly && toolsDontSupportReadOnly.length > 0) {\r\n this.throwCriticalError();\r\n }\r\n\r\n this.toggle(this.config.readOnly, true);\r\n }\r\n\r\n /**\r\n * Set read-only mode or toggle current state\r\n * Call all Modules `toggleReadOnly` method and re-render Editor\r\n *\r\n * @param state - (optional) read-only state or toggle\r\n * @param isInitial - (optional) true when editor is initializing\r\n */\r\n public async toggle(state = !this.readOnlyEnabled, isInitial = false): Promise<boolean> {\r\n if (state && this.toolsDontSupportReadOnly.length > 0) {\r\n this.throwCriticalError();\r\n }\r\n\r\n const oldState = this.readOnlyEnabled;\r\n\r\n this.readOnlyEnabled = state;\r\n\r\n for (const name in this.Editor) {\r\n /**\r\n * Verify module has method `toggleReadOnly` method\r\n */\r\n if (!this.Editor[name].toggleReadOnly) {\r\n continue;\r\n }\r\n\r\n /**\r\n * set or toggle read-only state\r\n */\r\n this.Editor[name].toggleReadOnly(state);\r\n }\r\n\r\n /**\r\n * If new state equals old one, do not re-render blocks\r\n */\r\n if (oldState === state) {\r\n return this.readOnlyEnabled;\r\n }\r\n\r\n /**\r\n * Do not re-render blocks if it's initial call\r\n */\r\n if (isInitial) {\r\n return this.readOnlyEnabled;\r\n }\r\n\r\n /**\r\n * Mutex for modifications observer to prevent onChange call when read-only mode is enabled\r\n */\r\n this.Editor.ModificationsObserver.disable();\r\n\r\n /**\r\n * Save current Editor Blocks and render again\r\n */\r\n const savedBlocks = await this.Editor.Saver.save();\r\n\r\n await this.Editor.BlockManager.clear();\r\n await this.Editor.Renderer.render(savedBlocks.blocks);\r\n\r\n this.Editor.ModificationsObserver.enable();\r\n\r\n return this.readOnlyEnabled;\r\n }\r\n\r\n /**\r\n * Throws an error about tools which don't support read-only mode\r\n */\r\n private throwCriticalError(): never {\r\n throw new CriticalError(\r\n `To enable read-only mode all connected tools should support it. Tools ${this.toolsDontSupportReadOnly.join(', ')} don't support read-only mode.`\r\n );\r\n }\r\n}\r\n","/**\r\n * @class RectangleSelection\r\n * @classdesc Manages Block selection with mouse\r\n * @module RectangleSelection\r\n * @version 1.0.0\r\n */\r\nimport Module from '../__module';\r\nimport $ from '../dom';\r\n\r\nimport SelectionUtils from '../selection';\r\nimport Block from '../block';\r\nimport * as _ from '../utils';\r\n\r\n/**\r\n *\r\n */\r\nexport default class RectangleSelection extends Module {\r\n /**\r\n * CSS classes for the Block\r\n *\r\n * @returns {{wrapper: string, content: string}}\r\n */\r\n public static get CSS(): {[name: string]: string} {\r\n return {\r\n overlay: 'codex-editor-overlay',\r\n overlayContainer: 'codex-editor-overlay__container',\r\n rect: 'codex-editor-overlay__rectangle',\r\n topScrollZone: 'codex-editor-overlay__scroll-zone--top',\r\n bottomScrollZone: 'codex-editor-overlay__scroll-zone--bottom',\r\n };\r\n }\r\n\r\n /**\r\n * Using the selection rectangle\r\n *\r\n * @type {boolean}\r\n */\r\n private isRectSelectionActivated = false;\r\n\r\n /**\r\n * Speed of Scrolling\r\n */\r\n private readonly SCROLL_SPEED: number = 3;\r\n\r\n /**\r\n * Height of scroll zone on boundary of screen\r\n */\r\n private readonly HEIGHT_OF_SCROLL_ZONE = 40;\r\n\r\n /**\r\n * Scroll zone type indicators\r\n */\r\n private readonly BOTTOM_SCROLL_ZONE = 1;\r\n private readonly TOP_SCROLL_ZONE = 2;\r\n\r\n /**\r\n * Id of main button for event.button\r\n */\r\n private readonly MAIN_MOUSE_BUTTON = 0;\r\n\r\n /**\r\n * Mouse is clamped\r\n */\r\n private mousedown = false;\r\n\r\n /**\r\n * Is scrolling now\r\n */\r\n private isScrolling = false;\r\n\r\n /**\r\n * Mouse is in scroll zone\r\n */\r\n private inScrollZone: number | null = null;\r\n\r\n /**\r\n * Coords of rect\r\n */\r\n private startX = 0;\r\n private startY = 0;\r\n private mouseX = 0;\r\n private mouseY = 0;\r\n\r\n /**\r\n * Selected blocks\r\n */\r\n private stackOfSelected: number[] = [];\r\n\r\n /**\r\n * Does the rectangle intersect blocks\r\n */\r\n private rectCrossesBlocks: boolean;\r\n\r\n /**\r\n * Selection rectangle\r\n */\r\n private overlayRectangle: HTMLDivElement;\r\n\r\n /**\r\n * Listener identifiers\r\n */\r\n private listenerIds: string[] = [];\r\n\r\n /**\r\n * Module Preparation\r\n * Creating rect and hang handlers\r\n */\r\n public prepare(): void {\r\n this.enableModuleBindings();\r\n }\r\n\r\n /**\r\n * Init rect params\r\n *\r\n * @param {number} pageX - X coord of mouse\r\n * @param {number} pageY - Y coord of mouse\r\n */\r\n public startSelection(pageX, pageY): void {\r\n const elemWhereSelectionStart = document.elementFromPoint(pageX - window.pageXOffset, pageY - window.pageYOffset);\r\n\r\n /**\r\n * Don't clear selected block by clicks on the Block settings\r\n * because we need to keep highlighting working block\r\n */\r\n const startsInsideToolbar = elemWhereSelectionStart.closest(`.${this.Editor.Toolbar.CSS.toolbar}`);\r\n\r\n if (!startsInsideToolbar) {\r\n this.Editor.BlockSelection.allBlocksSelected = false;\r\n this.clearSelection();\r\n this.stackOfSelected = [];\r\n }\r\n\r\n const selectorsToAvoid = [\r\n `.${Block.CSS.content}`,\r\n `.${this.Editor.Toolbar.CSS.toolbar}`,\r\n `.${this.Editor.InlineToolbar.CSS.inlineToolbar}`,\r\n ];\r\n\r\n const startsInsideEditor = elemWhereSelectionStart.closest('.' + this.Editor.UI.CSS.editorWrapper);\r\n const startsInSelectorToAvoid = selectorsToAvoid.some((selector) => !!elemWhereSelectionStart.closest(selector));\r\n\r\n /**\r\n * If selection starts outside of the editor or inside the blocks or on Editor UI elements, do not handle it\r\n */\r\n if (!startsInsideEditor || startsInSelectorToAvoid) {\r\n return;\r\n }\r\n\r\n this.mousedown = true;\r\n this.startX = pageX;\r\n this.startY = pageY;\r\n }\r\n\r\n /**\r\n * Clear all params to end selection\r\n */\r\n public endSelection(): void {\r\n this.mousedown = false;\r\n this.startX = 0;\r\n this.startY = 0;\r\n this.overlayRectangle.style.display = 'none';\r\n }\r\n\r\n /**\r\n * is RectSelection Activated\r\n */\r\n public isRectActivated(): boolean {\r\n return this.isRectSelectionActivated;\r\n }\r\n\r\n /**\r\n * Mark that selection is end\r\n */\r\n public clearSelection(): void {\r\n this.isRectSelectionActivated = false;\r\n }\r\n\r\n /**\r\n * Sets Module necessary event handlers\r\n */\r\n private enableModuleBindings(): void {\r\n const { container } = this.genHTML();\r\n\r\n this.listeners.on(container, 'mousedown', (mouseEvent: MouseEvent) => {\r\n this.processMouseDown(mouseEvent);\r\n }, false);\r\n\r\n this.listeners.on(document.body, 'mousemove', _.throttle((mouseEvent: MouseEvent) => {\r\n this.processMouseMove(mouseEvent);\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n }, 10), {\r\n passive: true,\r\n });\r\n\r\n this.listeners.on(document.body, 'mouseleave', () => {\r\n this.processMouseLeave();\r\n });\r\n\r\n this.listeners.on(window, 'scroll', _.throttle((mouseEvent: MouseEvent) => {\r\n this.processScroll(mouseEvent);\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n }, 10), {\r\n passive: true,\r\n });\r\n\r\n this.listeners.on(document.body, 'mouseup', () => {\r\n this.processMouseUp();\r\n }, false);\r\n }\r\n\r\n /**\r\n * Handle mouse down events\r\n *\r\n * @param {MouseEvent} mouseEvent - mouse event payload\r\n */\r\n private processMouseDown(mouseEvent: MouseEvent): void {\r\n if (mouseEvent.button !== this.MAIN_MOUSE_BUTTON) {\r\n return;\r\n }\r\n\r\n /**\r\n * Do not enable the Rectangle Selection when mouse dragging started some editable input\r\n * Used to prevent Rectangle Selection on Block Tune wrappers' inputs that also can be inside the Block\r\n */\r\n const startedFromContentEditable = (mouseEvent.target as Element).closest($.allInputsSelector) !== null;\r\n\r\n if (!startedFromContentEditable) {\r\n this.startSelection(mouseEvent.pageX, mouseEvent.pageY);\r\n }\r\n }\r\n\r\n /**\r\n * Handle mouse move events\r\n *\r\n * @param {MouseEvent} mouseEvent - mouse event payload\r\n */\r\n private processMouseMove(mouseEvent: MouseEvent): void {\r\n this.changingRectangle(mouseEvent);\r\n this.scrollByZones(mouseEvent.clientY);\r\n }\r\n\r\n /**\r\n * Handle mouse leave\r\n */\r\n private processMouseLeave(): void {\r\n this.clearSelection();\r\n this.endSelection();\r\n }\r\n\r\n /**\r\n * @param {MouseEvent} mouseEvent - mouse event payload\r\n */\r\n private processScroll(mouseEvent: MouseEvent): void {\r\n this.changingRectangle(mouseEvent);\r\n }\r\n\r\n /**\r\n * Handle mouse up\r\n */\r\n private processMouseUp(): void {\r\n this.clearSelection();\r\n this.endSelection();\r\n }\r\n\r\n /**\r\n * Scroll If mouse in scroll zone\r\n *\r\n * @param {number} clientY - Y coord of mouse\r\n */\r\n private scrollByZones(clientY): void {\r\n this.inScrollZone = null;\r\n if (clientY <= this.HEIGHT_OF_SCROLL_ZONE) {\r\n this.inScrollZone = this.TOP_SCROLL_ZONE;\r\n }\r\n if (document.documentElement.clientHeight - clientY <= this.HEIGHT_OF_SCROLL_ZONE) {\r\n this.inScrollZone = this.BOTTOM_SCROLL_ZONE;\r\n }\r\n\r\n if (!this.inScrollZone) {\r\n this.isScrolling = false;\r\n\r\n return;\r\n }\r\n\r\n if (!this.isScrolling) {\r\n this.scrollVertical(this.inScrollZone === this.TOP_SCROLL_ZONE ? -this.SCROLL_SPEED : this.SCROLL_SPEED);\r\n this.isScrolling = true;\r\n }\r\n }\r\n\r\n /**\r\n * Generates required HTML elements\r\n *\r\n * @returns {Object<string, Element>}\r\n */\r\n private genHTML(): {container: Element; overlay: Element} {\r\n const { UI } = this.Editor;\r\n\r\n const container = UI.nodes.holder.querySelector('.' + UI.CSS.editorWrapper);\r\n const overlay = $.make('div', RectangleSelection.CSS.overlay, {});\r\n const overlayContainer = $.make('div', RectangleSelection.CSS.overlayContainer, {});\r\n const overlayRectangle = $.make('div', RectangleSelection.CSS.rect, {});\r\n\r\n overlayContainer.appendChild(overlayRectangle);\r\n overlay.appendChild(overlayContainer);\r\n container.appendChild(overlay);\r\n\r\n this.overlayRectangle = overlayRectangle as HTMLDivElement;\r\n\r\n return {\r\n container,\r\n overlay,\r\n };\r\n }\r\n\r\n /**\r\n * Activates scrolling if blockSelection is active and mouse is in scroll zone\r\n *\r\n * @param {number} speed - speed of scrolling\r\n */\r\n private scrollVertical(speed): void {\r\n if (!(this.inScrollZone && this.mousedown)) {\r\n return;\r\n }\r\n const lastOffset = window.pageYOffset;\r\n\r\n window.scrollBy(0, speed);\r\n this.mouseY += window.pageYOffset - lastOffset;\r\n setTimeout(() => {\r\n this.scrollVertical(speed);\r\n }, 0);\r\n }\r\n\r\n /**\r\n * Handles the change in the rectangle and its effect\r\n *\r\n * @param {MouseEvent} event - mouse event\r\n */\r\n private changingRectangle(event: MouseEvent): void {\r\n if (!this.mousedown) {\r\n return;\r\n }\r\n\r\n if (event.pageY !== undefined) {\r\n this.mouseX = event.pageX;\r\n this.mouseY = event.pageY;\r\n }\r\n\r\n const { rightPos, leftPos, index } = this.genInfoForMouseSelection();\r\n // There is not new block in selection\r\n\r\n const rectIsOnRighSideOfredactor = this.startX > rightPos && this.mouseX > rightPos;\r\n const rectISOnLeftSideOfRedactor = this.startX < leftPos && this.mouseX < leftPos;\r\n\r\n this.rectCrossesBlocks = !(rectIsOnRighSideOfredactor || rectISOnLeftSideOfRedactor);\r\n\r\n if (!this.isRectSelectionActivated) {\r\n this.rectCrossesBlocks = false;\r\n this.isRectSelectionActivated = true;\r\n this.shrinkRectangleToPoint();\r\n this.overlayRectangle.style.display = 'block';\r\n }\r\n\r\n this.updateRectangleSize();\r\n\r\n /**\r\n * Hide Block Settings Toggler (along with the Toolbar) (if showed) when the Rectangle Selection is activated\r\n */\r\n this.Editor.Toolbar.close();\r\n\r\n if (index === undefined) {\r\n return;\r\n }\r\n\r\n this.trySelectNextBlock(index);\r\n // For case, when rect is out from blocks\r\n this.inverseSelection();\r\n\r\n SelectionUtils.get().removeAllRanges();\r\n }\r\n\r\n /**\r\n * Shrink rect to singular point\r\n */\r\n private shrinkRectangleToPoint(): void {\r\n this.overlayRectangle.style.left = `${this.startX - window.pageXOffset}px`;\r\n this.overlayRectangle.style.top = `${this.startY - window.pageYOffset}px`;\r\n this.overlayRectangle.style.bottom = `calc(100% - ${this.startY - window.pageYOffset}px`;\r\n this.overlayRectangle.style.right = `calc(100% - ${this.startX - window.pageXOffset}px`;\r\n }\r\n\r\n /**\r\n * Select or unselect all of blocks in array if rect is out or in selectable area\r\n */\r\n private inverseSelection(): void {\r\n const firstBlockInStack = this.Editor.BlockManager.getBlockByIndex(this.stackOfSelected[0]);\r\n const isSelectedMode = firstBlockInStack.selected;\r\n\r\n if (this.rectCrossesBlocks && !isSelectedMode) {\r\n for (const it of this.stackOfSelected) {\r\n this.Editor.BlockSelection.selectBlockByIndex(it);\r\n }\r\n }\r\n\r\n if (!this.rectCrossesBlocks && isSelectedMode) {\r\n for (const it of this.stackOfSelected) {\r\n this.Editor.BlockSelection.unSelectBlockByIndex(it);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates size of rectangle\r\n */\r\n private updateRectangleSize(): void {\r\n // Depending on the position of the mouse relative to the starting point,\r\n // change this.e distance from the desired edge of the screen*/\r\n if (this.mouseY >= this.startY) {\r\n this.overlayRectangle.style.top = `${this.startY - window.pageYOffset}px`;\r\n this.overlayRectangle.style.bottom = `calc(100% - ${this.mouseY - window.pageYOffset}px`;\r\n } else {\r\n this.overlayRectangle.style.bottom = `calc(100% - ${this.startY - window.pageYOffset}px`;\r\n this.overlayRectangle.style.top = `${this.mouseY - window.pageYOffset}px`;\r\n }\r\n\r\n if (this.mouseX >= this.startX) {\r\n this.overlayRectangle.style.left = `${this.startX - window.pageXOffset}px`;\r\n this.overlayRectangle.style.right = `calc(100% - ${this.mouseX - window.pageXOffset}px`;\r\n } else {\r\n this.overlayRectangle.style.right = `calc(100% - ${this.startX - window.pageXOffset}px`;\r\n this.overlayRectangle.style.left = `${this.mouseX - window.pageXOffset}px`;\r\n }\r\n }\r\n\r\n /**\r\n * Collects information needed to determine the behavior of the rectangle\r\n *\r\n * @returns {object} index - index next Block, leftPos - start of left border of Block, rightPos - right border\r\n */\r\n private genInfoForMouseSelection(): {index: number; leftPos: number; rightPos: number} {\r\n const widthOfRedactor = document.body.offsetWidth;\r\n const centerOfRedactor = widthOfRedactor / 2;\r\n const Y = this.mouseY - window.pageYOffset;\r\n const elementUnderMouse = document.elementFromPoint(centerOfRedactor, Y);\r\n const blockInCurrentPos = this.Editor.BlockManager.getBlockByChildNode(elementUnderMouse);\r\n let index;\r\n\r\n if (blockInCurrentPos !== undefined) {\r\n index = this.Editor.BlockManager.blocks.findIndex((block) => block.holder === blockInCurrentPos.holder);\r\n }\r\n const contentElement = this.Editor.BlockManager.lastBlock.holder.querySelector('.' + Block.CSS.content);\r\n const centerOfBlock = Number.parseInt(window.getComputedStyle(contentElement).width, 10) / 2;\r\n const leftPos = centerOfRedactor - centerOfBlock;\r\n const rightPos = centerOfRedactor + centerOfBlock;\r\n\r\n return {\r\n index,\r\n leftPos,\r\n rightPos,\r\n };\r\n }\r\n\r\n /**\r\n * Select block with index index\r\n *\r\n * @param index - index of block in redactor\r\n */\r\n private addBlockInSelection(index): void {\r\n if (this.rectCrossesBlocks) {\r\n this.Editor.BlockSelection.selectBlockByIndex(index);\r\n }\r\n this.stackOfSelected.push(index);\r\n }\r\n\r\n /**\r\n * Adds a block to the selection and determines which blocks should be selected\r\n *\r\n * @param {object} index - index of new block in the reactor\r\n */\r\n private trySelectNextBlock(index): void {\r\n const sameBlock = this.stackOfSelected[this.stackOfSelected.length - 1] === index;\r\n const sizeStack = this.stackOfSelected.length;\r\n const down = 1, up = -1, undef = 0;\r\n\r\n if (sameBlock) {\r\n return;\r\n }\r\n\r\n const blockNumbersIncrease = this.stackOfSelected[sizeStack - 1] - this.stackOfSelected[sizeStack - 2] > 0;\r\n\r\n let direction = undef;\r\n\r\n if (sizeStack > 1) {\r\n direction = blockNumbersIncrease ? down : up;\r\n }\r\n\r\n const selectionInDownDirection = index > this.stackOfSelected[sizeStack - 1] && direction === down;\r\n const selectionInUpDirection = index < this.stackOfSelected[sizeStack - 1] && direction === up;\r\n const generalSelection = selectionInDownDirection || selectionInUpDirection || direction === undef;\r\n const reduction = !generalSelection;\r\n\r\n // When the selection is too fast, some blocks do not have time to be noticed. Fix it.\r\n if (!reduction && (index > this.stackOfSelected[sizeStack - 1] ||\r\n this.stackOfSelected[sizeStack - 1] === undefined)) {\r\n let ind = this.stackOfSelected[sizeStack - 1] + 1 || index;\r\n\r\n for (ind; ind <= index; ind++) {\r\n this.addBlockInSelection(ind);\r\n }\r\n\r\n return;\r\n }\r\n\r\n // for both directions\r\n if (!reduction && (index < this.stackOfSelected[sizeStack - 1])) {\r\n for (let ind = this.stackOfSelected[sizeStack - 1] - 1; ind >= index; ind--) {\r\n this.addBlockInSelection(ind);\r\n }\r\n\r\n return;\r\n }\r\n\r\n if (!reduction) {\r\n return;\r\n }\r\n\r\n let i = sizeStack - 1;\r\n let cmp;\r\n\r\n // cmp for different directions\r\n if (index > this.stackOfSelected[sizeStack - 1]) {\r\n cmp = (): boolean => index > this.stackOfSelected[i];\r\n } else {\r\n cmp = (): boolean => index < this.stackOfSelected[i];\r\n }\r\n\r\n // Remove blocks missed due to speed.\r\n // cmp checks if we have removed all the necessary blocks\r\n while (cmp()) {\r\n if (this.rectCrossesBlocks) {\r\n this.Editor.BlockSelection.unSelectBlockByIndex(this.stackOfSelected[i]);\r\n }\r\n this.stackOfSelected.pop();\r\n i--;\r\n }\r\n }\r\n}\r\n","import Module from '../__module';\r\nimport * as _ from '../utils';\r\nimport type { BlockId, BlockToolData, OutputBlockData } from '../../../types';\r\nimport type BlockToolAdapter from '../tools/block';\r\nimport type { StubData } from '../../tools/stub';\r\nimport type Block from '../block';\r\n\r\n/**\r\n * Module that responsible for rendering Blocks on editor initialization\r\n */\r\nexport default class Renderer extends Module {\r\n /**\r\n * Renders passed blocks as one batch\r\n *\r\n * @param blocksData - blocks to render\r\n */\r\n public async render(blocksData: OutputBlockData[]): Promise<void> {\r\n return new Promise((resolve) => {\r\n const { Tools, BlockManager } = this.Editor;\r\n\r\n if (blocksData.length === 0) {\r\n BlockManager.insert();\r\n } else {\r\n /**\r\n * Create Blocks instances\r\n */\r\n const blocks = blocksData.map(({ type: tool, data, tunes, id }) => {\r\n if (Tools.available.has(tool) === false) {\r\n _.logLabeled(`Tool «${tool}» is not found. Check 'tools' property at the Editor.js config.`, 'warn');\r\n\r\n data = this.composeStubDataForTool(tool, data, id);\r\n tool = Tools.stubTool;\r\n }\r\n\r\n let block: Block;\r\n\r\n try {\r\n block = BlockManager.composeBlock({\r\n id,\r\n tool,\r\n data,\r\n tunes,\r\n });\r\n } catch (error) {\r\n _.log(`Block «${tool}» skipped because of plugins error`, 'error', {\r\n data,\r\n error,\r\n });\r\n\r\n /**\r\n * If tool throws an error during render, we should render stub instead of it\r\n */\r\n data = this.composeStubDataForTool(tool, data, id);\r\n tool = Tools.stubTool;\r\n\r\n block = BlockManager.composeBlock({\r\n id,\r\n tool,\r\n data,\r\n tunes,\r\n });\r\n }\r\n\r\n return block;\r\n });\r\n\r\n /**\r\n * Insert batch of Blocks\r\n */\r\n BlockManager.insertMany(blocks);\r\n }\r\n\r\n /**\r\n * Wait till browser will render inserted Blocks and resolve a promise\r\n */\r\n window.requestIdleCallback(() => {\r\n resolve();\r\n }, { timeout: 2000 });\r\n });\r\n }\r\n\r\n /**\r\n * Create data for the Stub Tool that will be used instead of unavailable tool\r\n *\r\n * @param tool - unavailable tool name to stub\r\n * @param data - data of unavailable block\r\n * @param [id] - id of unavailable block\r\n */\r\n private composeStubDataForTool(tool: string, data: BlockToolData, id?: BlockId): StubData {\r\n const { Tools } = this.Editor;\r\n\r\n let title = tool;\r\n\r\n if (Tools.unavailable.has(tool)) {\r\n const toolboxSettings = (Tools.unavailable.get(tool) as BlockToolAdapter).toolbox;\r\n\r\n if (toolboxSettings !== undefined && toolboxSettings[0].title !== undefined) {\r\n title = toolboxSettings[0].title;\r\n }\r\n }\r\n\r\n return {\r\n savedData: {\r\n id,\r\n type: tool,\r\n data,\r\n },\r\n title,\r\n };\r\n }\r\n}\r\n","/**\r\n * Editor.js Saver\r\n *\r\n * @module Saver\r\n * @author Codex Team\r\n * @version 2.0.0\r\n */\r\nimport Module from '../__module';\r\nimport type { OutputData } from '../../../types';\r\nimport type { SavedData, ValidatedData } from '../../../types/data-formats';\r\nimport type Block from '../block';\r\nimport * as _ from '../utils';\r\nimport { sanitizeBlocks } from '../utils/sanitizer';\r\n\r\ndeclare const VERSION: string;\r\n\r\n/**\r\n * @classdesc This method reduces all Blocks asyncronically and calls Block's save method to extract data\r\n * @typedef {Saver} Saver\r\n * @property {Element} html - Editor HTML content\r\n * @property {string} json - Editor JSON output\r\n */\r\nexport default class Saver extends Module {\r\n /**\r\n * Composes new chain of Promises to fire them alternatelly\r\n *\r\n * @returns {OutputData}\r\n */\r\n public async save(): Promise<OutputData> {\r\n const { BlockManager, Tools } = this.Editor;\r\n const blocks = BlockManager.blocks,\r\n chainData = [];\r\n\r\n try {\r\n blocks.forEach((block: Block) => {\r\n chainData.push(this.getSavedData(block));\r\n });\r\n\r\n const extractedData = await Promise.all(chainData) as Array<Pick<SavedData, 'data' | 'tool'>>;\r\n const sanitizedData = await sanitizeBlocks(extractedData, (name) => {\r\n return Tools.blockTools.get(name).sanitizeConfig;\r\n });\r\n\r\n return this.makeOutput(sanitizedData);\r\n } catch (e) {\r\n _.logLabeled(`Saving failed due to the Error %o`, 'error', e);\r\n }\r\n }\r\n\r\n /**\r\n * Saves and validates\r\n *\r\n * @param {Block} block - Editor's Tool\r\n * @returns {ValidatedData} - Tool's validated data\r\n */\r\n private async getSavedData(block: Block): Promise<ValidatedData> {\r\n const blockData = await block.save();\r\n const isValid = blockData && await block.validate(blockData.data);\r\n\r\n return {\r\n ...blockData,\r\n isValid,\r\n };\r\n }\r\n\r\n /**\r\n * Creates output object with saved data, time and version of editor\r\n *\r\n * @param {ValidatedData} allExtractedData - data extracted from Blocks\r\n * @returns {OutputData}\r\n */\r\n private makeOutput(allExtractedData): OutputData {\r\n const blocks = [];\r\n\r\n allExtractedData.forEach(({ id, tool, data, tunes, isValid }) => {\r\n if (!isValid) {\r\n _.log(`Block «${tool}» skipped because saved data is invalid`);\r\n\r\n return;\r\n }\r\n\r\n /** If it was stub Block, get original data */\r\n if (tool === this.Editor.Tools.stubTool) {\r\n blocks.push(data);\r\n\r\n return;\r\n }\r\n\r\n const output = {\r\n id,\r\n type: tool,\r\n data,\r\n ...!_.isEmpty(tunes) && {\r\n tunes,\r\n },\r\n };\r\n\r\n blocks.push(output);\r\n });\r\n\r\n return {\r\n time: +new Date(),\r\n blocks,\r\n version: VERSION,\r\n };\r\n }\r\n}\r\n","(function(){\"use strict\";try{if(typeof document<\"u\"){var e=document.createElement(\"style\");e.appendChild(document.createTextNode(\".ce-paragraph{line-height:1.6em;outline:none}.ce-block:only-of-type .ce-paragraph[data-placeholder-active]:empty:before,.ce-block:only-of-type .ce-paragraph[data-placeholder-active][data-empty=true]:before{content:attr(data-placeholder-active)}.ce-paragraph p:first-of-type{margin-top:0}.ce-paragraph p:last-of-type{margin-bottom:0}\")),document.head.appendChild(e)}}catch(a){console.error(\"vite-plugin-css-injected-by-js\",a)}})();\nconst a = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"2\" d=\"M8 9V7.2C8 7.08954 8.08954 7 8.2 7L12 7M16 9V7.2C16 7.08954 15.9105 7 15.8 7L12 7M12 7L12 17M12 17H10M12 17H14\"/></svg>';\nfunction l(r) {\n const t = document.createElement(\"div\");\n t.innerHTML = r.trim();\n const e = document.createDocumentFragment();\n return e.append(...Array.from(t.childNodes)), e;\n}\n/**\n * Base Paragraph Block for the Editor.js.\n * Represents a regular text block\n *\n * @author CodeX (team@codex.so)\n * @copyright CodeX 2018\n * @license The MIT License (MIT)\n */\nclass n {\n /**\n * Default placeholder for Paragraph Tool\n *\n * @returns {string}\n * @class\n */\n static get DEFAULT_PLACEHOLDER() {\n return \"\";\n }\n /**\n * Render plugin`s main Element and fill it with saved data\n *\n * @param {object} params - constructor params\n * @param {ParagraphData} params.data - previously saved data\n * @param {ParagraphConfig} params.config - user config for Tool\n * @param {object} params.api - editor.js api\n * @param {boolean} readOnly - read only mode flag\n */\n constructor({ data: t, config: e, api: i, readOnly: s }) {\n this.api = i, this.readOnly = s, this._CSS = {\n block: this.api.styles.block,\n wrapper: \"ce-paragraph\"\n }, this.readOnly || (this.onKeyUp = this.onKeyUp.bind(this)), this._placeholder = e.placeholder ? e.placeholder : n.DEFAULT_PLACEHOLDER, this._data = t ?? {}, this._element = null, this._preserveBlank = e.preserveBlank ?? !1;\n }\n /**\n * Check if text content is empty and set empty string to inner html.\n * We need this because some browsers (e.g. Safari) insert <br> into empty contenteditanle elements\n *\n * @param {KeyboardEvent} e - key up event\n */\n onKeyUp(t) {\n if (t.code !== \"Backspace\" && t.code !== \"Delete\" || !this._element)\n return;\n const { textContent: e } = this._element;\n e === \"\" && (this._element.innerHTML = \"\");\n }\n /**\n * Create Tool's view\n *\n * @returns {HTMLDivElement}\n * @private\n */\n drawView() {\n const t = document.createElement(\"DIV\");\n return t.classList.add(this._CSS.wrapper, this._CSS.block), t.contentEditable = \"false\", t.dataset.placeholderActive = this.api.i18n.t(this._placeholder), this._data.text && (t.innerHTML = this._data.text), this.readOnly || (t.contentEditable = \"true\", t.addEventListener(\"keyup\", this.onKeyUp)), t;\n }\n /**\n * Return Tool's view\n *\n * @returns {HTMLDivElement}\n */\n render() {\n return this._element = this.drawView(), this._element;\n }\n /**\n * Method that specified how to merge two Text blocks.\n * Called by Editor.js by backspace at the beginning of the Block\n *\n * @param {ParagraphData} data\n * @public\n */\n merge(t) {\n if (!this._element)\n return;\n this._data.text += t.text;\n const e = l(t.text);\n this._element.appendChild(e), this._element.normalize();\n }\n /**\n * Validate Paragraph block data:\n * - check for emptiness\n *\n * @param {ParagraphData} savedData — data received after saving\n * @returns {boolean} false if saved data is not correct, otherwise true\n * @public\n */\n validate(t) {\n return !(t.text.trim() === \"\" && !this._preserveBlank);\n }\n /**\n * Extract Tool's data from the view\n *\n * @param {HTMLDivElement} toolsContent - Paragraph tools rendered view\n * @returns {ParagraphData} - saved data\n * @public\n */\n save(t) {\n return {\n text: t.innerHTML\n };\n }\n /**\n * On paste callback fired from Editor.\n *\n * @param {HTMLPasteEvent} event - event with pasted data\n */\n onPaste(t) {\n const e = {\n text: t.detail.data.innerHTML\n };\n this._data = e, window.requestAnimationFrame(() => {\n this._element && (this._element.innerHTML = this._data.text || \"\");\n });\n }\n /**\n * Enable Conversion Toolbar. Paragraph can be converted to/from other tools\n * @returns {ConversionConfig}\n */\n static get conversionConfig() {\n return {\n export: \"text\",\n // to convert Paragraph to other block, use 'text' property of saved data\n import: \"text\"\n // to covert other block's exported string to Paragraph, fill 'text' property of tool data\n };\n }\n /**\n * Sanitizer rules\n * @returns {SanitizerConfig} - Edtior.js sanitizer config\n */\n static get sanitize() {\n return {\n text: {\n br: !0\n }\n };\n }\n /**\n * Returns true to notify the core that read-only mode is supported\n *\n * @returns {boolean}\n */\n static get isReadOnlySupported() {\n return !0;\n }\n /**\n * Used by Editor paste handling API.\n * Provides configuration to handle P tags.\n *\n * @returns {PasteConfig} - Paragraph Paste Setting\n */\n static get pasteConfig() {\n return {\n tags: [\"P\"]\n };\n }\n /**\n * Icon and title for displaying at the Toolbox\n *\n * @returns {ToolboxConfig} - Paragraph Toolbox Setting\n */\n static get toolbox() {\n return {\n icon: a,\n title: \"Text\"\n };\n }\n}\nexport {\n n as default\n};\n","import type { InlineTool, SanitizerConfig } from '../../../types';\r\nimport { IconBold } from '@codexteam/icons';\r\nimport type { MenuConfig } from '../../../types/tools';\r\n\r\n/**\r\n * Bold Tool\r\n *\r\n * Inline Toolbar Tool\r\n *\r\n * Makes selected text bolder\r\n */\r\nexport default class BoldInlineTool implements InlineTool {\r\n /**\r\n * Specifies Tool as Inline Toolbar Tool\r\n *\r\n * @returns {boolean}\r\n */\r\n public static isInline = true;\r\n\r\n /**\r\n * Title for hover-tooltip\r\n */\r\n public static title = 'Bold';\r\n\r\n /**\r\n * Sanitizer Rule\r\n * Leave <b> tags\r\n *\r\n * @returns {object}\r\n */\r\n public static get sanitize(): SanitizerConfig {\r\n return {\r\n b: {},\r\n } as SanitizerConfig;\r\n }\r\n\r\n /**\r\n * Native Document's command that uses for Bold\r\n */\r\n private readonly commandName: string = 'bold';\r\n\r\n /**\r\n * Create button for Inline Toolbar\r\n */\r\n public render(): MenuConfig {\r\n return {\r\n icon: IconBold,\r\n name: 'bold',\r\n onActivate: () => {\r\n document.execCommand(this.commandName);\r\n },\r\n isActive: () => document.queryCommandState(this.commandName),\r\n };\r\n }\r\n\r\n /**\r\n * Set a shortcut\r\n *\r\n * @returns {boolean}\r\n */\r\n public get shortcut(): string {\r\n return 'CMD+B';\r\n }\r\n}\r\n","import type { InlineTool, SanitizerConfig } from '../../../types';\r\nimport { IconItalic } from '@codexteam/icons';\r\n\r\n/**\r\n * Italic Tool\r\n *\r\n * Inline Toolbar Tool\r\n *\r\n * Style selected text with italic\r\n */\r\nexport default class ItalicInlineTool implements InlineTool {\r\n /**\r\n * Specifies Tool as Inline Toolbar Tool\r\n *\r\n * @returns {boolean}\r\n */\r\n public static isInline = true;\r\n\r\n /**\r\n * Title for hover-tooltip\r\n */\r\n public static title = 'Italic';\r\n\r\n /**\r\n * Sanitizer Rule\r\n * Leave <i> tags\r\n *\r\n * @returns {object}\r\n */\r\n public static get sanitize(): SanitizerConfig {\r\n return {\r\n i: {},\r\n } as SanitizerConfig;\r\n }\r\n\r\n /**\r\n * Native Document's command that uses for Italic\r\n */\r\n private readonly commandName: string = 'italic';\r\n\r\n /**\r\n * Styles\r\n */\r\n private readonly CSS = {\r\n button: 'ce-inline-tool',\r\n buttonActive: 'ce-inline-tool--active',\r\n buttonModifier: 'ce-inline-tool--italic',\r\n };\r\n\r\n /**\r\n * Elements\r\n */\r\n private nodes: {button: HTMLButtonElement} = {\r\n button: null,\r\n };\r\n\r\n /**\r\n * Create button for Inline Toolbar\r\n */\r\n public render(): HTMLElement {\r\n this.nodes.button = document.createElement('button') as HTMLButtonElement;\r\n this.nodes.button.type = 'button';\r\n this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);\r\n this.nodes.button.innerHTML = IconItalic;\r\n\r\n return this.nodes.button;\r\n }\r\n\r\n /**\r\n * Wrap range with <i> tag\r\n */\r\n public surround(): void {\r\n document.execCommand(this.commandName);\r\n }\r\n\r\n /**\r\n * Check selection and set activated state to button if there are <i> tag\r\n */\r\n public checkState(): boolean {\r\n const isActive = document.queryCommandState(this.commandName);\r\n\r\n this.nodes.button.classList.toggle(this.CSS.buttonActive, isActive);\r\n\r\n return isActive;\r\n }\r\n\r\n /**\r\n * Set a shortcut\r\n */\r\n public get shortcut(): string {\r\n return 'CMD+I';\r\n }\r\n}\r\n","import SelectionUtils from '../selection';\r\nimport * as _ from '../utils';\r\nimport type { InlineTool, SanitizerConfig, API } from '../../../types';\r\nimport type { Notifier, Toolbar, I18n, InlineToolbar } from '../../../types/api';\r\nimport { IconLink, IconUnlink } from '@codexteam/icons';\r\n\r\n/**\r\n * Link Tool\r\n *\r\n * Inline Toolbar Tool\r\n *\r\n * Wrap selected text with <a> tag\r\n */\r\nexport default class LinkInlineTool implements InlineTool {\r\n /**\r\n * Specifies Tool as Inline Toolbar Tool\r\n *\r\n * @returns {boolean}\r\n */\r\n public static isInline = true;\r\n\r\n /**\r\n * Title for hover-tooltip\r\n */\r\n public static title = 'Link';\r\n\r\n /**\r\n * Sanitizer Rule\r\n * Leave <a> tags\r\n *\r\n * @returns {object}\r\n */\r\n public static get sanitize(): SanitizerConfig {\r\n return {\r\n a: {\r\n href: true,\r\n target: '_blank',\r\n rel: 'nofollow',\r\n },\r\n } as SanitizerConfig;\r\n }\r\n\r\n /**\r\n * Native Document's commands for link/unlink\r\n */\r\n private readonly commandLink: string = 'createLink';\r\n private readonly commandUnlink: string = 'unlink';\r\n\r\n /**\r\n * Enter key code\r\n */\r\n private readonly ENTER_KEY: number = 13;\r\n\r\n /**\r\n * Styles\r\n */\r\n private readonly CSS = {\r\n button: 'ce-inline-tool',\r\n buttonActive: 'ce-inline-tool--active',\r\n buttonModifier: 'ce-inline-tool--link',\r\n buttonUnlink: 'ce-inline-tool--unlink',\r\n input: 'ce-inline-tool-input',\r\n inputWrap: 'ce-inline-tool-input-wrap',\r\n inputBtn:'ce-inline-tool-input-btn',\r\n inputShowed: 'ce-inline-tool-input--showed',\r\n };\r\n\r\n /**\r\n * Elements\r\n */\r\n private nodes: {\r\n button: HTMLButtonElement;\r\n input: HTMLInputElement;\r\n inputWrap: HTMLElement;\r\n } = {\r\n button: null,\r\n inputWrap:null,\r\n input: null,\r\n };\r\n\r\n /**\r\n * SelectionUtils instance\r\n */\r\n private selection: SelectionUtils;\r\n\r\n /**\r\n * Input opening state\r\n */\r\n private inputOpened = false;\r\n\r\n /**\r\n * Available Toolbar methods (open/close)\r\n */\r\n private toolbar: Toolbar;\r\n\r\n /**\r\n * Available inline toolbar methods (open/close)\r\n */\r\n private inlineToolbar: InlineToolbar;\r\n\r\n /**\r\n * Notifier API methods\r\n */\r\n private notifier: Notifier;\r\n\r\n /**\r\n * I18n API\r\n */\r\n private i18n: I18n;\r\n\r\n /**\r\n * @param api - Editor.js API\r\n */\r\n constructor({ api }: { api: API }) {\r\n this.toolbar = api.toolbar;\r\n this.inlineToolbar = api.inlineToolbar;\r\n this.notifier = api.notifier;\r\n this.i18n = api.i18n;\r\n this.selection = new SelectionUtils();\r\n }\r\n\r\n /**\r\n * Create button for Inline Toolbar\r\n */\r\n public render(): HTMLElement {\r\n this.nodes.button = document.createElement('button') as HTMLButtonElement;\r\n this.nodes.button.type = 'button';\r\n this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);\r\n\r\n this.nodes.button.innerHTML = IconLink;\r\n\r\n return this.nodes.button;\r\n }\r\n\r\n /**\r\n * Input for the link\r\n */\r\n public renderActions(): HTMLElement {\r\n this.nodes.inputWrap = document.createElement('div') as HTMLDivElement;\r\n this.nodes.inputWrap.classList.add(this.CSS.inputWrap);\r\n this.nodes.input = document.createElement('input') as HTMLInputElement;\r\n this.nodes.input.placeholder = this.i18n.t('Add a link');\r\n this.nodes.input.enterKeyHint = 'done';\r\n this.nodes.input.classList.add(this.CSS.input);\r\n this.nodes.input.addEventListener('keydown', (event: KeyboardEvent) => {\r\n if (event.keyCode === this.ENTER_KEY) {\r\n this.enterPressed(event);\r\n }\r\n });\r\n this.nodes.inputWrap.appendChild(this.nodes.input);\r\n\r\n const btn = document.createElement('button') as HTMLButtonElement;\r\n btn.type = 'button';\r\n btn.innerText = this.i18n.t('Save');\r\n btn.classList.add(this.CSS.inputBtn);\r\n btn.addEventListener('click', (event:MouseEvent) => {\r\n this.enterPressed(event);\r\n });\r\n this.nodes.inputWrap.appendChild(btn);\r\n \r\n return this.nodes.inputWrap;\r\n }\r\n\r\n /**\r\n * Handle clicks on the Inline Toolbar icon\r\n *\r\n * @param {Range} range - range to wrap with link\r\n */\r\n public surround(range: Range): void {\r\n /**\r\n * Range will be null when user makes second click on the 'link icon' to close opened input\r\n */\r\n if (range) {\r\n /**\r\n * Save selection before change focus to the input\r\n */\r\n if (!this.inputOpened) {\r\n /** Create blue background instead of selection */\r\n this.selection.setFakeBackground();\r\n this.selection.save();\r\n } else {\r\n this.selection.restore();\r\n this.selection.removeFakeBackground();\r\n }\r\n const parentAnchor = this.selection.findParentTag('A');\r\n\r\n /**\r\n * Unlink icon pressed\r\n */\r\n if (parentAnchor) {\r\n this.selection.expandToTag(parentAnchor);\r\n this.unlink();\r\n this.closeActions();\r\n this.checkState();\r\n this.toolbar.close();\r\n\r\n return;\r\n }\r\n }\r\n\r\n this.toggleActions();\r\n }\r\n\r\n /**\r\n * Check selection and set activated state to button if there are <a> tag\r\n */\r\n public checkState(): boolean {\r\n const anchorTag = this.selection.findParentTag('A');\r\n\r\n if (anchorTag) {\r\n this.nodes.button.innerHTML = IconUnlink;\r\n this.nodes.button.classList.add(this.CSS.buttonUnlink);\r\n this.nodes.button.classList.add(this.CSS.buttonActive);\r\n this.openActions();\r\n\r\n /**\r\n * Fill input value with link href\r\n */\r\n const hrefAttr = anchorTag.getAttribute('href');\r\n\r\n this.nodes.input.value = hrefAttr !== 'null' ? hrefAttr : '';\r\n\r\n this.selection.save();\r\n } else {\r\n this.nodes.button.innerHTML = IconLink;\r\n this.nodes.button.classList.remove(this.CSS.buttonUnlink);\r\n this.nodes.button.classList.remove(this.CSS.buttonActive);\r\n }\r\n\r\n return !!anchorTag;\r\n }\r\n\r\n /**\r\n * Function called with Inline Toolbar closing\r\n */\r\n public clear(): void {\r\n this.closeActions();\r\n }\r\n\r\n /**\r\n * Set a shortcut\r\n */\r\n public get shortcut(): string {\r\n return 'CMD+K';\r\n }\r\n\r\n /**\r\n * Show/close link input\r\n */\r\n private toggleActions(): void {\r\n if (!this.inputOpened) {\r\n this.openActions(true);\r\n } else {\r\n this.closeActions(false);\r\n }\r\n }\r\n\r\n /**\r\n * @param {boolean} needFocus - on link creation we need to focus input. On editing - nope.\r\n */\r\n private openActions(needFocus = false): void {\r\n this.nodes.input.classList.add(this.CSS.inputShowed);\r\n if (needFocus) {\r\n this.nodes.input.focus();\r\n }\r\n this.inputOpened = true;\r\n }\r\n\r\n /**\r\n * Close input\r\n *\r\n * @param {boolean} clearSavedSelection — we don't need to clear saved selection\r\n * on toggle-clicks on the icon of opened Toolbar\r\n */\r\n private closeActions(clearSavedSelection = true): void {\r\n if (this.selection.isFakeBackgroundEnabled) {\r\n // if actions is broken by other selection We need to save new selection\r\n const currentSelection = new SelectionUtils();\r\n\r\n currentSelection.save();\r\n\r\n this.selection.restore();\r\n this.selection.removeFakeBackground();\r\n\r\n // and recover new selection after removing fake background\r\n currentSelection.restore();\r\n }\r\n\r\n this.nodes.input.classList.remove(this.CSS.inputShowed);\r\n this.nodes.input.value = '';\r\n if (clearSavedSelection) {\r\n this.selection.clearSaved();\r\n }\r\n this.inputOpened = false;\r\n }\r\n\r\n /**\r\n * Enter pressed on input\r\n *\r\n * @param {KeyboardEvent} event - enter keydown event\r\n */\r\n private enterPressed(event: KeyboardEvent|MouseEvent): void {\r\n let value = this.nodes.input.value || '';\r\n\r\n if (!value.trim()) {\r\n this.selection.restore();\r\n this.unlink();\r\n event.preventDefault();\r\n this.closeActions();\r\n\r\n return;\r\n }\r\n\r\n if (!this.validateURL(value)) {\r\n this.notifier.show({\r\n message: this.i18n.t('Pasted link is not valid.'),\r\n style: 'error',\r\n });\r\n\r\n _.log('Incorrect Link pasted', 'warn', value);\r\n\r\n return;\r\n }\r\n\r\n value = this.prepareLink(value);\r\n\r\n this.selection.restore();\r\n this.selection.removeFakeBackground();\r\n\r\n this.insertLink(value);\r\n\r\n /**\r\n * Preventing events that will be able to happen\r\n */\r\n event.preventDefault();\r\n event.stopPropagation();\r\n event.stopImmediatePropagation();\r\n this.selection.collapseToEnd();\r\n this.inlineToolbar.close();\r\n }\r\n\r\n /**\r\n * Detects if passed string is URL\r\n *\r\n * @param {string} str - string to validate\r\n * @returns {boolean}\r\n */\r\n private validateURL(str: string): boolean {\r\n // /**\r\n // * Don't allow spaces\r\n // */\r\n // return !/\\s/.test(str);\r\n\r\n const pattern = new RegExp('^(https?:\\\\/\\\\/)?'+ // protocol\r\n '((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|'+ // domain name\r\n '((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))'+ // OR ip (v4) address\r\n '(\\\\:\\\\d+)?(\\\\/[-a-z\\\\d%_.~+]*)*'+ // port and path\r\n '(\\\\?[;&a-z\\\\d%_.~+=-]*)?'+ // query string\r\n '(\\\\#[-a-z\\\\d_]*)?$','i'); // fragment locator\r\n return !!pattern.test(str);\r\n }\r\n\r\n /**\r\n * Process link before injection\r\n * - sanitize\r\n * - add protocol for links like 'google.com'\r\n *\r\n * @param {string} link - raw user input\r\n */\r\n private prepareLink(link: string): string {\r\n link = link.trim();\r\n link = this.addProtocol(link);\r\n\r\n return link;\r\n }\r\n\r\n /**\r\n * Add 'http' protocol to the links like 'vc.ru', 'google.com'\r\n *\r\n * @param {string} link - string to process\r\n */\r\n private addProtocol(link: string): string {\r\n /**\r\n * If protocol already exists, do nothing\r\n */\r\n if (/^(\\w+):(\\/\\/)?/.test(link)) {\r\n return link;\r\n }\r\n\r\n /**\r\n * We need to add missed HTTP protocol to the link, but skip 2 cases:\r\n * 1) Internal links like \"/general\"\r\n * 2) Anchors looks like \"#results\"\r\n * 3) Protocol-relative URLs like \"//google.com\"\r\n */\r\n const isInternal = /^\\/[^/\\s]/.test(link),\r\n isAnchor = link.substring(0, 1) === '#',\r\n isProtocolRelative = /^\\/\\/[^/\\s]/.test(link);\r\n\r\n if (!isInternal && !isAnchor && !isProtocolRelative) {\r\n link = 'http://' + link;\r\n }\r\n\r\n return link;\r\n }\r\n\r\n /**\r\n * Inserts <a> tag with \"href\"\r\n *\r\n * @param {string} link - \"href\" value\r\n */\r\n private insertLink(link: string): void {\r\n /**\r\n * Edit all link, not selected part\r\n */\r\n const anchorTag = this.selection.findParentTag('A');\r\n\r\n if (anchorTag) {\r\n this.selection.expandToTag(anchorTag);\r\n }\r\n\r\n document.execCommand(this.commandLink, false, link);\r\n }\r\n\r\n /**\r\n * Removes <a> tag\r\n */\r\n private unlink(): void {\r\n document.execCommand(this.commandUnlink);\r\n }\r\n}\r\n","import { IconReplace } from '@codexteam/icons';\r\nimport type { InlineTool, API } from '../../../types';\r\nimport type { MenuConfig, MenuConfigItem } from '../../../types/tools';\r\nimport * as _ from '../utils';\r\nimport type { Blocks, Selection, Tools, Caret, I18n } from '../../../types/api';\r\nimport SelectionUtils from '../selection';\r\nimport { getConvertibleToolsForBlock } from '../utils/blocks';\r\nimport I18nInternal from '../i18n';\r\nimport { I18nInternalNS } from '../i18n/namespace-internal';\r\n\r\n/**\r\n * Inline tools for converting blocks\r\n */\r\nexport default class ConvertInlineTool implements InlineTool {\r\n /**\r\n * Specifies Tool as Inline Toolbar Tool\r\n */\r\n public static isInline = true;\r\n\r\n /**\r\n * API for working with editor blocks\r\n */\r\n private readonly blocksAPI: Blocks;\r\n\r\n /**\r\n * API for working with Selection\r\n */\r\n private readonly selectionAPI: Selection;\r\n\r\n /**\r\n * API for working with Tools\r\n */\r\n private readonly toolsAPI: Tools;\r\n\r\n /**\r\n * I18n API\r\n */\r\n private readonly i18nAPI: I18n;\r\n\r\n /**\r\n * API for working with Caret\r\n */\r\n private readonly caretAPI: Caret;\r\n\r\n /**\r\n * @param api - Editor.js API\r\n */\r\n constructor({ api }: { api: API }) {\r\n this.i18nAPI = api.i18n;\r\n this.blocksAPI = api.blocks;\r\n this.selectionAPI = api.selection;\r\n this.toolsAPI = api.tools;\r\n this.caretAPI = api.caret;\r\n }\r\n\r\n /**\r\n * Returns tool's UI config\r\n */\r\n public async render(): Promise<MenuConfig> {\r\n const currentSelection = SelectionUtils.get();\r\n const currentBlock = this.blocksAPI.getBlockByElement(currentSelection.anchorNode as HTMLElement);\r\n\r\n if (currentBlock === undefined) {\r\n return [];\r\n }\r\n\r\n const allBlockTools = this.toolsAPI.getBlockTools();\r\n const convertibleTools = await getConvertibleToolsForBlock(currentBlock, allBlockTools);\r\n\r\n if (convertibleTools.length === 0) {\r\n return [];\r\n }\r\n\r\n const convertToItems = convertibleTools.reduce<MenuConfigItem[]>((result, tool) => {\r\n tool.toolbox?.forEach((toolboxItem) => {\r\n result.push({\r\n icon: toolboxItem.icon,\r\n title: I18nInternal.t(I18nInternalNS.toolNames, toolboxItem.title),\r\n name: tool.name,\r\n hint: {\r\n title: I18nInternal.t(I18nInternalNS.toolNames, toolboxItem.title),\r\n },\r\n closeOnActivate: true,\r\n onActivate: async () => {\r\n const newBlock = await this.blocksAPI.convert(currentBlock.id, tool.name, toolboxItem.data);\r\n\r\n this.caretAPI.setToBlock(newBlock, 'end');\r\n },\r\n });\r\n });\r\n\r\n return result;\r\n }, []);\r\n\r\n const currentBlockToolboxItem = await currentBlock.getActiveToolboxEntry();\r\n const icon = currentBlockToolboxItem !== undefined ? currentBlockToolboxItem.icon : IconReplace;\r\n const isDesktop = !_.isMobileScreen();\r\n\r\n return {\r\n icon,\r\n name: 'convert-to',\r\n hint: {\r\n title: this.i18nAPI.t('Convert to'),\r\n },\r\n children: {\r\n searchable: isDesktop,\r\n items: convertToItems,\r\n onOpen: () => {\r\n if (isDesktop) {\r\n this.selectionAPI.setFakeBackground();\r\n this.selectionAPI.save();\r\n }\r\n },\r\n onClose: () => {\r\n if (isDesktop) {\r\n this.selectionAPI.restore();\r\n this.selectionAPI.removeFakeBackground();\r\n }\r\n },\r\n },\r\n };\r\n }\r\n}\r\n","import $ from '../../components/dom';\r\nimport type { API, BlockTool, BlockToolConstructorOptions, BlockToolData } from '../../../types';\r\nimport { IconWarning } from '@codexteam/icons';\r\n\r\nexport interface StubData extends BlockToolData {\r\n title: string;\r\n savedData: BlockToolData;\r\n}\r\n\r\n/**\r\n * This tool will be shown in place of a block without corresponding plugin\r\n * It will store its data inside and pass it back with article saving\r\n */\r\nexport default class Stub implements BlockTool {\r\n /**\r\n * Notify core that tool supports read-only mode\r\n */\r\n public static isReadOnlySupported = true;\r\n\r\n /**\r\n * Stub styles\r\n *\r\n * @type {{wrapper: string, info: string, title: string, subtitle: string}}\r\n */\r\n private CSS = {\r\n wrapper: 'ce-stub',\r\n info: 'ce-stub__info',\r\n title: 'ce-stub__title',\r\n subtitle: 'ce-stub__subtitle',\r\n };\r\n\r\n /**\r\n * Main stub wrapper\r\n */\r\n private readonly wrapper: HTMLElement;\r\n\r\n /**\r\n * Editor.js API\r\n */\r\n private readonly api: API;\r\n\r\n /**\r\n * Stub title — tool name\r\n */\r\n private readonly title: string;\r\n\r\n /**\r\n * Stub hint\r\n */\r\n private readonly subtitle: string;\r\n\r\n /**\r\n * Original Tool data\r\n */\r\n private readonly savedData: BlockToolData;\r\n\r\n /**\r\n * @param options - constructor options\r\n * @param options.data - stub tool data\r\n * @param options.api - Editor.js API\r\n */\r\n constructor({ data, api }: BlockToolConstructorOptions<StubData>) {\r\n this.api = api;\r\n this.title = data.title || this.api.i18n.t('Error');\r\n this.subtitle = this.api.i18n.t('The block can not be displayed correctly.');\r\n this.savedData = data.savedData;\r\n\r\n this.wrapper = this.make();\r\n }\r\n\r\n /**\r\n * Returns stub holder\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n public render(): HTMLElement {\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Return original Tool data\r\n *\r\n * @returns {BlockToolData}\r\n */\r\n public save(): BlockToolData {\r\n return this.savedData;\r\n }\r\n\r\n /**\r\n * Create Tool html markup\r\n *\r\n * @returns {HTMLElement}\r\n */\r\n private make(): HTMLElement {\r\n const wrapper = $.make('div', this.CSS.wrapper);\r\n const icon = IconWarning;\r\n const infoContainer = $.make('div', this.CSS.info);\r\n const title = $.make('div', this.CSS.title, {\r\n textContent: this.title,\r\n });\r\n const subtitle = $.make('div', this.CSS.subtitle, {\r\n textContent: this.subtitle,\r\n });\r\n\r\n wrapper.innerHTML = icon;\r\n\r\n infoContainer.appendChild(title);\r\n infoContainer.appendChild(subtitle);\r\n\r\n wrapper.appendChild(infoContainer);\r\n\r\n return wrapper;\r\n }\r\n}\r\n","import BaseToolAdapter, { InternalInlineToolSettings } from './base';\r\nimport type { InlineTool as IInlineTool, InlineToolConstructable } from '../../../types';\r\nimport type { InlineToolAdapter as InlineToolAdapterInterface } from '../../../types/tools/adapters/inline-tool-adapter';\r\nimport { ToolType } from '../../../types/tools/adapters/tool-type';\r\n\r\n/**\r\n * InlineTool object to work with Inline Tools constructables\r\n */\r\nexport default class InlineToolAdapter extends BaseToolAdapter<ToolType.Inline, IInlineTool> implements InlineToolAdapterInterface {\r\n /**\r\n * Tool type — Inline\r\n */\r\n public type: ToolType.Inline = ToolType.Inline;\r\n\r\n /**\r\n * Tool's constructable blueprint\r\n */\r\n protected constructable: InlineToolConstructable;\r\n\r\n /**\r\n * Returns title for Inline Tool if specified by user\r\n */\r\n public get title(): string {\r\n return this.constructable[InternalInlineToolSettings.Title];\r\n }\r\n\r\n /**\r\n * Constructs new InlineTool instance from constructable\r\n */\r\n public create(): IInlineTool {\r\n // eslint-disable-next-line new-cap\r\n return new this.constructable({\r\n api: this.api,\r\n config: this.settings,\r\n }) as IInlineTool;\r\n }\r\n\r\n /**\r\n * Allows inline tool to be available in read-only mode\r\n * Can be used, for example, by comments tool\r\n */\r\n public get isReadOnlySupported(): boolean {\r\n return this.constructable[InternalInlineToolSettings.IsReadOnlySupported] ?? false;\r\n }\r\n}\r\n","import BaseToolAdapter from './base';\r\nimport type { BlockAPI, BlockTune as IBlockTune, BlockTuneConstructable } from '../../../types';\r\nimport type { BlockTuneData } from '../../../types/block-tunes/block-tune-data';\r\nimport type { BlockTuneAdapter as BlockTuneAdapterInterface } from '../../../types/tools/adapters/block-tune-adapter';\r\nimport { ToolType } from '../../../types/tools/adapters/tool-type';\r\n\r\n/**\r\n * Stub class for BlockTunes\r\n *\r\n * @todo Implement\r\n */\r\nexport default class BlockTuneAdapter extends BaseToolAdapter<ToolType.Tune, IBlockTune> implements BlockTuneAdapterInterface {\r\n /**\r\n * Tool type — Tune\r\n */\r\n public type: ToolType.Tune = ToolType.Tune;\r\n\r\n /**\r\n * Tool's constructable blueprint\r\n */\r\n protected readonly constructable: BlockTuneConstructable;\r\n\r\n /**\r\n * Constructs new BlockTune instance from constructable\r\n *\r\n * @param data - Tune data\r\n * @param block - Block API object\r\n */\r\n public create(data: BlockTuneData, block: BlockAPI): IBlockTune {\r\n // eslint-disable-next-line new-cap\r\n return new this.constructable({\r\n api: this.api,\r\n config: this.settings,\r\n block,\r\n data,\r\n });\r\n }\r\n}\r\n","import type BlockToolAdapter from './block';\r\nimport type InlineToolAdapter from './inline';\r\nimport type BlockTuneAdapter from './tune';\r\nimport type { ToolsCollection as ToolsCollectionInterface } from '../../../types/tools/adapters/tools-collection';\r\n\r\n\r\nexport type ToolClass = BlockToolAdapter | InlineToolAdapter | BlockTuneAdapter;\r\n\r\n/**\r\n * Class to store Editor Tools\r\n */\r\nexport default class ToolsCollection<V extends ToolClass = ToolClass> extends Map<string, V> implements ToolsCollectionInterface<V> {\r\n /**\r\n * Returns Block Tools collection\r\n */\r\n public get blockTools(): ToolsCollection<BlockToolAdapter> {\r\n const tools = Array\r\n .from(this.entries())\r\n .filter(([, tool]) => tool.isBlock()) as [string, BlockToolAdapter][];\r\n\r\n return new ToolsCollection<BlockToolAdapter>(tools);\r\n }\r\n\r\n /**\r\n * Returns Inline Tools collection\r\n */\r\n public get inlineTools(): ToolsCollection<InlineToolAdapter> {\r\n const tools = Array\r\n .from(this.entries())\r\n .filter(([, tool]) => tool.isInline()) as [string, InlineToolAdapter][];\r\n\r\n return new ToolsCollection<InlineToolAdapter>(tools);\r\n }\r\n\r\n /**\r\n * Returns Block Tunes collection\r\n */\r\n public get blockTunes(): ToolsCollection<BlockTuneAdapter> {\r\n const tools = Array\r\n .from(this.entries())\r\n .filter(([, tool]) => tool.isTune()) as [string, BlockTuneAdapter][];\r\n\r\n return new ToolsCollection<BlockTuneAdapter>(tools);\r\n }\r\n\r\n /**\r\n * Returns internal Tools collection\r\n */\r\n public get internalTools(): ToolsCollection<V> {\r\n const tools = Array\r\n .from(this.entries())\r\n .filter(([, tool]) => tool.isInternal);\r\n\r\n return new ToolsCollection<V>(tools);\r\n }\r\n\r\n /**\r\n * Returns Tools collection provided by user\r\n */\r\n public get externalTools(): ToolsCollection<V> {\r\n const tools = Array\r\n .from(this.entries())\r\n .filter(([, tool]) => !tool.isInternal);\r\n\r\n return new ToolsCollection<V>(tools);\r\n }\r\n}\r\n","import BaseToolAdapter, { InternalBlockToolSettings, UserSettings } from './base';\r\nimport type {\r\n BlockAPI,\r\n BlockTool as IBlockTool,\r\n BlockToolConstructable,\r\n BlockToolData,\r\n ConversionConfig,\r\n PasteConfig, SanitizerConfig, ToolboxConfig,\r\n ToolboxConfigEntry\r\n} from '../../../types';\r\nimport * as _ from '../utils';\r\nimport type InlineToolAdapter from './inline';\r\nimport type BlockTuneAdapter from './tune';\r\nimport ToolsCollection from './collection';\r\nimport type { BlockToolAdapter as BlockToolAdapterInterface } from '../../../types/tools/adapters/block-tool-adapter';\r\n\r\nimport { ToolType } from '../../../types/tools/adapters/tool-type';\r\n\r\n/**\r\n * Class to work with Block tools constructables\r\n */\r\nexport default class BlockToolAdapter extends BaseToolAdapter<ToolType.Block, IBlockTool> implements BlockToolAdapterInterface {\r\n /**\r\n * Tool type — Block\r\n */\r\n public type: ToolType.Block = ToolType.Block;\r\n\r\n /**\r\n * InlineTool collection for current Block Tool\r\n */\r\n public inlineTools: ToolsCollection<InlineToolAdapter> = new ToolsCollection<InlineToolAdapter>();\r\n\r\n /**\r\n * BlockTune collection for current Block Tool\r\n */\r\n public tunes: ToolsCollection<BlockTuneAdapter> = new ToolsCollection<BlockTuneAdapter>();\r\n\r\n /**\r\n * Tool's constructable blueprint\r\n */\r\n protected constructable: BlockToolConstructable;\r\n\r\n /**\r\n * Creates new Tool instance\r\n *\r\n * @param data - Tool data\r\n * @param block - BlockAPI for current Block\r\n * @param readOnly - True if Editor is in read-only mode\r\n */\r\n public create(data: BlockToolData, block: BlockAPI, readOnly: boolean): IBlockTool {\r\n // eslint-disable-next-line new-cap\r\n return new this.constructable({\r\n data,\r\n block,\r\n readOnly,\r\n api: this.api,\r\n config: this.settings,\r\n }) as IBlockTool;\r\n }\r\n\r\n /**\r\n * Returns true if read-only mode is supported by Tool\r\n */\r\n public get isReadOnlySupported(): boolean {\r\n return this.constructable[InternalBlockToolSettings.IsReadOnlySupported] === true;\r\n }\r\n\r\n /**\r\n * Returns true if Tool supports linebreaks\r\n */\r\n public get isLineBreaksEnabled(): boolean {\r\n return this.constructable[InternalBlockToolSettings.IsEnabledLineBreaks];\r\n }\r\n\r\n /**\r\n * Returns Tool toolbox configuration (internal or user-specified).\r\n *\r\n * Merges internal and user-defined toolbox configs based on the following rules:\r\n *\r\n * - If both internal and user-defined toolbox configs are arrays their items are merged.\r\n * Length of the second one is kept.\r\n *\r\n * - If both are objects their properties are merged.\r\n *\r\n * - If one is an object and another is an array than internal config is replaced with user-defined\r\n * config. This is made to allow user to override default tool's toolbox representation (single/multiple entries)\r\n */\r\n public get toolbox(): ToolboxConfigEntry[] | undefined {\r\n const toolToolboxSettings = this.constructable[InternalBlockToolSettings.Toolbox] as ToolboxConfig;\r\n const userToolboxSettings = this.config[UserSettings.Toolbox];\r\n\r\n if (_.isEmpty(toolToolboxSettings)) {\r\n return;\r\n }\r\n if (userToolboxSettings === false) {\r\n return;\r\n }\r\n /**\r\n * Return tool's toolbox settings if user settings are not defined\r\n */\r\n if (!userToolboxSettings) {\r\n return Array.isArray(toolToolboxSettings) ? toolToolboxSettings : [ toolToolboxSettings ];\r\n }\r\n\r\n /**\r\n * Otherwise merge user settings with tool's settings\r\n */\r\n if (Array.isArray(toolToolboxSettings)) {\r\n if (Array.isArray(userToolboxSettings)) {\r\n return userToolboxSettings.map((item, i) => {\r\n const toolToolboxEntry = toolToolboxSettings[i];\r\n\r\n if (toolToolboxEntry) {\r\n return {\r\n ...toolToolboxEntry,\r\n ...item,\r\n };\r\n }\r\n\r\n return item;\r\n });\r\n }\r\n\r\n return [ userToolboxSettings ];\r\n } else {\r\n if (Array.isArray(userToolboxSettings)) {\r\n return userToolboxSettings;\r\n }\r\n\r\n return [\r\n {\r\n ...toolToolboxSettings,\r\n ...userToolboxSettings,\r\n },\r\n ];\r\n }\r\n }\r\n\r\n /**\r\n * Returns Tool conversion configuration\r\n */\r\n public get conversionConfig(): ConversionConfig | undefined {\r\n return this.constructable[InternalBlockToolSettings.ConversionConfig];\r\n }\r\n\r\n /**\r\n * Returns enabled inline tools for Tool\r\n */\r\n public get enabledInlineTools(): boolean | string[] {\r\n return this.config[UserSettings.EnabledInlineTools] || false;\r\n }\r\n\r\n /**\r\n * Returns enabled tunes for Tool\r\n */\r\n public get enabledBlockTunes(): boolean | string[] {\r\n return this.config[UserSettings.EnabledBlockTunes];\r\n }\r\n\r\n /**\r\n * Returns Tool paste configuration\r\n */\r\n public get pasteConfig(): PasteConfig {\r\n return this.constructable[InternalBlockToolSettings.PasteConfig] ?? {};\r\n }\r\n\r\n /**\r\n * Returns sanitize configuration for Block Tool including configs from related Inline Tools and Block Tunes\r\n */\r\n @_.cacheable\r\n public get sanitizeConfig(): SanitizerConfig {\r\n const toolRules = super.sanitizeConfig;\r\n const baseConfig = this.baseSanitizeConfig;\r\n\r\n if (_.isEmpty(toolRules)) {\r\n return baseConfig;\r\n }\r\n\r\n const toolConfig = {} as SanitizerConfig;\r\n\r\n for (const fieldName in toolRules) {\r\n if (Object.prototype.hasOwnProperty.call(toolRules, fieldName)) {\r\n const rule = toolRules[fieldName];\r\n\r\n /**\r\n * If rule is object, merge it with Inline Tools configuration\r\n *\r\n * Otherwise pass as it is\r\n */\r\n if (_.isObject(rule)) {\r\n toolConfig[fieldName] = Object.assign({}, baseConfig, rule);\r\n } else {\r\n toolConfig[fieldName] = rule;\r\n }\r\n }\r\n }\r\n\r\n return toolConfig;\r\n }\r\n\r\n /**\r\n * Returns sanitizer configuration composed from sanitize config of Inline Tools enabled for Tool\r\n */\r\n @_.cacheable\r\n public get baseSanitizeConfig(): SanitizerConfig {\r\n const baseConfig = {};\r\n\r\n Array\r\n .from(this.inlineTools.values())\r\n .forEach(tool => Object.assign(baseConfig, tool.sanitizeConfig));\r\n\r\n Array\r\n .from(this.tunes.values())\r\n .forEach(tune => Object.assign(baseConfig, tune.sanitizeConfig));\r\n\r\n return baseConfig;\r\n }\r\n}\r\n","import type { ToolConstructable, ToolSettings } from '../../../types/tools';\r\nimport { InternalInlineToolSettings, InternalTuneSettings } from './base';\r\nimport InlineToolAdapter from './inline';\r\nimport BlockTuneAdapter from './tune';\r\nimport BlockToolAdapter from './block';\r\nimport type ApiModule from '../modules/api';\r\nimport type { EditorConfig } from '../../../types/configs';\r\n\r\ntype ToolConstructor = typeof InlineToolAdapter | typeof BlockToolAdapter | typeof BlockTuneAdapter;\r\n\r\n/**\r\n * Factory to construct classes to work with tools\r\n */\r\nexport default class ToolsFactory {\r\n /**\r\n * Tools configuration specified by user\r\n */\r\n private config: {[name: string]: ToolSettings & { isInternal?: boolean }};\r\n\r\n /**\r\n * EditorJS API Module\r\n */\r\n private api: ApiModule;\r\n\r\n /**\r\n * EditorJS configuration\r\n */\r\n private editorConfig: EditorConfig;\r\n\r\n /**\r\n * @class\r\n * @param config - tools config\r\n * @param editorConfig - EditorJS config\r\n * @param api - EditorJS API module\r\n */\r\n constructor(\r\n config: {[name: string]: ToolSettings & { isInternal?: boolean }},\r\n editorConfig: EditorConfig,\r\n api: ApiModule\r\n ) {\r\n this.api = api;\r\n this.config = config;\r\n this.editorConfig = editorConfig;\r\n }\r\n\r\n /**\r\n * Returns Tool object based on it's type\r\n *\r\n * @param name - tool name\r\n */\r\n public get(name: string): InlineToolAdapter | BlockToolAdapter | BlockTuneAdapter {\r\n const { class: constructable, isInternal = false, ...config } = this.config[name];\r\n\r\n const Constructor = this.getConstructor(constructable);\r\n const isTune = constructable[InternalTuneSettings.IsTune];\r\n\r\n return new Constructor({\r\n name,\r\n constructable,\r\n config,\r\n api: this.api.getMethodsForTool(name, isTune),\r\n isDefault: name === this.editorConfig.defaultBlock,\r\n defaultPlaceholder: this.editorConfig.placeholder,\r\n isInternal,\r\n });\r\n }\r\n\r\n /**\r\n * Find appropriate Tool object constructor for Tool constructable\r\n *\r\n * @param constructable - Tools constructable\r\n */\r\n private getConstructor(constructable: ToolConstructable): ToolConstructor {\r\n switch (true) {\r\n case constructable[InternalInlineToolSettings.IsInline]:\r\n return InlineToolAdapter;\r\n case constructable[InternalTuneSettings.IsTune]:\r\n return BlockTuneAdapter;\r\n default:\r\n return BlockToolAdapter;\r\n }\r\n }\r\n}\r\n","/**\r\n * @class MoveDownTune\r\n * @classdesc Editor's default tune - Moves down highlighted block\r\n * @copyright <CodeX Team> 2018\r\n */\r\n\r\nimport type { API, BlockTune } from '../../../types';\r\nimport { IconChevronDown } from '@codexteam/icons';\r\nimport type { TunesMenuConfig } from '../../../types/tools';\r\n\r\n\r\n/**\r\n *\r\n */\r\nexport default class MoveDownTune implements BlockTune {\r\n /**\r\n * Set Tool is Tune\r\n */\r\n public static readonly isTune = true;\r\n\r\n /**\r\n * Property that contains Editor.js API methods\r\n *\r\n * @see {@link docs/api.md}\r\n */\r\n private readonly api: API;\r\n\r\n /**\r\n * Styles\r\n */\r\n private CSS = {\r\n animation: 'wobble',\r\n };\r\n\r\n /**\r\n * MoveDownTune constructor\r\n *\r\n * @param {API} api — Editor's API\r\n */\r\n constructor({ api }) {\r\n this.api = api;\r\n }\r\n\r\n /**\r\n * Tune's appearance in block settings menu\r\n */\r\n public render(): TunesMenuConfig {\r\n return {\r\n icon: IconChevronDown,\r\n title: this.api.i18n.t('Move down'),\r\n onActivate: (): void => this.handleClick(),\r\n name: 'move-down',\r\n //lrj:添加提示\r\n hint: {\r\n title: this.api.i18n.t('Move down'),\r\n \r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Handle clicks on 'move down' button\r\n */\r\n public handleClick(): void { \r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n const nextBlock = this.api.blocks.getBlockByIndex(currentBlockIndex + 1);\r\n\r\n // If Block is last do nothing\r\n if (!nextBlock) {\r\n throw new Error('Unable to move Block down since it is already the last');\r\n }\r\n\r\n const nextBlockElement = nextBlock.holder;\r\n const nextBlockCoords = nextBlockElement.getBoundingClientRect();\r\n\r\n let scrollOffset = Math.abs(window.innerHeight - nextBlockElement.offsetHeight);\r\n\r\n /**\r\n * Next block ends on screen.\r\n * Increment scroll by next block's height to save element onscreen-position\r\n */\r\n if (nextBlockCoords.top < window.innerHeight) {\r\n scrollOffset = window.scrollY + nextBlockElement.offsetHeight;\r\n }\r\n\r\n window.scrollTo(0, scrollOffset);\r\n\r\n /** Change blocks positions */\r\n this.api.blocks.move(currentBlockIndex + 1);\r\n\r\n this.api.toolbar.toggleBlockSettings(true);\r\n }\r\n}\r\n","/**\r\n * @class DeleteTune\r\n * @classdesc Editor's default tune that moves up selected block\r\n * @copyright <CodeX Team> 2018\r\n */\r\nimport type { API, BlockTune } from '../../../types';\r\nimport { IconCross } from '@codexteam/icons';\r\nimport type { MenuConfig } from '../../../types/tools/menu-config';\r\n\r\n/**\r\n *\r\n */\r\nexport default class DeleteTune implements BlockTune {\r\n /**\r\n * Set Tool is Tune\r\n */\r\n public static readonly isTune = true;\r\n\r\n /**\r\n * Property that contains Editor.js API methods\r\n *\r\n * @see {@link docs/api.md}\r\n */\r\n private readonly api: API;\r\n\r\n /**\r\n * DeleteTune constructor\r\n *\r\n * @param {API} api - Editor's API\r\n */\r\n constructor({ api }) {\r\n this.api = api;\r\n }\r\n\r\n /**\r\n * Tune's appearance in block settings menu\r\n */\r\n public render(): MenuConfig {\r\n return {\r\n icon: IconCross,\r\n title: this.api.i18n.t('Delete'),\r\n name: 'delete', \r\n confirmation: {\r\n //title: this.api.i18n.t('Click to delete'),\r\n onActivate: (): void => this.handleClick(),\r\n \r\n },\r\n //lrj:添加提示\r\n hint: {\r\n title: this.api.i18n.t('Click to delete')\r\n }\r\n \r\n };\r\n }\r\n\r\n /**\r\n * Delete block conditions passed\r\n */\r\n public handleClick(): void {\r\n this.api.blocks.delete();\r\n }\r\n}\r\n","/**\r\n * @class MoveUpTune\r\n * @classdesc Editor's default tune that moves up selected block\r\n * @copyright <CodeX Team> 2018\r\n */\r\nimport type { API, BlockTune } from '../../../types';\r\nimport { IconChevronUp } from '@codexteam/icons';\r\nimport type { TunesMenuConfig } from '../../../types/tools';\r\n\r\n/**\r\n *\r\n */\r\nexport default class MoveUpTune implements BlockTune {\r\n /**\r\n * Set Tool is Tune\r\n */\r\n public static readonly isTune = true;\r\n\r\n /**\r\n * Property that contains Editor.js API methods\r\n *\r\n * @see {@link docs/api.md}\r\n */\r\n private readonly api: API;\r\n\r\n /**\r\n * Styles\r\n */\r\n private CSS = {\r\n animation: 'wobble',\r\n };\r\n\r\n /**\r\n * MoveUpTune constructor\r\n *\r\n * @param {API} api - Editor's API\r\n */\r\n constructor({ api }) {\r\n this.api = api;\r\n }\r\n\r\n /**\r\n * Tune's appearance in block settings menu\r\n */\r\n public render(): TunesMenuConfig {\r\n return {\r\n icon: IconChevronUp,\r\n title: this.api.i18n.t('Move up'),\r\n onActivate: (): void => this.handleClick(),\r\n name: 'move-up',\r\n //lrj:添加提示\r\n hint: {\r\n title: this.api.i18n.t('Move up'), \r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Move current block up\r\n */\r\n public handleClick(): void {\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);\r\n const previousBlock = this.api.blocks.getBlockByIndex(currentBlockIndex - 1);\r\n\r\n if (currentBlockIndex === 0 || !currentBlock || !previousBlock) {\r\n throw new Error('Unable to move Block up since it is already the first');\r\n }\r\n\r\n const currentBlockElement = currentBlock.holder;\r\n const previousBlockElement = previousBlock.holder;\r\n\r\n /**\r\n * Here is two cases:\r\n * - when previous block has negative offset and part of it is visible on window, then we scroll\r\n * by window's height and add offset which is mathematically difference between two blocks\r\n *\r\n * - when previous block is visible and has offset from the window,\r\n * than we scroll window to the difference between this offsets.\r\n */\r\n const currentBlockCoords = currentBlockElement.getBoundingClientRect(),\r\n previousBlockCoords = previousBlockElement.getBoundingClientRect();\r\n\r\n let scrollUpOffset;\r\n\r\n if (previousBlockCoords.top > 0) {\r\n scrollUpOffset = Math.abs(currentBlockCoords.top) - Math.abs(previousBlockCoords.top);\r\n } else {\r\n scrollUpOffset = Math.abs(currentBlockCoords.top) + previousBlockCoords.height;\r\n }\r\n\r\n window.scrollBy(0, -1 * scrollUpOffset);\r\n\r\n /** Change blocks positions */\r\n this.api.blocks.move(currentBlockIndex - 1);\r\n\r\n this.api.toolbar.toggleBlockSettings(true);\r\n }\r\n}\r\n","import Paragraph from '@editorjs/paragraph';\r\nimport Module from '../__module';\r\nimport * as _ from '../utils';\r\nimport type { SanitizerConfig, ToolConfig, ToolConstructable, ToolSettings } from '../../../types';\r\nimport BoldInlineTool from '../inline-tools/inline-tool-bold';\r\nimport ItalicInlineTool from '../inline-tools/inline-tool-italic';\r\nimport LinkInlineTool from '../inline-tools/inline-tool-link';\r\nimport ConvertInlineTool from '../inline-tools/inline-tool-convert';\r\nimport Stub from '../../tools/stub';\r\nimport ToolsFactory from '../tools/factory';\r\nimport type InlineToolAdapter from '../tools/inline';\r\nimport type BlockToolAdapter from '../tools/block';\r\nimport type BlockTuneAdapter from '../tools/tune';\r\nimport MoveDownTune from '../block-tunes/block-tune-move-down';\r\nimport DeleteTune from '../block-tunes/block-tune-delete';\r\nimport MoveUpTune from '../block-tunes/block-tune-move-up';\r\nimport ToolsCollection from '../tools/collection';\r\n\r\n/**\r\n * @module Editor.js Tools Submodule\r\n *\r\n * Creates Instances from Plugins and binds external config to the instances\r\n */\r\n\r\n/**\r\n * Modules that works with tools classes\r\n */\r\nexport default class Tools extends Module {\r\n /**\r\n * Name of Stub Tool\r\n * Stub Tool is used to substitute unavailable block Tools and store their data\r\n *\r\n * @type {string}\r\n */\r\n public stubTool = 'stub';\r\n\r\n /**\r\n * Returns available Tools\r\n */\r\n public get available(): ToolsCollection {\r\n return this.toolsAvailable;\r\n }\r\n\r\n /**\r\n * Returns unavailable Tools\r\n */\r\n public get unavailable(): ToolsCollection {\r\n return this.toolsUnavailable;\r\n }\r\n\r\n /**\r\n * Return Tools for the Inline Toolbar\r\n */\r\n public get inlineTools(): ToolsCollection<InlineToolAdapter> {\r\n return this.available.inlineTools;\r\n }\r\n\r\n /**\r\n * Return editor block tools\r\n */\r\n public get blockTools(): ToolsCollection<BlockToolAdapter> {\r\n return this.available.blockTools;\r\n }\r\n\r\n /**\r\n * Return available Block Tunes\r\n *\r\n * @returns {object} - object of Inline Tool's classes\r\n */\r\n public get blockTunes(): ToolsCollection<BlockTuneAdapter> {\r\n return this.available.blockTunes;\r\n }\r\n\r\n /**\r\n * Returns default Tool object\r\n */\r\n public get defaultTool(): BlockToolAdapter {\r\n return this.blockTools.get(this.config.defaultBlock);\r\n }\r\n\r\n /**\r\n * Tools objects factory\r\n */\r\n private factory: ToolsFactory;\r\n\r\n /**\r\n * Tools` classes available to use\r\n */\r\n private readonly toolsAvailable: ToolsCollection = new ToolsCollection();\r\n\r\n /**\r\n * Tools` classes not available to use because of preparation failure\r\n */\r\n private readonly toolsUnavailable: ToolsCollection = new ToolsCollection();\r\n\r\n /**\r\n * Returns internal tools\r\n */\r\n public get internal(): ToolsCollection {\r\n return this.available.internalTools;\r\n }\r\n\r\n /**\r\n * Creates instances via passed or default configuration\r\n *\r\n * @returns {Promise<void>}\r\n */\r\n public async prepare(): Promise<void> {\r\n this.validateTools();\r\n\r\n /**\r\n * Assign internal tools\r\n */\r\n this.config.tools = _.deepMerge({}, this.internalTools, this.config.tools);\r\n\r\n if (!Object.prototype.hasOwnProperty.call(this.config, 'tools') || Object.keys(this.config.tools).length === 0) {\r\n throw Error('Can\\'t start without tools');\r\n }\r\n\r\n const config = this.prepareConfig();\r\n\r\n this.factory = new ToolsFactory(config, this.config, this.Editor.API);\r\n\r\n /**\r\n * getting classes that has prepare method\r\n */\r\n const sequenceData = this.getListOfPrepareFunctions(config);\r\n\r\n /**\r\n * if sequence data contains nothing then resolve current chain and run other module prepare\r\n */\r\n if (sequenceData.length === 0) {\r\n return Promise.resolve();\r\n }\r\n\r\n /**\r\n * to see how it works {@link '../utils.ts#sequence'}\r\n */\r\n await _.sequence(sequenceData, (data: { toolName: string }) => {\r\n this.toolPrepareMethodSuccess(data);\r\n }, (data: { toolName: string }) => {\r\n this.toolPrepareMethodFallback(data);\r\n });\r\n\r\n this.prepareBlockTools();\r\n }\r\n\r\n /**\r\n * Return general Sanitizer config for all inline tools\r\n */\r\n @_.cacheable\r\n public getAllInlineToolsSanitizeConfig(): SanitizerConfig {\r\n const config: SanitizerConfig = {} as SanitizerConfig;\r\n\r\n Array.from(this.inlineTools.values())\r\n .forEach(inlineTool => {\r\n Object.assign(config, inlineTool.sanitizeConfig);\r\n });\r\n\r\n return config;\r\n }\r\n\r\n /**\r\n * Calls each Tool reset method to clean up anything set by Tool\r\n */\r\n public destroy(): void {\r\n Object.values(this.available).forEach(async tool => {\r\n if (_.isFunction(tool.reset)) {\r\n await tool.reset();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Returns internal tools\r\n * Includes Bold, Italic, Link and Paragraph\r\n */\r\n private get internalTools(): { [toolName: string]: ToolConstructable | ToolSettings & { isInternal?: boolean } } {\r\n return {\r\n convertTo: {\r\n class: ConvertInlineTool,\r\n isInternal: true,\r\n },\r\n link: {\r\n class: LinkInlineTool,\r\n isInternal: true,\r\n },\r\n bold: {\r\n class: BoldInlineTool,\r\n isInternal: true,\r\n },\r\n italic: {\r\n class: ItalicInlineTool,\r\n isInternal: true,\r\n },\r\n paragraph: {\r\n class: Paragraph,\r\n inlineToolbar: true,\r\n isInternal: true,\r\n },\r\n stub: {\r\n class: Stub,\r\n isInternal: true,\r\n },\r\n moveUp: {\r\n class: MoveUpTune,\r\n isInternal: true,\r\n },\r\n delete: {\r\n class: DeleteTune,\r\n isInternal: true,\r\n },\r\n moveDown: {\r\n class: MoveDownTune,\r\n isInternal: true,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Tool prepare method success callback\r\n *\r\n * @param {object} data - append tool to available list\r\n */\r\n private toolPrepareMethodSuccess(data: { toolName: string }): void {\r\n const tool = this.factory.get(data.toolName);\r\n\r\n if (tool.isInline()) {\r\n /**\r\n * Some Tools validation\r\n */\r\n const inlineToolRequiredMethods = [ 'render' ];\r\n const notImplementedMethods = inlineToolRequiredMethods.filter((method) => !tool.create()[method]);\r\n\r\n if (notImplementedMethods.length) {\r\n _.log(\r\n `Incorrect Inline Tool: ${tool.name}. Some of required methods is not implemented %o`,\r\n 'warn',\r\n notImplementedMethods\r\n );\r\n\r\n this.toolsUnavailable.set(tool.name, tool);\r\n\r\n return;\r\n }\r\n }\r\n\r\n this.toolsAvailable.set(tool.name, tool);\r\n }\r\n\r\n /**\r\n * Tool prepare method fail callback\r\n *\r\n * @param {object} data - append tool to unavailable list\r\n */\r\n private toolPrepareMethodFallback(data: { toolName: string }): void {\r\n this.toolsUnavailable.set(data.toolName, this.factory.get(data.toolName));\r\n }\r\n\r\n /**\r\n * Binds prepare function of plugins with user or default config\r\n *\r\n * @returns {Array} list of functions that needs to be fired sequentially\r\n * @param config - tools config\r\n */\r\n private getListOfPrepareFunctions(config: {[name: string]: ToolSettings}): {\r\n function: (data: { toolName: string; config: ToolConfig }) => void | Promise<void>;\r\n data: { toolName: string; config: ToolConfig };\r\n }[] {\r\n const toolPreparationList: {\r\n function: (data: { toolName: string }) => void | Promise<void>;\r\n data: { toolName: string; config: ToolConfig };\r\n }[] = [];\r\n\r\n Object\r\n .entries(config)\r\n .forEach(([toolName, settings]) => {\r\n toolPreparationList.push({\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n function: _.isFunction(settings.class.prepare) ? settings.class.prepare : (): void => {},\r\n data: {\r\n toolName,\r\n config: settings.config,\r\n },\r\n });\r\n });\r\n\r\n return toolPreparationList;\r\n }\r\n\r\n /**\r\n * Assign enabled Inline Tools and Block Tunes for Block Tool\r\n */\r\n private prepareBlockTools(): void {\r\n Array.from(this.blockTools.values()).forEach(tool => {\r\n this.assignInlineToolsToBlockTool(tool);\r\n this.assignBlockTunesToBlockTool(tool);\r\n });\r\n }\r\n\r\n /**\r\n * Assign enabled Inline Tools for Block Tool\r\n *\r\n * @param tool - Block Tool\r\n */\r\n private assignInlineToolsToBlockTool(tool: BlockToolAdapter): void {\r\n /**\r\n * If common inlineToolbar property is false no Inline Tools should be assigned\r\n */\r\n if (this.config.inlineToolbar === false) {\r\n return;\r\n }\r\n\r\n /**\r\n * If user pass just 'true' for tool, get common inlineToolbar settings\r\n * - if common settings is an array, use it\r\n * - if common settings is 'true' or not specified, get default order\r\n */\r\n if (tool.enabledInlineTools === true) {\r\n tool.inlineTools = new ToolsCollection<InlineToolAdapter>(\r\n Array.isArray(this.config.inlineToolbar)\r\n ? this.config.inlineToolbar.map(name => [name, this.inlineTools.get(name)])\r\n /**\r\n * If common settings is 'true' or not specified (will be set as true at core.ts), get the default order\r\n */\r\n : Array.from(this.inlineTools.entries())\r\n );\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * If user pass the list of inline tools for the particular tool, return it.\r\n */\r\n if (Array.isArray(tool.enabledInlineTools)) {\r\n tool.inlineTools = new ToolsCollection<InlineToolAdapter>(\r\n /** Prepend ConvertTo Inline Tool */\r\n ['convertTo', ...tool.enabledInlineTools].map(name => [name, this.inlineTools.get(name)])\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Assign enabled Block Tunes for Block Tool\r\n *\r\n * @param tool — Block Tool\r\n */\r\n private assignBlockTunesToBlockTool(tool: BlockToolAdapter): void {\r\n if (tool.enabledBlockTunes === false) {\r\n return;\r\n }\r\n\r\n if (Array.isArray(tool.enabledBlockTunes)) {\r\n const userTunes = new ToolsCollection<BlockTuneAdapter>(\r\n tool.enabledBlockTunes.map(name => [name, this.blockTunes.get(name)])\r\n );\r\n\r\n tool.tunes = new ToolsCollection<BlockTuneAdapter>([...userTunes, ...this.blockTunes.internalTools]);\r\n\r\n return;\r\n }\r\n\r\n if (Array.isArray(this.config.tunes)) {\r\n const userTunes = new ToolsCollection<BlockTuneAdapter>(\r\n this.config.tunes.map(name => [name, this.blockTunes.get(name)])\r\n );\r\n\r\n tool.tunes = new ToolsCollection<BlockTuneAdapter>([...userTunes, ...this.blockTunes.internalTools]);\r\n\r\n return;\r\n }\r\n\r\n tool.tunes = this.blockTunes.internalTools;\r\n }\r\n\r\n /**\r\n * Validate Tools configuration objects and throw Error for user if it is invalid\r\n */\r\n private validateTools(): void {\r\n /**\r\n * Check Tools for a class containing\r\n */\r\n for (const toolName in this.config.tools) {\r\n if (Object.prototype.hasOwnProperty.call(this.config.tools, toolName)) {\r\n if (toolName in this.internalTools) {\r\n return;\r\n }\r\n\r\n const tool = this.config.tools[toolName];\r\n\r\n if (!_.isFunction(tool) && !_.isFunction((tool as ToolSettings).class)) {\r\n throw Error(\r\n `Tool «${toolName}» must be a constructor function or an object with function in the «class» property`\r\n );\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Unify tools config\r\n */\r\n private prepareConfig(): {[name: string]: ToolSettings} {\r\n const config: {[name: string]: ToolSettings} = {};\r\n\r\n /**\r\n * Save Tools settings to a map\r\n */\r\n for (const toolName in this.config.tools) {\r\n /**\r\n * If Tool is an object not a Tool's class then\r\n * save class and settings separately\r\n */\r\n if (_.isObject(this.config.tools[toolName])) {\r\n config[toolName] = this.config.tools[toolName] as ToolSettings;\r\n } else {\r\n config[toolName] = { class: this.config.tools[toolName] as ToolConstructable };\r\n }\r\n }\r\n\r\n return config;\r\n }\r\n}\r\n","/* eslint-disable jsdoc/no-undefined-types */\r\n/**\r\n * Module UI\r\n *\r\n * @type {UI}\r\n */\r\nimport Module from '../__module';\r\nimport $, { toggleEmptyMark } from '../dom';\r\nimport * as _ from '../utils';\r\n\r\nimport Selection from '../selection';\r\nimport Block from '../block';\r\nimport Flipper from '../flipper';\r\nimport { mobileScreenBreakpoint } from '../utils';\r\n\r\nimport styles from '../../styles/main.css?inline';\r\nimport { BlockHovered } from '../events/BlockHovered';\r\nimport { selectionChangeDebounceTimeout } from '../constants';\r\nimport { EditorMobileLayoutToggled } from '../events';\r\n/**\r\n * HTML Elements used for UI\r\n */\r\ninterface UINodes {\r\n holder: HTMLElement;\r\n wrapper: HTMLElement;\r\n redactor: HTMLElement;\r\n}\r\n\r\n/**\r\n * @class\r\n * @classdesc Makes Editor.js UI:\r\n * <codex-editor>\r\n * <ce-redactor />\r\n * <ce-toolbar />\r\n * <ce-inline-toolbar />\r\n * </codex-editor>\r\n * @typedef {UI} UI\r\n * @property {EditorConfig} config - editor configuration {@link EditorJS#configuration}\r\n * @property {object} Editor - available editor modules {@link EditorJS#moduleInstances}\r\n * @property {object} nodes -\r\n * @property {Element} nodes.holder - element where we need to append redactor\r\n * @property {Element} nodes.wrapper - <codex-editor>\r\n * @property {Element} nodes.redactor - <ce-redactor>\r\n */\r\nexport default class UI extends Module<UINodes> {\r\n /**\r\n * Editor.js UI CSS class names\r\n *\r\n * @returns {{editorWrapper: string, editorZone: string}}\r\n */\r\n public get CSS(): {\r\n editorWrapper: string; editorWrapperNarrow: string; editorZone: string; editorZoneHidden: string;\r\n editorEmpty: string; editorRtlFix: string;\r\n } {\r\n return {\r\n editorWrapper: 'codex-editor',\r\n editorWrapperNarrow: 'codex-editor--narrow',\r\n editorZone: 'codex-editor__redactor',\r\n editorZoneHidden: 'codex-editor__redactor--hidden',\r\n editorEmpty: 'codex-editor--empty',\r\n editorRtlFix: 'codex-editor--rtl',\r\n };\r\n }\r\n\r\n /**\r\n * Return Width of center column of Editor\r\n *\r\n * @returns {DOMRect}\r\n */\r\n public get contentRect(): DOMRect {\r\n if (this.contentRectCache !== null) {\r\n return this.contentRectCache;\r\n }\r\n\r\n const someBlock = this.nodes.wrapper.querySelector(`.${Block.CSS.content}`);\r\n\r\n /**\r\n * When Editor is not ready, there is no Blocks, so return the default value\r\n */\r\n if (!someBlock) {\r\n return {\r\n width: 650,\r\n left: 0,\r\n right: 0,\r\n } as DOMRect;\r\n }\r\n\r\n this.contentRectCache = someBlock.getBoundingClientRect();\r\n\r\n return this.contentRectCache;\r\n }\r\n\r\n /**\r\n * Flag that became true on mobile viewport\r\n *\r\n * @type {boolean}\r\n */\r\n public isMobile = false;\r\n\r\n\r\n /**\r\n * Cache for center column rectangle info\r\n * Invalidates on window resize\r\n *\r\n * @type {DOMRect}\r\n */\r\n private contentRectCache: DOMRect | null = null;\r\n\r\n /**\r\n * Handle window resize only when it finished\r\n *\r\n * @type {() => void}\r\n */\r\n private resizeDebouncer: () => void = _.debounce(() => {\r\n this.windowResize();\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n }, 200);\r\n\r\n /**\r\n * Handle selection change to manipulate Inline Toolbar appearance\r\n */\r\n private selectionChangeDebounced = _.debounce(() => {\r\n this.selectionChanged();\r\n }, selectionChangeDebounceTimeout);\r\n\r\n /**\r\n * Making main interface\r\n */\r\n public async prepare(): Promise<void> {\r\n /**\r\n * Detect mobile version\r\n */\r\n this.setIsMobile();\r\n\r\n /**\r\n * Make main UI elements\r\n */\r\n this.make();\r\n\r\n /**\r\n * Load and append CSS\r\n */\r\n this.loadStyles();\r\n }\r\n\r\n /**\r\n * Toggle read-only state\r\n *\r\n * If readOnly is true:\r\n * - removes all listeners from main UI module elements\r\n *\r\n * if readOnly is false:\r\n * - enables all listeners to UI module elements\r\n *\r\n * @param {boolean} readOnlyEnabled - \"read only\" state\r\n */\r\n public toggleReadOnly(readOnlyEnabled: boolean): void {\r\n /**\r\n * Prepare components based on read-only state\r\n */\r\n if (!readOnlyEnabled) {\r\n /**\r\n * Postpone events binding to the next tick to make sure all ui elements are ready\r\n */\r\n window.requestIdleCallback(() => {\r\n /**\r\n * Bind events for the UI elements\r\n */\r\n this.bindReadOnlySensitiveListeners();\r\n }, {\r\n timeout: 2000,\r\n });\r\n } else {\r\n /**\r\n * Unbind all events\r\n *\r\n */\r\n this.unbindReadOnlySensitiveListeners();\r\n }\r\n }\r\n\r\n /**\r\n * Check if Editor is empty and set CSS class to wrapper\r\n */\r\n public checkEmptiness(): void {\r\n const { BlockManager } = this.Editor;\r\n\r\n this.nodes.wrapper.classList.toggle(this.CSS.editorEmpty, BlockManager.isEditorEmpty);\r\n }\r\n\r\n /**\r\n * Check if one of Toolbar is opened\r\n * Used to prevent global keydowns (for example, Enter) conflicts with Enter-on-toolbar\r\n *\r\n * @returns {boolean}\r\n */\r\n public get someToolbarOpened(): boolean {\r\n const { Toolbar, BlockSettings, InlineToolbar } = this.Editor;\r\n\r\n return Boolean(BlockSettings.opened || InlineToolbar.opened || Toolbar.toolbox.opened);\r\n }\r\n\r\n /**\r\n * Check for some Flipper-buttons is under focus\r\n */\r\n public get someFlipperButtonFocused(): boolean {\r\n /**\r\n * Toolbar has internal module (Toolbox) that has own Flipper,\r\n * so we check it manually\r\n */\r\n if (this.Editor.Toolbar.toolbox.hasFocus()) {\r\n return true;\r\n }\r\n\r\n /* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\r\n return Object.entries(this.Editor).filter(([_moduleName, moduleClass]) => {\r\n return moduleClass.flipper instanceof Flipper;\r\n })\r\n .some(([_moduleName, moduleClass]) => {\r\n return moduleClass.flipper.hasFocus();\r\n });\r\n\r\n /* eslint-enable @typescript-eslint/no-unused-vars, no-unused-vars */\r\n }\r\n\r\n /**\r\n * Clean editor`s UI\r\n */\r\n public destroy(): void {\r\n this.nodes.holder.innerHTML = '';\r\n\r\n this.unbindReadOnlyInsensitiveListeners();\r\n }\r\n\r\n /**\r\n * Close all Editor's toolbars\r\n */\r\n public closeAllToolbars(): void {\r\n const { Toolbar, BlockSettings, InlineToolbar } = this.Editor;\r\n\r\n BlockSettings.close();\r\n InlineToolbar.close();\r\n Toolbar.toolbox.close();\r\n }\r\n\r\n /**\r\n * Event listener for 'mousedown' and 'touchstart' events\r\n *\r\n * @param event - TouchEvent or MouseEvent\r\n */\r\n private documentTouchedListener = (event: Event): void => {\r\n this.documentTouched(event);\r\n };\r\n\r\n /**\r\n * Check for mobile mode and save the result\r\n */\r\n private setIsMobile(): void {\r\n const isMobile = window.innerWidth < mobileScreenBreakpoint;\r\n\r\n if (isMobile !== this.isMobile) {\r\n /**\r\n * Dispatch global event\r\n */\r\n this.eventsDispatcher.emit(EditorMobileLayoutToggled, {\r\n isEnabled: this.isMobile,\r\n });\r\n }\r\n\r\n this.isMobile = isMobile;\r\n }\r\n\r\n /**\r\n * Makes Editor.js interface\r\n */\r\n private make(): void {\r\n /**\r\n * Element where we need to append Editor.js\r\n *\r\n * @type {Element}\r\n */\r\n this.nodes.holder = $.getHolder(this.config.holder);\r\n\r\n /**\r\n * Create and save main UI elements\r\n */\r\n this.nodes.wrapper = $.make('div', [\r\n this.CSS.editorWrapper,\r\n ...(this.isRtl ? [ this.CSS.editorRtlFix ] : []),\r\n ]);\r\n this.nodes.redactor = $.make('div', this.CSS.editorZone);\r\n\r\n /**\r\n * If Editor has injected into the narrow container, enable Narrow Mode\r\n *\r\n * @todo Forced layout. Get rid of this feature\r\n */\r\n if (this.nodes.holder.offsetWidth < this.contentRect.width) {\r\n this.nodes.wrapper.classList.add(this.CSS.editorWrapperNarrow);\r\n }\r\n\r\n /**\r\n * Set customizable bottom zone height\r\n */\r\n this.nodes.redactor.style.paddingBottom = this.config.minHeight + 'px';\r\n\r\n this.nodes.wrapper.appendChild(this.nodes.redactor);\r\n this.nodes.holder.appendChild(this.nodes.wrapper);\r\n\r\n this.bindReadOnlyInsensitiveListeners();\r\n }\r\n\r\n /**\r\n * Appends CSS\r\n */\r\n private loadStyles(): void {\r\n /**\r\n * Load CSS\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n const styleTagId = 'editor-js-styles';\r\n\r\n /**\r\n * Do not append styles again if they are already on the page\r\n */\r\n if ($.get(styleTagId)) {\r\n return;\r\n }\r\n\r\n /**\r\n * Make tag\r\n */\r\n const tag = $.make('style', null, {\r\n id: styleTagId,\r\n textContent: styles.toString(),\r\n });\r\n\r\n /**\r\n * If user enabled Content Security Policy, he can pass nonce through the config\r\n *\r\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce\r\n */\r\n if (this.config.style && !_.isEmpty(this.config.style) && this.config.style.nonce) {\r\n tag.setAttribute('nonce', this.config.style.nonce);\r\n }\r\n\r\n /**\r\n * Append styles at the top of HEAD tag\r\n */\r\n $.prepend(document.head, tag);\r\n }\r\n\r\n /**\r\n * Adds listeners that should work both in read-only and read-write modes\r\n */\r\n private bindReadOnlyInsensitiveListeners(): void {\r\n this.listeners.on(document, 'selectionchange', this.selectionChangeDebounced);\r\n\r\n this.listeners.on(window, 'resize', this.resizeDebouncer, {\r\n passive: true,\r\n });\r\n\r\n this.listeners.on(this.nodes.redactor, 'mousedown', this.documentTouchedListener, {\r\n capture: true,\r\n passive: true,\r\n });\r\n\r\n this.listeners.on(this.nodes.redactor, 'touchstart', this.documentTouchedListener, {\r\n capture: true,\r\n passive: true,\r\n });\r\n }\r\n\r\n /**\r\n * Removes listeners that should work both in read-only and read-write modes\r\n */\r\n private unbindReadOnlyInsensitiveListeners(): void {\r\n this.listeners.off(document, 'selectionchange', this.selectionChangeDebounced);\r\n this.listeners.off(window, 'resize', this.resizeDebouncer);\r\n this.listeners.off(this.nodes.redactor, 'mousedown', this.documentTouchedListener);\r\n this.listeners.off(this.nodes.redactor, 'touchstart', this.documentTouchedListener);\r\n }\r\n\r\n\r\n /**\r\n * Adds listeners that should work only in read-only mode\r\n */\r\n private bindReadOnlySensitiveListeners(): void {\r\n this.readOnlyMutableListeners.on(this.nodes.redactor, 'click', (event: MouseEvent) => {\r\n this.redactorClicked(event);\r\n }, false);\r\n\r\n this.readOnlyMutableListeners.on(document, 'keydown', (event: KeyboardEvent) => {\r\n this.documentKeydown(event);\r\n }, true);\r\n\r\n this.readOnlyMutableListeners.on(document, 'mousedown', (event: MouseEvent) => {\r\n this.documentClicked(event);\r\n }, true);\r\n\r\n /**\r\n * Start watching 'block-hovered' events that is used by Toolbar for moving\r\n */\r\n this.watchBlockHoveredEvents();\r\n\r\n /**\r\n * We have custom logic for providing placeholders for contenteditable elements.\r\n * To make it work, we need to have data-empty mark on empty inputs.\r\n */\r\n this.enableInputsEmptyMark();\r\n }\r\n\r\n\r\n /**\r\n * Listen redactor mousemove to emit 'block-hovered' event\r\n */\r\n private watchBlockHoveredEvents(): void {\r\n /**\r\n * Used to not emit the same block multiple times to the 'block-hovered' event on every mousemove\r\n */\r\n let blockHoveredEmitted;\r\n\r\n this.readOnlyMutableListeners.on(this.nodes.redactor, 'mousemove', _.throttle((event: MouseEvent | TouchEvent) => {\r\n const hoveredBlock = (event.target as Element).closest('.ce-block');\r\n\r\n /**\r\n * Do not trigger 'block-hovered' for cross-block selection\r\n */\r\n if (this.Editor.BlockSelection.anyBlockSelected) {\r\n return;\r\n }\r\n\r\n if (!hoveredBlock) {\r\n return;\r\n }\r\n\r\n if (blockHoveredEmitted === hoveredBlock) {\r\n return;\r\n }\r\n\r\n blockHoveredEmitted = hoveredBlock;\r\n\r\n this.eventsDispatcher.emit(BlockHovered, {\r\n block: this.Editor.BlockManager.getBlockByChildNode(hoveredBlock),\r\n });\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n }, 20), {\r\n passive: true,\r\n });\r\n }\r\n\r\n /**\r\n * Unbind events that should work only in read-only mode\r\n */\r\n private unbindReadOnlySensitiveListeners(): void {\r\n this.readOnlyMutableListeners.clearAll();\r\n }\r\n\r\n /**\r\n * Resize window handler\r\n */\r\n private windowResize(): void {\r\n /**\r\n * Invalidate content zone size cached, because it may be changed\r\n */\r\n this.contentRectCache = null;\r\n\r\n /**\r\n * Detect mobile version\r\n */\r\n this.setIsMobile();\r\n }\r\n\r\n /**\r\n * All keydowns on document\r\n *\r\n * @param {KeyboardEvent} event - keyboard event\r\n */\r\n private documentKeydown(event: KeyboardEvent): void {\r\n switch (event.keyCode) {\r\n case _.keyCodes.ENTER:\r\n this.enterPressed(event);\r\n break;\r\n\r\n case _.keyCodes.BACKSPACE:\r\n case _.keyCodes.DELETE:\r\n this.backspacePressed(event);\r\n break;\r\n\r\n case _.keyCodes.ESC:\r\n this.escapePressed(event);\r\n break;\r\n\r\n default:\r\n this.defaultBehaviour(event);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Ignore all other document's keydown events\r\n *\r\n * @param {KeyboardEvent} event - keyboard event\r\n */\r\n private defaultBehaviour(event: KeyboardEvent): void {\r\n const { currentBlock } = this.Editor.BlockManager;\r\n const keyDownOnEditor = (event.target as HTMLElement).closest(`.${this.CSS.editorWrapper}`);\r\n const isMetaKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\r\n\r\n /**\r\n * When some block is selected, but the caret is not set inside the editor, treat such keydowns as keydown on selected block.\r\n */\r\n if (currentBlock !== undefined && keyDownOnEditor === null) {\r\n this.Editor.BlockEvents.keydown(event);\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Ignore keydowns on editor and meta keys\r\n */\r\n if (keyDownOnEditor || (currentBlock && isMetaKey)) {\r\n return;\r\n }\r\n\r\n /**\r\n * Remove all highlights and remove caret\r\n */\r\n this.Editor.BlockManager.unsetCurrentBlock();\r\n\r\n /**\r\n * Close Toolbar\r\n */\r\n this.Editor.Toolbar.close();\r\n }\r\n\r\n /**\r\n * @param {KeyboardEvent} event - keyboard event\r\n */\r\n private backspacePressed(event: KeyboardEvent): void {\r\n const { BlockManager, BlockSelection, Caret } = this.Editor;\r\n\r\n /**\r\n * If any block selected and selection doesn't exists on the page (that means no other editable element is focused),\r\n * remove selected blocks\r\n */\r\n if (BlockSelection.anyBlockSelected && !Selection.isSelectionExists) {\r\n const selectionPositionIndex = BlockManager.removeSelectedBlocks();\r\n\r\n const newBlock = BlockManager.insertDefaultBlockAtIndex(selectionPositionIndex, true);\r\n\r\n Caret.setToBlock(newBlock, Caret.positions.START);\r\n\r\n /** Clear selection */\r\n BlockSelection.clearSelection(event);\r\n\r\n /**\r\n * Stop propagations\r\n * Manipulation with BlockSelections is handled in global backspacePress because they may occur\r\n * with CMD+A or RectangleSelection and they can be handled on document event\r\n */\r\n event.preventDefault();\r\n event.stopPropagation();\r\n event.stopImmediatePropagation();\r\n }\r\n }\r\n\r\n /**\r\n * Escape pressed\r\n * If some of Toolbar components are opened, then close it otherwise close Toolbar\r\n *\r\n * @param {Event} event - escape keydown event\r\n */\r\n private escapePressed(event): void {\r\n /**\r\n * Clear blocks selection by ESC\r\n */\r\n this.Editor.BlockSelection.clearSelection(event);\r\n\r\n if (this.Editor.Toolbar.toolbox.opened) {\r\n this.Editor.Toolbar.toolbox.close();\r\n this.Editor.Caret.setToBlock(this.Editor.BlockManager.currentBlock, this.Editor.Caret.positions.END);\r\n } else if (this.Editor.BlockSettings.opened) {\r\n this.Editor.BlockSettings.close();\r\n } else if (this.Editor.InlineToolbar.opened) {\r\n this.Editor.InlineToolbar.close();\r\n } else {\r\n this.Editor.Toolbar.close();\r\n }\r\n }\r\n\r\n /**\r\n * Enter pressed on document\r\n *\r\n * @param {KeyboardEvent} event - keyboard event\r\n */\r\n private enterPressed(event: KeyboardEvent): void {\r\n const { BlockManager, BlockSelection } = this.Editor;\r\n\r\n if (this.someToolbarOpened) {\r\n return;\r\n }\r\n\r\n const hasPointerToBlock = BlockManager.currentBlockIndex >= 0;\r\n\r\n /**\r\n * If any block selected and selection doesn't exists on the page (that means no other editable element is focused),\r\n * remove selected blocks\r\n */\r\n if (BlockSelection.anyBlockSelected && !Selection.isSelectionExists) {\r\n /** Clear selection */\r\n BlockSelection.clearSelection(event);\r\n\r\n /**\r\n * Stop propagations\r\n * Manipulation with BlockSelections is handled in global enterPress because they may occur\r\n * with CMD+A or RectangleSelection\r\n */\r\n event.preventDefault();\r\n event.stopImmediatePropagation();\r\n event.stopPropagation();\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * If Caret is not set anywhere, event target on Enter is always Element that we handle\r\n * In our case it is document.body\r\n *\r\n * So, BlockManager points some Block and Enter press is on Body\r\n * We can create a new block\r\n */\r\n if (!this.someToolbarOpened && hasPointerToBlock && (event.target as HTMLElement).tagName === 'BODY') {\r\n /**\r\n * Insert the default typed Block\r\n */\r\n const newBlock = this.Editor.BlockManager.insert();\r\n\r\n /**\r\n * Prevent default enter behaviour to prevent adding a new line (<div><br></div>) to the inserted block\r\n */\r\n event.preventDefault();\r\n this.Editor.Caret.setToBlock(newBlock);\r\n\r\n /**\r\n * Move toolbar and show plus button because new Block is empty\r\n */\r\n this.Editor.Toolbar.moveAndOpen(newBlock);\r\n }\r\n\r\n this.Editor.BlockSelection.clearSelection(event);\r\n }\r\n\r\n /**\r\n * All clicks on document\r\n *\r\n * @param {MouseEvent} event - Click event\r\n */\r\n private documentClicked(event: MouseEvent): void {\r\n /**\r\n * Sometimes we emulate click on some UI elements, for example by Enter on Block Settings button\r\n * We don't need to handle such events, because they handled in other place.\r\n */\r\n if (!event.isTrusted) {\r\n return;\r\n }\r\n /**\r\n * Close Inline Toolbar when nothing selected\r\n * Do not fire check on clicks at the Inline Toolbar buttons\r\n */\r\n const target = event.target as HTMLElement;\r\n const clickedInsideOfEditor = this.nodes.holder.contains(target) || Selection.isAtEditor;\r\n\r\n if (!clickedInsideOfEditor) {\r\n /**\r\n * Clear pointer on BlockManager\r\n *\r\n * Current page might contain several instances\r\n * Click between instances MUST clear focus, pointers and close toolbars\r\n */\r\n this.Editor.BlockManager.unsetCurrentBlock();\r\n this.Editor.Toolbar.close();\r\n }\r\n\r\n /**\r\n * If Block Settings opened, close them by click on document.\r\n *\r\n * But allow clicking inside Block Settings.\r\n * Also, do not process clicks on the Block Settings Toggler, because it has own click listener\r\n */\r\n const isClickedInsideBlockSettings = this.Editor.BlockSettings.nodes.wrapper?.contains(target);\r\n const isClickedInsideBlockSettingsToggler = this.Editor.Toolbar.nodes.settingsToggler?.contains(target);\r\n const doNotProcess = isClickedInsideBlockSettings || isClickedInsideBlockSettingsToggler;\r\n\r\n if (this.Editor.BlockSettings.opened && !doNotProcess) {\r\n this.Editor.BlockSettings.close();\r\n\r\n const clickedBlock = this.Editor.BlockManager.getBlockByChildNode(target);\r\n\r\n this.Editor.Toolbar.moveAndOpen(clickedBlock);\r\n }\r\n\r\n /**\r\n * Clear Selection if user clicked somewhere\r\n */\r\n this.Editor.BlockSelection.clearSelection(event);\r\n }\r\n\r\n /**\r\n * First touch on editor\r\n * Fired before click\r\n *\r\n * Used to change current block — we need to do it before 'selectionChange' event.\r\n * Also:\r\n * - Move and show the Toolbar\r\n * - Set a Caret\r\n *\r\n * @param event - touch or mouse event\r\n */\r\n private documentTouched(event: Event): void {\r\n let clickedNode = event.target as HTMLElement;\r\n\r\n /**\r\n * If click was fired on Editor`s wrapper, try to get clicked node by elementFromPoint method\r\n */\r\n if (clickedNode === this.nodes.redactor) {\r\n const clientX = event instanceof MouseEvent ? event.clientX : (event as TouchEvent).touches[0].clientX;\r\n const clientY = event instanceof MouseEvent ? event.clientY : (event as TouchEvent).touches[0].clientY;\r\n\r\n clickedNode = document.elementFromPoint(clientX, clientY) as HTMLElement;\r\n }\r\n\r\n /**\r\n * Select clicked Block as Current\r\n */\r\n try {\r\n this.Editor.BlockManager.setCurrentBlockByChildNode(clickedNode);\r\n } catch (e) {\r\n /**\r\n * If clicked outside first-level Blocks and it is not RectSelection, set Caret to the last empty Block\r\n */\r\n if (!this.Editor.RectangleSelection.isRectActivated()) {\r\n this.Editor.Caret.setToTheLastBlock();\r\n }\r\n }\r\n\r\n /**\r\n * Move and open toolbar\r\n * (used for showing Block Settings toggler after opening and closing Inline Toolbar)\r\n */\r\n if (!this.Editor.ReadOnly.isEnabled) {\r\n this.Editor.Toolbar.moveAndOpen();\r\n }\r\n }\r\n\r\n /**\r\n * All clicks on the redactor zone\r\n *\r\n * @param {MouseEvent} event - click event\r\n * @description\r\n * - By clicks on the Editor's bottom zone:\r\n * - if last Block is empty, set a Caret to this\r\n * - otherwise, add a new empty Block and set a Caret to that\r\n */\r\n private redactorClicked(event: MouseEvent): void {\r\n if (!Selection.isCollapsed) {\r\n return;\r\n }\r\n\r\n /**\r\n * case when user clicks on anchor element\r\n * if it is clicked via ctrl key, then we open new window with url\r\n */\r\n const element = event.target as Element;\r\n const ctrlKey = event.metaKey || event.ctrlKey;\r\n\r\n if ($.isAnchor(element) && ctrlKey) {\r\n event.stopImmediatePropagation();\r\n event.stopPropagation();\r\n\r\n const href = element.getAttribute('href');\r\n const validUrl = _.getValidUrl(href);\r\n\r\n _.openTab(validUrl);\r\n\r\n return;\r\n }\r\n\r\n this.processBottomZoneClick(event);\r\n }\r\n\r\n /**\r\n * Check if user clicks on the Editor's bottom zone:\r\n * - set caret to the last block\r\n * - or add new empty block\r\n *\r\n * @param event - click event\r\n */\r\n private processBottomZoneClick(event: MouseEvent): void {\r\n const lastBlock = this.Editor.BlockManager.getBlockByIndex(-1);\r\n\r\n const lastBlockBottomCoord = $.offset(lastBlock.holder).bottom;\r\n const clickedCoord = event.pageY;\r\n const { BlockSelection } = this.Editor;\r\n const isClickedBottom = event.target instanceof Element &&\r\n event.target.isEqualNode(this.nodes.redactor) &&\r\n /**\r\n * If there is cross block selection started, target will be equal to redactor so we need additional check\r\n */\r\n !BlockSelection.anyBlockSelected &&\r\n\r\n /**\r\n * Prevent caret jumping (to last block) when clicking between blocks\r\n */\r\n lastBlockBottomCoord < clickedCoord;\r\n\r\n if (isClickedBottom) {\r\n event.stopImmediatePropagation();\r\n event.stopPropagation();\r\n\r\n const { BlockManager, Caret, Toolbar } = this.Editor;\r\n\r\n /**\r\n * Insert a default-block at the bottom if:\r\n * - last-block is not a default-block (Text)\r\n * to prevent unnecessary tree-walking on Tools with many nodes (for ex. Table)\r\n * - Or, default-block is not empty\r\n */\r\n if (!BlockManager.lastBlock.tool.isDefault || !BlockManager.lastBlock.isEmpty) {\r\n BlockManager.insertAtEnd();\r\n }\r\n\r\n /**\r\n * Set the caret and toolbar to empty Block\r\n */\r\n Caret.setToTheLastBlock();\r\n Toolbar.moveAndOpen(BlockManager.lastBlock);\r\n }\r\n }\r\n\r\n /**\r\n * Handle selection changes on mobile devices\r\n * Uses for showing the Inline Toolbar\r\n */\r\n private selectionChanged(): void {\r\n const { CrossBlockSelection, BlockSelection } = this.Editor;\r\n const focusedElement = Selection.anchorElement;\r\n\r\n if (CrossBlockSelection.isCrossBlockSelectionStarted) {\r\n // Removes all ranges when any Block is selected\r\n if (BlockSelection.anyBlockSelected) {\r\n Selection.get().removeAllRanges();\r\n }\r\n }\r\n\r\n /**\r\n * Usual clicks on some controls, for example, Block Tunes Toggler\r\n */\r\n if (!focusedElement) {\r\n /**\r\n * If there is no selected range, close inline toolbar\r\n *\r\n * @todo Make this method more straightforward\r\n */\r\n if (!Selection.range) {\r\n this.Editor.InlineToolbar.close();\r\n }\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Event can be fired on clicks at non-block-content elements,\r\n * for example, at the Inline Toolbar or some Block Tune element.\r\n * We also make sure that the closest block belongs to the current editor and not a parent\r\n */\r\n const closestBlock = focusedElement.closest(`.${Block.CSS.content}`);\r\n const clickedOutsideBlockContent = closestBlock === null || (closestBlock.closest(`.${Selection.CSS.editorWrapper}`) !== this.nodes.wrapper);\r\n\r\n if (clickedOutsideBlockContent) {\r\n /**\r\n * If new selection is not on Inline Toolbar, we need to close it\r\n */\r\n if (!this.Editor.InlineToolbar.containsNode(focusedElement)) {\r\n this.Editor.InlineToolbar.close();\r\n }\r\n\r\n /**\r\n * Case when we click on external tool elements,\r\n * for example some Block Tune element.\r\n * If this external content editable element has data-inline-toolbar=\"true\"\r\n */\r\n const inlineToolbarEnabledForExternalTool = (focusedElement as HTMLElement).dataset.inlineToolbar === 'true';\r\n\r\n if (!inlineToolbarEnabledForExternalTool) {\r\n return;\r\n }\r\n }\r\n\r\n /**\r\n * Set current block when entering to Editor.js by tab key\r\n */\r\n if (!this.Editor.BlockManager.currentBlock) {\r\n this.Editor.BlockManager.setCurrentBlockByChildNode(focusedElement);\r\n }\r\n\r\n this.Editor.InlineToolbar.tryToShow(true);\r\n }\r\n\r\n /**\r\n * Editor.js provides and ability to show placeholders for empty contenteditable elements\r\n *\r\n * This method watches for input and focus events and toggles 'data-empty' attribute\r\n * to workaroud the case, when inputs contains only <br>s and has no visible content\r\n * Then, CSS could rely on this attribute to show placeholders\r\n */\r\n private enableInputsEmptyMark(): void {\r\n /**\r\n * Toggle data-empty attribute on input depending on its emptiness\r\n *\r\n * @param event - input or focus event\r\n */\r\n function handleInputOrFocusChange(event: Event): void {\r\n const input = event.target as HTMLElement;\r\n\r\n toggleEmptyMark(input);\r\n }\r\n\r\n this.readOnlyMutableListeners.on(this.nodes.wrapper, 'input', handleInputOrFocusChange);\r\n this.readOnlyMutableListeners.on(this.nodes.wrapper, 'focusin', handleInputOrFocusChange);\r\n this.readOnlyMutableListeners.on(this.nodes.wrapper, 'focusout', handleInputOrFocusChange);\r\n }\r\n}\r\n","/** ./api */\r\nimport BlocksAPI from './api/blocks';\r\nimport CaretAPI from './api/caret';\r\nimport EventsAPI from './api/events';\r\nimport I18nAPI from './api/i18n';\r\nimport API from './api/index';\r\nimport InlineToolbarAPI from './api/inlineToolbar';\r\nimport ListenersAPI from './api/listeners';\r\nimport NotifierAPI from './api/notifier';\r\nimport ReadOnlyAPI from './api/readonly';\r\nimport SanitizerAPI from './api/sanitizer';\r\nimport SaverAPI from './api/saver';\r\nimport SelectionAPI from './api/selection';\r\nimport ToolsAPI from './api/tools';\r\nimport StylesAPI from './api/styles';\r\nimport ToolbarAPI from './api/toolbar';\r\nimport TooltipAPI from './api/tooltip';\r\nimport UiAPI from './api/ui';\r\n\r\n/** ./toolbar */\r\nimport BlockSettings from './toolbar/blockSettings';\r\nimport Toolbar from './toolbar/index';\r\nimport InlineToolbar from './toolbar/inline';\r\n\r\n/** . */\r\nimport BlockEvents from './blockEvents';\r\nimport BlockManager from './blockManager';\r\nimport BlockSelection from './blockSelection';\r\nimport Caret from './caret';\r\nimport CrossBlockSelection from './crossBlockSelection';\r\nimport DragNDrop from './dragNDrop';\r\nimport ModificationsObserver from './modificationsObserver';\r\nimport Paste from './paste';\r\nimport ReadOnly from './readonly';\r\nimport RectangleSelection from './rectangleSelection';\r\nimport Renderer from './renderer';\r\nimport Saver from './saver';\r\nimport Tools from './tools';\r\nimport UI from './ui';\r\n\r\nexport default {\r\n // API Modules\r\n BlocksAPI,\r\n CaretAPI,\r\n EventsAPI,\r\n I18nAPI,\r\n API,\r\n InlineToolbarAPI,\r\n ListenersAPI,\r\n NotifierAPI,\r\n ReadOnlyAPI,\r\n SanitizerAPI,\r\n SaverAPI,\r\n SelectionAPI,\r\n ToolsAPI,\r\n StylesAPI,\r\n ToolbarAPI,\r\n TooltipAPI,\r\n UiAPI,\r\n\r\n // Toolbar Modules\r\n BlockSettings,\r\n Toolbar,\r\n InlineToolbar,\r\n\r\n // Modules\r\n BlockEvents,\r\n BlockManager,\r\n BlockSelection,\r\n Caret,\r\n CrossBlockSelection,\r\n DragNDrop,\r\n ModificationsObserver,\r\n Paste,\r\n ReadOnly,\r\n RectangleSelection,\r\n Renderer,\r\n Saver,\r\n Tools,\r\n UI,\r\n};\r\n","import $ from './dom';\r\nimport * as _ from './utils';\r\nimport type { EditorConfig, SanitizerConfig } from '../../types';\r\nimport type { EditorModules } from '../types-internal/editor-modules';\r\nimport I18n from './i18n';\r\nimport { CriticalError } from './errors/critical';\r\nimport EventsDispatcher from './utils/events';\r\nimport Modules from './modules';\r\nimport type { EditorEventMap } from './events';\r\n\r\n/**\r\n * Editor.js core class. Bootstraps modules.\r\n */\r\nexport default class Core {\r\n /**\r\n * Editor configuration passed by user to the constructor\r\n */\r\n public config: EditorConfig;\r\n\r\n /**\r\n * Object with core modules instances\r\n */\r\n public moduleInstances: EditorModules = {} as EditorModules;\r\n\r\n /**\r\n * Promise that resolves when all core modules are prepared and UI is rendered on the page\r\n */\r\n public isReady: Promise<void>;\r\n\r\n /**\r\n * Common Editor Event Bus\r\n */\r\n private eventsDispatcher: EventsDispatcher<EditorEventMap> = new EventsDispatcher();\r\n\r\n /**\r\n * @param {EditorConfig} config - user configuration\r\n */\r\n constructor(config?: EditorConfig|string) {\r\n /**\r\n * Ready promise. Resolved if Editor.js is ready to work, rejected otherwise\r\n */\r\n let onReady: (value?: void | PromiseLike<void>) => void;\r\n let onFail: (reason?: unknown) => void;\r\n\r\n this.isReady = new Promise((resolve, reject) => {\r\n onReady = resolve;\r\n onFail = reject;\r\n });\r\n\r\n Promise.resolve()\r\n .then(async () => {\r\n this.configuration = config;\r\n\r\n this.validate();\r\n this.init();\r\n await this.start();\r\n await this.render();\r\n\r\n const { BlockManager, Caret, UI, ModificationsObserver } = this.moduleInstances;\r\n\r\n UI.checkEmptiness();\r\n ModificationsObserver.enable();\r\n\r\n if ((this.configuration as EditorConfig).autofocus === true && this.configuration.readOnly !== true) {\r\n Caret.setToBlock(BlockManager.blocks[0], Caret.positions.START);\r\n }\r\n\r\n onReady();\r\n })\r\n .catch((error) => {\r\n _.log(`Editor.js is not ready because of ${error}`, 'error');\r\n\r\n /**\r\n * Reject this.isReady promise\r\n */\r\n onFail(error);\r\n });\r\n }\r\n\r\n /**\r\n * Setting for configuration\r\n *\r\n * @param {EditorConfig|string} config - Editor's config to set\r\n */\r\n public set configuration(config: EditorConfig|string) {\r\n /**\r\n * Place config into the class property\r\n *\r\n * @type {EditorConfig}\r\n */\r\n if (_.isObject(config)) {\r\n this.config = {\r\n ...config,\r\n };\r\n } else {\r\n /**\r\n * Process zero-configuration or with only holderId\r\n * Make config object\r\n */\r\n this.config = {\r\n holder: config,\r\n };\r\n }\r\n\r\n /**\r\n * If holderId is preset, assign him to holder property and work next only with holder\r\n */\r\n _.deprecationAssert(!!this.config.holderId, 'config.holderId', 'config.holder');\r\n if (this.config.holderId && !this.config.holder) {\r\n this.config.holder = this.config.holderId;\r\n this.config.holderId = null;\r\n }\r\n\r\n /**\r\n * If holder is empty then set a default value\r\n */\r\n if (this.config.holder == null) {\r\n this.config.holder = 'editorjs';\r\n }\r\n\r\n if (!this.config.logLevel) {\r\n this.config.logLevel = _.LogLevels.VERBOSE;\r\n }\r\n\r\n _.setLogLevel(this.config.logLevel);\r\n\r\n /**\r\n * If default Block's Tool was not passed, use the Paragraph Tool\r\n */\r\n _.deprecationAssert(Boolean(this.config.initialBlock), 'config.initialBlock', 'config.defaultBlock');\r\n this.config.defaultBlock = this.config.defaultBlock || this.config.initialBlock || 'paragraph';\r\n\r\n /**\r\n * Height of Editor's bottom area that allows to set focus on the last Block\r\n *\r\n * @type {number}\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n this.config.minHeight = this.config.minHeight !== undefined ? this.config.minHeight : 300;\r\n\r\n /**\r\n * Default block type\r\n * Uses in case when there is no blocks passed\r\n *\r\n * @type {{type: (*), data: {text: null}}}\r\n */\r\n const defaultBlockData = {\r\n type: this.config.defaultBlock,\r\n data: {},\r\n };\r\n\r\n this.config.placeholder = this.config.placeholder || false;\r\n this.config.sanitizer = this.config.sanitizer || {\r\n p: true,\r\n b: true,\r\n a: true,\r\n } as SanitizerConfig;\r\n\r\n this.config.hideToolbar = this.config.hideToolbar ? this.config.hideToolbar : false;\r\n this.config.tools = this.config.tools || {};\r\n this.config.i18n = this.config.i18n || {};\r\n this.config.data = this.config.data || { blocks: [] };\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n this.config.onReady = this.config.onReady || ((): void => {});\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n this.config.onChange = this.config.onChange || ((): void => {});\r\n this.config.inlineToolbar = this.config.inlineToolbar !== undefined ? this.config.inlineToolbar : true;\r\n\r\n /**\r\n * Initialize default Block to pass data to the Renderer\r\n */\r\n if (_.isEmpty(this.config.data) || !this.config.data.blocks || this.config.data.blocks.length === 0) {\r\n this.config.data = { blocks: [ defaultBlockData ] };\r\n }\r\n\r\n this.config.readOnly = this.config.readOnly as boolean || false;\r\n\r\n /**\r\n * Adjust i18n\r\n */\r\n if (this.config.i18n?.messages) {\r\n I18n.setDictionary(this.config.i18n.messages);\r\n }\r\n\r\n /**\r\n * Text direction. If not set, uses ltr\r\n */\r\n this.config.i18n.direction = this.config.i18n?.direction || 'ltr';\r\n }\r\n\r\n /**\r\n * Returns private property\r\n *\r\n * @returns {EditorConfig}\r\n */\r\n public get configuration(): EditorConfig {\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Checks for required fields in Editor's config\r\n */\r\n public validate(): void {\r\n const { holderId, holder } = this.config;\r\n\r\n if (holderId && holder) {\r\n throw Error('«holderId» and «holder» param can\\'t assign at the same time.');\r\n }\r\n\r\n /**\r\n * Check for a holder element's existence\r\n */\r\n if (_.isString(holder) && !$.get(holder)) {\r\n throw Error(`element with ID «${holder}» is missing. Pass correct holder's ID.`);\r\n }\r\n\r\n if (holder && _.isObject(holder) && !$.isElement(holder)) {\r\n throw Error('«holder» value must be an Element node');\r\n }\r\n }\r\n\r\n /**\r\n * Initializes modules:\r\n * - make and save instances\r\n * - configure\r\n */\r\n public init(): void {\r\n /**\r\n * Make modules instances and save it to the @property this.moduleInstances\r\n */\r\n this.constructModules();\r\n\r\n /**\r\n * Modules configuration\r\n */\r\n this.configureModules();\r\n }\r\n\r\n /**\r\n * Start Editor!\r\n *\r\n * Get list of modules that needs to be prepared and return a sequence (Promise)\r\n *\r\n * @returns {Promise<void>}\r\n */\r\n public async start(): Promise<void> {\r\n const modulesToPrepare = [\r\n 'Tools',\r\n 'UI',\r\n 'BlockManager',\r\n 'Paste',\r\n 'BlockSelection',\r\n 'RectangleSelection',\r\n 'CrossBlockSelection',\r\n 'ReadOnly',\r\n ];\r\n\r\n await modulesToPrepare.reduce(\r\n (promise, module) => promise.then(async () => {\r\n // _.log(`Preparing ${module} module`, 'time');\r\n\r\n try {\r\n await this.moduleInstances[module].prepare();\r\n } catch (e) {\r\n /**\r\n * CriticalError's will not be caught\r\n * It is used when Editor is rendering in read-only mode with unsupported plugin\r\n */\r\n if (e instanceof CriticalError) {\r\n throw new Error(e.message);\r\n }\r\n _.log(`Module ${module} was skipped because of %o`, 'warn', e);\r\n }\r\n // _.log(`Preparing ${module} module`, 'timeEnd');\r\n }),\r\n Promise.resolve()\r\n );\r\n }\r\n\r\n /**\r\n * Render initial data\r\n */\r\n private render(): Promise<void> {\r\n return this.moduleInstances.Renderer.render(this.config.data.blocks);\r\n }\r\n\r\n /**\r\n * Make modules instances and save it to the @property this.moduleInstances\r\n */\r\n private constructModules(): void {\r\n Object.entries(Modules).forEach(([key, module]) => {\r\n try {\r\n this.moduleInstances[key] = new module({\r\n config: this.configuration,\r\n eventsDispatcher: this.eventsDispatcher,\r\n });\r\n } catch (e) {\r\n _.log('[constructModules]', `Module ${key} skipped because`, 'error', e);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Modules instances configuration:\r\n * - pass other modules to the 'state' property\r\n * - ...\r\n */\r\n private configureModules(): void {\r\n for (const name in this.moduleInstances) {\r\n if (Object.prototype.hasOwnProperty.call(this.moduleInstances, name)) {\r\n /**\r\n * Module does not need self-instance\r\n */\r\n this.moduleInstances[name].state = this.getModulesDiff(name);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Return modules without passed name\r\n *\r\n * @param {string} name - module for witch modules difference should be calculated\r\n */\r\n private getModulesDiff(name: string): EditorModules {\r\n const diff = {} as EditorModules;\r\n\r\n for (const moduleName in this.moduleInstances) {\r\n /**\r\n * Skip module with passed name\r\n */\r\n if (moduleName === name) {\r\n continue;\r\n }\r\n diff[moduleName] = this.moduleInstances[moduleName];\r\n }\r\n\r\n return diff;\r\n }\r\n}\r\n","'use strict';\r\n\r\nimport type { EditorConfig } from '../types';\r\n\r\n/**\r\n * Apply polyfills\r\n */\r\nimport '@babel/register';\r\n\r\nimport './components/polyfills';\r\nimport Core from './components/core';\r\nimport * as _ from './components/utils';\r\nimport { destroy as destroyTooltip } from './components/utils/tooltip';\r\n\r\ndeclare const VERSION: string;\r\n\r\n/**\r\n * Editor.js\r\n *\r\n * @license Apache-2.0\r\n * @see Editor.js <https://editorjs.io>\r\n * @author CodeX Team <https://codex.so>\r\n */\r\nexport default class EditorJS {\r\n\r\n /**\r\n * Promise that resolves when core modules are ready and UI is rendered on the page\r\n */\r\n public isReady: Promise<void>;\r\n\r\n /**\r\n * Stores destroy method implementation.\r\n * Clear heap occupied by Editor and remove UI components from the DOM.\r\n */\r\n public destroy: () => void;\r\n\r\n /** Editor version */\r\n public static get version(): string {\r\n return VERSION;\r\n }\r\n\r\n /**\r\n * @param {EditorConfig|string|undefined} [configuration] - user configuration\r\n */\r\n constructor(configuration?: EditorConfig | string) {\r\n \r\n /**\r\n * Set default onReady function\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n let onReady = (): void => {};\r\n\r\n /**\r\n * If `onReady` was passed in `configuration` then redefine onReady function\r\n */\r\n if (_.isObject(configuration) && _.isFunction(configuration.onReady)) {\r\n onReady = configuration.onReady;\r\n }\r\n\r\n /**\r\n * Create a Editor.js instance\r\n */\r\n const editor = new Core(configuration);\r\n\r\n /**\r\n * We need to export isReady promise in the constructor\r\n * as it can be used before other API methods are exported\r\n *\r\n * @type {Promise<void>}\r\n */\r\n this.isReady = editor.isReady.then(() => {\r\n this.exportAPI(editor);\r\n /**\r\n * @todo pass API as an argument. It will allow to use Editor's API when editor is ready\r\n */\r\n onReady();\r\n });\r\n }\r\n\r\n /**\r\n * Export external API methods\r\n *\r\n * @param {Core} editor — Editor's instance\r\n */\r\n public exportAPI(editor: Core): void {\r\n const fieldsToExport = [ 'configuration' ];\r\n const destroy = (): void => {\r\n Object.values(editor.moduleInstances)\r\n .forEach((moduleInstance) => {\r\n if (_.isFunction(moduleInstance.destroy)) {\r\n moduleInstance.destroy();\r\n }\r\n moduleInstance.listeners.removeAll();\r\n });\r\n\r\n destroyTooltip();\r\n\r\n editor = null;\r\n\r\n for (const field in this) {\r\n if (Object.prototype.hasOwnProperty.call(this, field)) {\r\n delete this[field];\r\n }\r\n }\r\n\r\n Object.setPrototypeOf(this, null);\r\n };\r\n\r\n fieldsToExport.forEach((field) => {\r\n this[field] = editor[field];\r\n });\r\n\r\n this.destroy = destroy;\r\n\r\n Object.setPrototypeOf(this, editor.moduleInstances.API.methods);\r\n\r\n delete this.exportAPI;\r\n\r\n const shorthands = {\r\n blocks: {\r\n clear: 'clear',\r\n render: 'render',\r\n },\r\n caret: {\r\n focus: 'focus',\r\n },\r\n events: {\r\n on: 'on',\r\n off: 'off',\r\n emit: 'emit',\r\n },\r\n saver: {\r\n save: 'save',\r\n },\r\n };\r\n\r\n Object.entries(shorthands)\r\n .forEach(([key, methods]) => {\r\n Object.entries(methods)\r\n .forEach(([name, alias]) => {\r\n this[alias] = editor.moduleInstances.API.methods[key][name];\r\n });\r\n });\r\n }\r\n}\r\n"],"names":["register","s","matches","i","el","nodes","docFrag","node","isNode","centerIfNeeded","parent","parentComputedStyle","parentBorderTopWidth","parentBorderLeftWidth","overTop","overBottom","overLeft","overRight","alignWithTop","cb","start","id","nanoid","size","byte","LogLevels","keyCodes","mouseButtons","_log","labeled","msg","type","args","style","isSimpleType","argsToPass","editorLabelText","editorLabelStyle","setLogLevel","logLevel","log","logLabeled","typeOf","object","isFunction","fn","isObject","v","isString","isBoolean","isNumber","isUndefined","isEmpty","isPrintableKey","keyCode","sequence","chains","success","fallback","waitNextBlock","chainData","successCallback","fallbackCallback","previousValue","currentValue","array","collection","delay","method","timeout","context","getFileExtension","file","isValidMimeType","debounce","func","wait","immediate","later","callNow","throttle","options","result","previous","now","remaining","getUserOS","OS","userOS","os","capitalize","text","deepMerge","target","sources","source","key","beautifyShortcut","shortcut","getValidUrl","url","generateBlockId","openTab","generateId","prefix","deprecationAssert","condition","oldProperty","newProperty","message","cacheable","propertyKey","descriptor","propertyToOverride","originalMethod","cacheKey","originalSet","value","mobileScreenBreakpoint","isMobileScreen","isIosDevice","equals","var1","var2","isVar1NonPrimitive","isVar2NonPrimitive","Dom","tag","element","tagName","classNames","attributes","validClassnames","className","attrName","content","elements","el1","el2","temp","selector","holder","_.array","input","atLast","child","sibling","nodeChild","_.isNumber","nativeInputs","ignoreChars","nodeText","treeWalker","str","wrapper","data","_.isString","check","rect","scrollLeft","scrollTop","top","left","root","totalOffset","currentOffset","lastTextNode","walker","textContent","nodeLength","nodeOffset","isCollapsedWhitespaces","calculateBaseline","fontSize","lineHeight","paddingTop","borderTopWidth","marginTop","baselineOffset","extraLineHeight","toggleEmptyMark","_I18n","internalNamespace","dictKey","namespace","dictionary","section","part","defaultDictionary","I18n","CriticalError","EventsDispatcher","eventName","callback","wrappedCallback","indexOfHandler","previousData","currentHandler","newData","BlockAPI","block","state","methodName","param","Listeners","eventType","handler","_.generateId","assignedEventData","existingListeners","listener","index","foundListeners","found","foundByEventTargets","event","current","Module","config","eventsDispatcher","Editor","SelectionUtils","selection","anchorNode","$","selectedNode","editorZone","range","sel","_.log","span","spanParent","offset","container","fakeCursor","searchDepth","parentTag","searchDepthIterable","isMutationBelongsToElement","mutationRecord","addedNodes","removedNodes","RedactorDomChanged","BlockChanged","FakeCursorAboutToBeToggled","FakeCursorHaveBeenSet","EditorMobileLayoutToggled","isToolConvertable","tool","direction","conversionProp","isBlockConvertable","isSameBlockData","data1","data2","propName","propValue","getConvertibleToolsForBlock","allBlockTools","blockData","blockTool","actualToolboxItems","toolboxItem","areBlocksMergeable","targetBlock","blockToMerge","convertBlockDataToString","conversionConfig","exportProp","convertStringToBlockData","stringToImport","targetToolConfig","importProp","PopoverItemType","BlockToolAPI","Block","_.generateBlockId","readOnly","tunesData","eventBus","mutationsOrInputEvent","isManuallyDispatched","isInputEventHandler","shouldFireUpdate","record","inputs","savedObject","_.isEmpty","_.isFunction","emptyText","emptyMedia","mediaTags","fakeCursorWillBeAdded","fakeCursorWillBeRemoved","_a","_b","params","e","extractedBlock","name","tune","measuringStart","measuringEnd","finishedExtraction","error","isValid","toolTunesPopoverParams","commonTunesPopoverParams","tunesDefinedInTool","tuneInstance","tuneConfig","toolboxSettings","toolboxItems","item","contentNode","pluginsContent","wrappedContentNode","payload","mutations","newToolElement","BlocksAPI","needToFocus","replace","insertedBlock","toolName","tunes","BlockManager","updatedBlock","newType","dataOverrides","Tools","blockToConvert","originalBlockTool","targetBlockTool","originalBlockConvertable","targetBlockConvertable","newBlock","unsupportedBlockTypes","blocks","blocksToInsert","fromIndex","toIndex","status","_.logLabeled","blockIndex","_.deprecationAssert","resolveBlock","attribute","editor","CaretAPI","position","blockOrIdOrIndex","atEnd","EventsAPI","I18nAPI","isTune","I18nInternal","API","InlineToolbarAPI","ListenersAPI","useCapture","module","n","o","t","r","a","f","d","u","l","h","c","p","b","m","x","y","_","g","Notifier","notifier","NotifierAPI","ReadOnlyAPI","getIsEnabled","factory","this","HTMLJanitor","tagDefinitions","tags","validConfigValues","k","blockElementNames","isBlockElement","inlineElementNames","isInlineElement","html","sandbox","document","parentNode","createTreeWalker","isInline","containsBlockElement","isNotTopContainer","isNestedBlockElement","nodeName","allowedAttrs","getAllowedAttrs","isInvalid","shouldRejectNode","attr","shouldRejectAttr","sanitizeBlocks","blocksData","sanitizeConfig","toolConfig","deepSanitize","clean","taintString","customConfig","sanitizerConfig","dataToSanitize","rules","cleanArray","_.isObject","cleanObject","cleanOneItem","ruleForItem","arrayItem","cleanData","fieldName","currentIterationItem","isRule","rule","_.isBoolean","SanitizerAPI","SaverAPI","errorText","SelectionAPI","ToolsAPI","StylesAPI","ToolbarAPI","openingState","lib","prepare","CodeXTooltips","show","hide","skipHidingDelay","onHover","destroy","TooltipAPI","tooltip.show","tooltip.hide","tooltip.onHover","UiAPI","getNamespaces","dict","keyPath","newPath","sectionValue","I18nInternalNS","resolveAliases","obj","aliases","property","aliasedProperty","_DomIterator","nodeList","focusedCssClass","cursorPosition","focusedButtonIndex","_.delay","DomIterator","Flipper","_.keyCodes","items","M","I","D","N","Q","J","X","O","Y","t1","n1","i1","c1","C1","M1","H1","ELEMENT_DELIMITER","MODIFIER_DELIMITER","bem","blockName","elementName","modifier","css","Hint","PopoverItem","itemElement","hintData","PopoverItemDefault","renderParams","isActive","isHidden","IconDotCircle","IconChevronRight","newState","confirmationEl","itemWithOriginalParams","_c","PopoverItemSeparator","PopoverEvent","level","CSSVariables","PopoverItemHtml","controls","PopoverAbstract","itemsRenderParams","itemEl","foundItem","clickedItem","itemsInToggleGroup","SearchInputEvent","SearchInput","placeholder","iconWrapper","IconSearch","query","_PopoverDesktop","focusedItem","isEmptyQuery","isNothingFound","flippableElements","popoverItemCls","nestedPopoverEl","itemOffsetTop","topOffset","popoverRect","scopeElementRect","popoverHeight","popoverPotentialBottomEdge","popoverPotentialTopEdge","bottomEdgeForComparison","popoverWidth","popoverPotentialRightEdge","popoverPotentialLeftEdge","rightEdgeForComparison","popoverClone","searchElement","isDisplayed","__decorateClass","PopoverDesktop","PopoverInline","isHintEnabled","itemOffsetLeft","totalLeftOffset","nestedPopover","_ScrollLocker","ScrollLocker","PopoverHeader","onBackButtonClick","IconChevronLeft","PopoverStatesHistory","PopoverMobile","title","headerEl","BlockSettings","toolTunes","commonTunes","PopoverClass","currentBlock","convertToItems","Caret","Toolbar","IconReplace","Shortcuts","newShortcut","Shortcut","shortcuts","filteredShortcuts","Shortcuts$1","ToolboxEvent","_Toolbox","api","tools","i18nLabels","blockDataOverrides","_.isMobileScreen","toPopoverItem","displaySecondaryLabel","_.capitalize","_.beautifyShortcut","currentBlockIndex","defaultBlockData","_.cacheable","Toolbox","BlockHovered","getKeyboardKeyForCode","code","keyboard","IconCode","IconToolboxAlert","readOnlyEnabled","targetBlockHolder","isMobile","toolbarY","MAX_OFFSET","firstInput","targetBlockHolderRect","firstInputRect","firstInputOffset","isFirstInputFarFromTop","pluginContentOffset","baseline","toolbarActionsHeight","toolbarActionsPaddingBottom","iconBlockName","_d","_e","IconPicture","IconTable","IconChecklist","IconListNumbered","IconListBulleted","IconDelimiter","IconH1","IconH2","IconH3","IconH4","IconH5","IconH6","IconText","IconQuote","withBlockActions","IconPlus","tooltipContent","settingbtn","IconMenu","blockTunesTooltip","blockTunesTooltipEl","slashRealKey","ToolType","ToolType2","UserSettings","CommonInternalSettings","InternalBlockToolSettings","InternalInlineToolSettings","InternalTuneSettings","BaseToolAdapter","constructable","isDefault","isInternal","defaultPlaceholder","toolShortcut","InlineToolbar","needToClose","toolInstance","popoverItems","selectionRect","wrapperOffset","newCoords","tagsConflictsWithSelection","currentSelection","selectedText","instance","renderedTool","shortcutBeautified","toolTitle","commonPopoverItemParams","popoverItem","actions","internalTools","getCaretNodeAndOffset","focusNode","focusOffset","checkContenteditableSliceForEmptiness","contenteditable","fromNode","offsetInsideNode","clonedContent","tempDiv","isCaretAtStartOfInput","firstNode","caretNode","caretOffset","isCaretAtEndOfInput","lastNode","allInputsSelector_1","allInputsSelector$1","allInputsSelector","allowedInputTypes","exports","require$$0","isNativeInput_1","isNativeInput$1","isNativeInput","append_1","append$1","append","blockElements_1","blockElements$1","blockElements","calculateBaseline_1","calculateBaseline$1","baselineY","isContentEditable_1","isContentEditable$1","isContentEditable","canSetCaret_1","canSetCaret$1","canSetCaret","require$$1","notEmpty","copyTextToClipboard","isClass","isPromise","PromiseQueue$1","operation","resolve","reject","containsOnlyInlineElements_1","containsOnlyInlineElements$1","containsOnlyInlineElements","helpers_1","make_1","make$1","make","fragmentToString_1","fragmentToString$1","fragmentToString","fragment","div","getContentLength_1","getContentLength$1","getContentLength","__spreadArray","to","from","pack","ar","getDeepestBlockElements_1","getDeepestBlockElements$1","getDeepestBlockElements","isLineBreakTag_1","isLineBreakTag$1","isLineBreakTag","isSingleTag_1","isSingleTag$1","isSingleTag","getDeepestNode_1","getDeepestNode$1","getDeepestNode","require$$2","findAllInputs_1","findAllInputs$1","findAllInputs","require$$3","isCollapsedWhitespaces_1","isCollapsedWhitespaces$1","isElement_1","isElement$1","isElement","isLeaf_1","isLeaf$1","isLeaf","isNodeEmpty_1","isNodeEmpty$1","isNodeEmpty","isEmpty_1","isEmpty$1","newNode","isFragment_1","isFragment$1","isFragment","isHtmlString","isHTMLString","isHtmlString_1","offset_1","offset$1","prepend_1","prepend$1","prepend","require$$4","require$$5","require$$6","require$$7","require$$8","require$$9","require$$10","require$$11","require$$12","require$$13","require$$14","require$$15","require$$16","require$$17","require$$18","require$$19","require$$20","require$$21","require$$22","require$$23","require$$24","getContenteditableSlice_1","getContenteditableSlice$2","getContenteditableSlice","dom_1","extract","textContent_1","checkContenteditableSliceForEmptiness_1","checkContenteditableSliceForEmptiness$1","focus_1","focus$1","focus","atStart","range_1","createAndFocusTextNode","textNode","isDefinedAndNotNull","childNodes","nodeToFocus","length_1","getCaretNodeAndOffset_1","getCaretNodeAndOffset$1","getRange_1","getRange$1","getRange","isCaretAtEndOfInput_1","isCaretAtEndOfInput$1","isCaretAtStartOfInput_1","isCaretAtStartOfInput$1","save_1","save$1","save","caret","BlockEvents","_.isPrintableKey","BlockSelection","selectionPositionIndex","UI","_.isIosDevice","blockToFocus","caretUtils.isCaretAtStartOfInput","caretUtils.isCaretAtEndOfInput","previousBlock","newCurrentBlock","nextBlock","isFlipperCombination","shouldEnableCBS","toolboxItemSelected","blockSettingsItemSelected","inlineToolbarItemSelected","flippingToolbarItems","Blocks","workingArea","first","second","secondBlock","prevIndex","previousBlockIndex","deleteCount","detail","BlockRemovedMutationType","BlockAddedMutationType","BlockMovedMutationType","BlockChangedMutationType","PromiseQueue","newIndex","existingData","newTool","pasteEvent","blockToMergeData","blockToMergeDataRaw","blockToMergeDataStringified","addLastBlock","firstSelectedBlockIndex","extractedFragment","firstLevelBlock","childNode","parentFirstLevelBlock","editorWrapper","targetToolName","replacingTool","exportedData","newBlockData","needToAddDefaultBlock","queue","affectedBlock","mutationType","detailData","ReadOnly","reason","restoreSelection","RectangleSelection","isKeyboard","indexToInsert","eventKey","fakeClipboard","cleanHTML","textPlain","textHTML","savedData","workingBlock","nodeToSet","offsetToSet","bottom","Selection","innerHeight","lastBlock","selectRange","currentBlockInput","newFragment","inputRemainingText","fragmentText","force","nextInput","currentInput","isAtEnd","blockToNavigate","navigationAllowed","previousInput","caretAtStart","shadowCaret","newRange","lastChild","nodeToSetCaret","CrossBlockSelection","relatedBlock","_.mouseButtons","next","nextBlockIndex","fIndex","lIndex","firstBlock","shouldntSelectFirstBlock","DragNDrop","dropEvent","dragEvent","Paste","selectionChangeDebounceTimeout","modificationsObserverBatchTimeout","ModificationsObserver","eventsToEmit","_Paste","dataTransfer","isDragNDrop","types","editorJSData","plainData","htmlData","toolsTags","isHTML","dataToInsert","needToReplaceCurrentBlock","tagOrSanitizeConfig","tagsOrSanitizeConfigs","toolTags","sanitizationConfig","files","extensions","mimeTypes","_.isValidMimeType","pattern","extension","_.getFileExtension","foundConfig","fileType","fileSubtype","foundExt","ext","foundMimeType","mime","subtype","innerHTML","isBlock","cleanTableHTML","plain","defaultBlock","currentToolSanitizeConfig","substitute","execResult","canReplaceCurrentBlock","destNode","isSubstitutable","containsAnotherToolTags","containsBlockElements","children","elementNodeProcessingResult","reducer","blockTools","toolsDontSupportReadOnly","isInitial","oldState","savedBlocks","pageX","pageY","elemWhereSelectionStart","selectorsToAvoid","startsInsideEditor","startsInSelectorToAvoid","mouseEvent","_.throttle","clientY","overlay","overlayContainer","overlayRectangle","speed","lastOffset","rightPos","leftPos","rectIsOnRighSideOfredactor","rectISOnLeftSideOfRedactor","isSelectedMode","it","centerOfRedactor","elementUnderMouse","blockInCurrentPos","contentElement","centerOfBlock","sameBlock","sizeStack","down","up","undef","blockNumbersIncrease","selectionInDownDirection","selectionInUpDirection","reduction","ind","cmp","Renderer","Saver","extractedData","sanitizedData","allExtractedData","output","BoldInlineTool","IconBold","ItalicInlineTool","IconItalic","LinkInlineTool","IconLink","btn","parentAnchor","anchorTag","IconUnlink","hrefAttr","needFocus","clearSavedSelection","link","isAnchor","isProtocolRelative","ConvertInlineTool","convertibleTools","currentBlockToolboxItem","icon","isDesktop","Stub","IconWarning","infoContainer","subtitle","InlineToolAdapter","BlockTuneAdapter","ToolsCollection","BlockToolAdapter","toolToolboxSettings","userToolboxSettings","toolToolboxEntry","toolRules","baseConfig","ToolsFactory","editorConfig","Constructor","MoveDownTune","IconChevronDown","nextBlockElement","nextBlockCoords","scrollOffset","DeleteTune","IconCross","MoveUpTune","IconChevronUp","currentBlockElement","previousBlockElement","currentBlockCoords","previousBlockCoords","scrollUpOffset","_.deepMerge","sequenceData","_.sequence","inlineTool","Paragraph","notImplementedMethods","toolPreparationList","settings","userTunes","_.debounce","someBlock","_moduleName","moduleClass","styleTagId","styles","blockHoveredEmitted","hoveredBlock","keyDownOnEditor","isMetaKey","hasPointerToBlock","isClickedInsideBlockSettings","isClickedInsideBlockSettingsToggler","doNotProcess","clickedBlock","clickedNode","clientX","ctrlKey","href","validUrl","_.getValidUrl","_.openTab","lastBlockBottomCoord","clickedCoord","focusedElement","closestBlock","handleInputOrFocusChange","Modules","Core","onReady","onFail","_.LogLevels","_.setLogLevel","holderId","promise","diff","moduleName","EditorJS","configuration","fieldsToExport","moduleInstance","destroyTooltip","field","methods","alias"],"mappings":"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","x_google_ignoreList":[0,2,30,34,42,50,75,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,199]}
|