diff --git a/build/codex-editor.js b/build/codex-editor.js index ef93d450..2ef801c4 100644 --- a/build/codex-editor.js +++ b/build/codex-editor.js @@ -103,7 +103,7 @@ return /******/ (function(modules) { // webpackBootstrap /*! no static exports found */ /***/ (function(module, exports) { -module.exports = "\n\n\n \n\n\n\n \n\n\n\n \n\n\n\n \n\n\n\n \n \n \n \n \n\n\n\n \n\n\n\n \n\n\n\n \n\n\n\n \n\n" +module.exports = "\n\n\r\n \r\n\n\n\r\n \r\n\n\n\r\n \r\n\n\n\r\n \r\n\n\n\r\n \r\n \r\n \r\n \r\n \r\n\n\n\r\n \r\n\n\n\r\n \r\n\n\n\r\n \r\n\n\n\r\n \r\n\n" /***/ }), @@ -483,7 +483,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons */ // eslint-disable-next-line var modules = ["api-blocks.ts","api-events.ts","api-listener.ts","api-sanitizer.ts","api-saver.ts","api-selection.ts","api-toolbar.ts","api.ts","block-events.ts","blockManager.js","caret.js","events.js","listeners.js","renderer.js","sanitizer.js","saver.js","toolbar-blockSettings.js","toolbar-inline.ts","toolbar-toolbox.js","toolbar.js","tools.js","ui.js"].map(function (module) { - return __webpack_require__("./src/components/modules sync [^_](api-blocks.ts|api-events.ts|api-listener.ts|api-sanitizer.ts|api-saver.ts|api-selection.ts|api-toolbar.ts|api.ts|block-events.ts|blockManager.js|caret.js|events.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$")("./" + module); + return __webpack_require__("./src/components/modules sync recursive ^\\.\\/.*$")("./" + module); }); /** @@ -1322,6 +1322,7 @@ var Block = function () { this.settings = settings; this.api = apiMethods; this.holder = this.compose(); + this.inputIndex = 0; /** * @type {IBlockTune[]} @@ -1516,6 +1517,29 @@ var Block = function () { get: function get() { return this.save(); } + }, { + key: 'inputs', + get: function get() { + var collection = this.holder.querySelectorAll('[contenteditable], input, textarea'); + + return _.array(collection); + } + }, { + key: 'nextInput', + get: function get() { + var inputs = this.inputs; + + this.inputIndex = Math.min(inputs.length - 1, this.inputIndex + 1); + + return inputs[this.inputIndex]; + } + }, { + key: 'previousInput', + get: function get() { + this.inputIndex = Math.max(0, this.inputIndex - 1); + + return this.inputs[this.inputIndex]; + } /** * is block mergeable @@ -2521,35 +2545,83 @@ module.exports = exports['default']; /***/ }), -/***/ "./src/components/modules sync [^_](api-blocks.ts|api-events.ts|api-listener.ts|api-sanitizer.ts|api-saver.ts|api-selection.ts|api-toolbar.ts|api.ts|block-events.ts|blockManager.js|caret.js|events.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$": -/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\ - !*** ./src/components/modules sync nonrecursive [^_](api-blocks.ts|api-events.ts|api-listener.ts|api-sanitizer.ts|api-saver.ts|api-selection.ts|api-toolbar.ts|api.ts|block-events.ts|blockManager.js|caret.js|events.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$ ***! - \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/ +/***/ "./src/components/modules sync recursive ^\\.\\/.*$": +/*!**********************************************!*\ + !*** ./src/components/modules sync ^\.\/.*$ ***! + \**********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var map = { + "./_anchors": "./src/components/modules/_anchors.js", + "./_anchors.js": "./src/components/modules/_anchors.js", + "./_callbacks": "./src/components/modules/_callbacks.js", + "./_callbacks.js": "./src/components/modules/_callbacks.js", + "./_caret": "./src/components/modules/_caret.js", + "./_caret.js": "./src/components/modules/_caret.js", + "./_content": "./src/components/modules/_content.js", + "./_content.js": "./src/components/modules/_content.js", + "./_destroyer": "./src/components/modules/_destroyer.js", + "./_destroyer.js": "./src/components/modules/_destroyer.js", + "./_notifications": "./src/components/modules/_notifications.js", + "./_notifications.js": "./src/components/modules/_notifications.js", + "./_parser": "./src/components/modules/_parser.js", + "./_parser.js": "./src/components/modules/_parser.js", + "./_paste": "./src/components/modules/_paste.js", + "./_paste.js": "./src/components/modules/_paste.js", + "./_transport": "./src/components/modules/_transport.js", + "./_transport.js": "./src/components/modules/_transport.js", + "./api": "./src/components/modules/api.ts", + "./api-blocks": "./src/components/modules/api-blocks.ts", "./api-blocks.ts": "./src/components/modules/api-blocks.ts", + "./api-events": "./src/components/modules/api-events.ts", "./api-events.ts": "./src/components/modules/api-events.ts", + "./api-listener": "./src/components/modules/api-listener.ts", "./api-listener.ts": "./src/components/modules/api-listener.ts", + "./api-sanitizer": "./src/components/modules/api-sanitizer.ts", "./api-sanitizer.ts": "./src/components/modules/api-sanitizer.ts", + "./api-saver": "./src/components/modules/api-saver.ts", "./api-saver.ts": "./src/components/modules/api-saver.ts", + "./api-selection": "./src/components/modules/api-selection.ts", "./api-selection.ts": "./src/components/modules/api-selection.ts", + "./api-toolbar": "./src/components/modules/api-toolbar.ts", "./api-toolbar.ts": "./src/components/modules/api-toolbar.ts", "./api.ts": "./src/components/modules/api.ts", + "./block-events": "./src/components/modules/block-events.ts", "./block-events.ts": "./src/components/modules/block-events.ts", + "./blockManager": "./src/components/modules/blockManager.js", "./blockManager.js": "./src/components/modules/blockManager.js", + "./caret": "./src/components/modules/caret.js", "./caret.js": "./src/components/modules/caret.js", + "./events": "./src/components/modules/events.js", "./events.js": "./src/components/modules/events.js", + "./listeners": "./src/components/modules/listeners.js", "./listeners.js": "./src/components/modules/listeners.js", + "./renderer": "./src/components/modules/renderer.js", "./renderer.js": "./src/components/modules/renderer.js", + "./sanitizer": "./src/components/modules/sanitizer.js", "./sanitizer.js": "./src/components/modules/sanitizer.js", + "./saver": "./src/components/modules/saver.js", "./saver.js": "./src/components/modules/saver.js", + "./toolbar": "./src/components/modules/toolbar.js", + "./toolbar-blockSettings": "./src/components/modules/toolbar-blockSettings.js", "./toolbar-blockSettings.js": "./src/components/modules/toolbar-blockSettings.js", + "./toolbar-inline": "./src/components/modules/toolbar-inline.ts", "./toolbar-inline.ts": "./src/components/modules/toolbar-inline.ts", + "./toolbar-toolbox": "./src/components/modules/toolbar-toolbox.js", "./toolbar-toolbox.js": "./src/components/modules/toolbar-toolbox.js", "./toolbar.js": "./src/components/modules/toolbar.js", + "./toolbar/inline": "./src/components/modules/toolbar/inline.js", + "./toolbar/inline.js": "./src/components/modules/toolbar/inline.js", + "./toolbar/settings": "./src/components/modules/toolbar/settings.js", + "./toolbar/settings.js": "./src/components/modules/toolbar/settings.js", + "./toolbar/toolbar": "./src/components/modules/toolbar/toolbar.js", + "./toolbar/toolbar.js": "./src/components/modules/toolbar/toolbar.js", + "./toolbar/toolbox": "./src/components/modules/toolbar/toolbox.js", + "./toolbar/toolbox.js": "./src/components/modules/toolbar/toolbox.js", + "./tools": "./src/components/modules/tools.js", "./tools.js": "./src/components/modules/tools.js", + "./ui": "./src/components/modules/ui.js", "./ui.js": "./src/components/modules/ui.js" }; @@ -2572,7 +2644,2765 @@ webpackContext.keys = function webpackContextKeys() { }; webpackContext.resolve = webpackContextResolve; module.exports = webpackContext; -webpackContext.id = "./src/components/modules sync [^_](api-blocks.ts|api-events.ts|api-listener.ts|api-sanitizer.ts|api-saver.ts|api-selection.ts|api-toolbar.ts|api.ts|block-events.ts|blockManager.js|caret.js|events.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$"; +webpackContext.id = "./src/components/modules sync recursive ^\\.\\/.*$"; + +/***/ }), + +/***/ "./src/components/modules/_anchors.js": +/*!********************************************!*\ + !*** ./src/components/modules/_anchors.js ***! + \********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Codex Editor Anchors module + * + * @author Codex Team + * @version 1.0 + */ + +module.exports = function (anchors) { + var editor = codex.editor; + + anchors.input = null; + anchors.currentNode = null; + + anchors.settingsOpened = function (currentBlock) { + anchors.currentNode = currentBlock; + anchors.input.value = anchors.currentNode.dataset.anchor || ''; + }; + + anchors.anchorChanged = function (e) { + var newAnchor = e.target.value = anchors.rusToTranslit(e.target.value); + + anchors.currentNode.dataset.anchor = newAnchor; + + if (newAnchor.trim() !== '') { + anchors.currentNode.classList.add(editor.ui.className.BLOCK_WITH_ANCHOR); + } else { + anchors.currentNode.classList.remove(editor.ui.className.BLOCK_WITH_ANCHOR); + } + }; + + anchors.keyDownOnAnchorInput = function (e) { + if (e.keyCode == editor.core.keys.ENTER) { + e.preventDefault(); + e.stopPropagation(); + + e.target.blur(); + editor.toolbar.settings.close(); + } + }; + + anchors.keyUpOnAnchorInput = function (e) { + if (e.keyCode >= editor.core.keys.LEFT && e.keyCode <= editor.core.keys.DOWN) { + e.stopPropagation(); + } + }; + + anchors.rusToTranslit = function (string) { + var ru = ['А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ь', 'Ы', 'Ь', 'Э', 'Ю', 'Я'], + en = ['A', 'B', 'V', 'G', 'D', 'E', 'E', 'Zh', 'Z', 'I', 'Y', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F', 'H', 'C', 'Ch', 'Sh', 'Sch', '', 'Y', '', 'E', 'Yu', 'Ya']; + + for (var i = 0; i < ru.length; i++) { + string = string.split(ru[i]).join(en[i]); + string = string.split(ru[i].toLowerCase()).join(en[i].toLowerCase()); + } + + string = string.replace(/[^0-9a-zA-Z_]+/g, '-'); + + return string; + }; + + return anchors; +}({}); + +/***/ }), + +/***/ "./src/components/modules/_callbacks.js": +/*!**********************************************!*\ + !*** ./src/components/modules/_callbacks.js ***! + \**********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * @module Codex Editor Callbacks module + * @description Module works with editor added Elements + * + * @author Codex Team + * @version 1.4.0 + */ + +module.exports = function (callbacks) { + var editor = codex.editor; + + /** + * used by UI module + * @description Routes all keydowns on document + * @param {Object} event + */ + callbacks.globalKeydown = function (event) { + switch (event.keyCode) { + case editor.core.keys.ENTER: + enterKeyPressed_(event);break; + } + }; + + /** + * used by UI module + * @description Routes all keydowns on redactors area + * @param {Object} event + */ + callbacks.redactorKeyDown = function (event) { + switch (event.keyCode) { + case editor.core.keys.TAB: + tabKeyPressedOnRedactorsZone_(event);break; + case editor.core.keys.ENTER: + enterKeyPressedOnRedactorsZone_(event);break; + case editor.core.keys.ESC: + escapeKeyPressedOnRedactorsZone_(event);break; + default: + defaultKeyPressedOnRedactorsZone_(event);break; + } + }; + + /** + * used by UI module + * @description Routes all keyup events + * @param {Object} event + */ + callbacks.globalKeyup = function (event) { + switch (event.keyCode) { + case editor.core.keys.UP: + case editor.core.keys.LEFT: + case editor.core.keys.RIGHT: + case editor.core.keys.DOWN: + arrowKeyPressed_(event);break; + } + }; + + /** + * @param {Object} event + * @private + * + * Handles behaviour when tab pressed + * @description if Content is empty show toolbox (if it is closed) or leaf tools + * uses Toolbars toolbox module to handle the situation + */ + var tabKeyPressedOnRedactorsZone_ = function tabKeyPressedOnRedactorsZone_(event) { + /** + * Wait for solution. Would like to know the behaviour + * @todo Add spaces + */ + event.preventDefault(); + + if (!editor.core.isBlockEmpty(editor.content.currentNode)) { + return; + } + + if (!editor.toolbar.opened) { + editor.toolbar.open(); + } + + if (editor.toolbar.opened && !editor.toolbar.toolbox.opened) { + editor.toolbar.toolbox.open(); + } else { + editor.toolbar.toolbox.leaf(); + } + }; + + /** + * Handles global EnterKey Press + * @see enterPressedOnBlock_ + * @param {Object} event + */ + var enterKeyPressed_ = function enterKeyPressed_() { + if (editor.content.editorAreaHightlighted) { + /** + * it means that we lose input index, saved index before is not correct + * therefore we need to set caret when we insert new block + */ + editor.caret.inputIndex = -1; + + enterPressedOnBlock_(); + } + }; + + /** + * Callback for enter key pressing in first-level block area + * + * @param {Event} event + * @private + * + * @description Inserts new block with initial type from settings + */ + var enterPressedOnBlock_ = function enterPressedOnBlock_() { + var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin; + + editor.content.insertBlock({ + type: NEW_BLOCK_TYPE, + block: editor.tools[NEW_BLOCK_TYPE].render() + }, true); + + editor.toolbar.move(); + editor.toolbar.open(); + }; + + /** + * ENTER key handler + * + * @param {Object} event + * @private + * + * @description Makes new block with initial type from settings + */ + var enterKeyPressedOnRedactorsZone_ = function enterKeyPressedOnRedactorsZone_(event) { + if (event.target.contentEditable == 'true') { + /** Update input index */ + editor.caret.saveCurrentInputIndex(); + } + + var currentInputIndex = editor.caret.getCurrentInputIndex() || 0, + workingNode = editor.content.currentNode, + tool = workingNode.dataset.tool, + isEnterPressedOnToolbar = editor.toolbar.opened && editor.toolbar.current && event.target == editor.state.inputs[currentInputIndex]; + + /** The list of tools which needs the default browser behaviour */ + var enableLineBreaks = editor.tools[tool].enableLineBreaks; + + /** This type of block creates when enter is pressed */ + var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin; + + /** + * When toolbar is opened, select tool instead of making new paragraph + */ + if (isEnterPressedOnToolbar) { + event.preventDefault(); + + editor.toolbar.toolbox.toolClicked(event); + + editor.toolbar.close(); + + /** + * Stop other listeners callback executions + */ + event.stopPropagation(); + event.stopImmediatePropagation(); + + return; + } + + /** + * Allow paragraph lineBreaks with shift enter + * Or if shiftkey pressed and enter and enabledLineBreaks, the let new block creation + */ + if (event.shiftKey || enableLineBreaks) { + event.stopPropagation(); + event.stopImmediatePropagation(); + return; + } + + var currentSelection = window.getSelection(), + currentSelectedNode = currentSelection.anchorNode, + caretAtTheEndOfText = editor.caret.position.atTheEnd(), + isTextNodeHasParentBetweenContenteditable = false; + + /** + * Allow making new

in same block by SHIFT+ENTER and forbids to prevent default browser behaviour + */ + if (event.shiftKey && !enableLineBreaks) { + editor.callback.enterPressedOnBlock(editor.content.currentBlock, event); + event.preventDefault(); + return; + } + + /** + * Workaround situation when caret at the Text node that has some wrapper Elements + * Split block cant handle this. + * We need to save default behavior + */ + isTextNodeHasParentBetweenContenteditable = currentSelectedNode && currentSelectedNode.parentNode.contentEditable != 'true'; + + /** + * Split blocks when input has several nodes and caret placed in textNode + */ + if (currentSelectedNode.nodeType == editor.core.nodeTypes.TEXT && !isTextNodeHasParentBetweenContenteditable && !caretAtTheEndOfText) { + event.preventDefault(); + + editor.core.log('Splitting Text node...'); + + editor.content.splitBlock(currentInputIndex); + + /** Show plus button when next input after split is empty*/ + if (!editor.state.inputs[currentInputIndex + 1].textContent.trim()) { + editor.toolbar.showPlusButton(); + } + } else { + var islastNode = editor.content.isLastNode(currentSelectedNode); + + if (islastNode && caretAtTheEndOfText) { + event.preventDefault(); + event.stopPropagation(); + event.stopImmediatePropagation(); + + editor.core.log('ENTER clicked in last textNode. Create new BLOCK'); + + editor.content.insertBlock({ + type: NEW_BLOCK_TYPE, + block: editor.tools[NEW_BLOCK_TYPE].render() + }, true); + + editor.toolbar.move(); + editor.toolbar.open(); + + /** Show plus button with empty block */ + editor.toolbar.showPlusButton(); + } + } + + /** get all inputs after new appending block */ + editor.ui.saveInputs(); + }; + + /** + * Escape behaviour + * @param event + * @private + * + * @description Closes toolbox and toolbar. Prevents default behaviour + */ + var escapeKeyPressedOnRedactorsZone_ = function escapeKeyPressedOnRedactorsZone_(event) { + /** Close all toolbar */ + editor.toolbar.close(); + + /** Close toolbox */ + editor.toolbar.toolbox.close(); + + event.preventDefault(); + }; + + /** + * @param {Event} event + * @private + * + * closes and moves toolbar + */ + var arrowKeyPressed_ = function arrowKeyPressed_(event) { + editor.content.workingNodeChanged(); + + /* Closing toolbar */ + editor.toolbar.close(); + editor.toolbar.move(); + }; + + /** + * @private + * @param {Event} event + * + * @description Closes all opened bars from toolbar. + * If block is mark, clears highlightning + */ + var defaultKeyPressedOnRedactorsZone_ = function defaultKeyPressedOnRedactorsZone_() { + editor.toolbar.close(); + + if (!editor.toolbar.inline.actionsOpened) { + editor.toolbar.inline.close(); + editor.content.clearMark(); + } + }; + + /** + * Handler when clicked on redactors area + * + * @protected + * @param event + * + * @description Detects clicked area. If it is first-level block area, marks as detected and + * on next enter press will be inserted new block + * Otherwise, save carets position (input index) and put caret to the editable zone. + * + * @see detectWhenClickedOnFirstLevelBlockArea_ + * + */ + callbacks.redactorClicked = function (event) { + detectWhenClickedOnFirstLevelBlockArea_(); + + editor.content.workingNodeChanged(event.target); + editor.ui.saveInputs(); + + var selectedText = editor.toolbar.inline.getSelectionText(), + firstLevelBlock; + + /** If selection range took off, then we hide inline toolbar */ + if (selectedText.length === 0) { + editor.toolbar.inline.close(); + } + + /** Update current input index in memory when caret focused into existed input */ + if (event.target.contentEditable == 'true') { + editor.caret.saveCurrentInputIndex(); + } + + if (editor.content.currentNode === null) { + /** + * If inputs in redactor does not exits, then we put input index 0 not -1 + */ + var indexOfLastInput = editor.state.inputs.length > 0 ? editor.state.inputs.length - 1 : 0; + + /** If we have any inputs */ + if (editor.state.inputs.length) { + /** getting firstlevel parent of input */ + firstLevelBlock = editor.content.getFirstLevelBlock(editor.state.inputs[indexOfLastInput]); + } + + /** If input is empty, then we set caret to the last input */ + if (editor.state.inputs.length && editor.state.inputs[indexOfLastInput].textContent === '' && firstLevelBlock.dataset.tool == editor.settings.initialBlockPlugin) { + editor.caret.setToBlock(indexOfLastInput); + } else { + /** Create new input when caret clicked in redactors area */ + var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin; + + editor.content.insertBlock({ + type: NEW_BLOCK_TYPE, + block: editor.tools[NEW_BLOCK_TYPE].render() + }); + + /** If there is no inputs except inserted */ + if (editor.state.inputs.length === 1) { + editor.caret.setToBlock(indexOfLastInput); + } else { + /** Set caret to this appended input */ + editor.caret.setToNextBlock(indexOfLastInput); + } + } + } else { + /** Close all panels */ + editor.toolbar.settings.close(); + editor.toolbar.toolbox.close(); + } + + /** + * Move toolbar and open + */ + editor.toolbar.move(); + editor.toolbar.open(); + + var inputIsEmpty = !editor.content.currentNode.textContent.trim(), + currentNodeType = editor.content.currentNode.dataset.tool, + isInitialType = currentNodeType == editor.settings.initialBlockPlugin; + + /** Hide plus buttons */ + editor.toolbar.hidePlusButton(); + + if (!inputIsEmpty) { + /** Mark current block */ + editor.content.markBlock(); + } + + if (isInitialType && inputIsEmpty) { + /** Show plus button */ + editor.toolbar.showPlusButton(); + } + }; + + /** + * This method allows to define, is caret in contenteditable element or not. + * + * @private + * + * @description Otherwise, if we get TEXT node from range container, that will means we have input index. + * In this case we use default browsers behaviour (if plugin allows that) or overwritten action. + * Therefore, to be sure that we've clicked first-level block area, we should have currentNode, which always + * specifies to the first-level block. Other cases we just ignore. + */ + var detectWhenClickedOnFirstLevelBlockArea_ = function detectWhenClickedOnFirstLevelBlockArea_() { + var selection = window.getSelection(), + anchorNode = selection.anchorNode, + flag = false; + + if (selection.rangeCount === 0) { + editor.content.editorAreaHightlighted = true; + } else { + if (!editor.core.isDomNode(anchorNode)) { + anchorNode = anchorNode.parentNode; + } + + /** Already founded, without loop */ + if (anchorNode.contentEditable == 'true') { + flag = true; + } + + while (anchorNode.contentEditable != 'true') { + anchorNode = anchorNode.parentNode; + + if (anchorNode.contentEditable == 'true') { + flag = true; + } + + if (anchorNode == document.body) { + break; + } + } + + /** If editable element founded, flag is "TRUE", Therefore we return "FALSE" */ + editor.content.editorAreaHightlighted = !flag; + } + }; + + /** + * Toolbar button click handler + * + * @param {Object} event - cursor to the button + * @protected + * + * @description gets current tool and calls render method + */ + callbacks.toolbarButtonClicked = function (event) { + var button = this; + + editor.toolbar.current = button.dataset.type; + + editor.toolbar.toolbox.toolClicked(event); + editor.toolbar.close(); + }; + + /** + * Show or Hide toolbox when plus button is clicked + */ + callbacks.plusButtonClicked = function () { + if (!editor.nodes.toolbox.classList.contains('opened')) { + editor.toolbar.toolbox.open(); + } else { + editor.toolbar.toolbox.close(); + } + }; + + /** + * Block handlers for KeyDown events + * + * @protected + * @param {Object} event + * + * Handles keydowns on block + * @see blockRightOrDownArrowPressed_ + * @see backspacePressed_ + * @see blockLeftOrUpArrowPressed_ + */ + callbacks.blockKeydown = function (event) { + var block = event.target; // event.target is input + + switch (event.keyCode) { + case editor.core.keys.DOWN: + case editor.core.keys.RIGHT: + blockRightOrDownArrowPressed_(event); + break; + + case editor.core.keys.BACKSPACE: + backspacePressed_(block, event); + break; + + case editor.core.keys.UP: + case editor.core.keys.LEFT: + blockLeftOrUpArrowPressed_(event); + break; + } + }; + + /** + * RIGHT or DOWN keydowns on block + * + * @param {Object} event + * @private + * + * @description watches the selection and gets closest editable element. + * Uses method getDeepestTextNodeFromPosition to get the last node of next block + * Sets caret if it is contenteditable + */ + var blockRightOrDownArrowPressed_ = function blockRightOrDownArrowPressed_(event) { + var selection = window.getSelection(), + inputs = editor.state.inputs, + focusedNode = selection.anchorNode, + focusedNodeHolder; + + /** Check for caret existance */ + if (!focusedNode) { + return false; + } + + /** Looking for closest (parent) contentEditable element of focused node */ + while (focusedNode.contentEditable != 'true') { + focusedNodeHolder = focusedNode.parentNode; + focusedNode = focusedNodeHolder; + } + + /** Input index in DOM level */ + var editableElementIndex = 0; + + while (focusedNode != inputs[editableElementIndex]) { + editableElementIndex++; + } + + /** + * Founded contentEditable element doesn't have childs + * Or maybe New created block + */ + if (!focusedNode.textContent) { + editor.caret.setToNextBlock(editableElementIndex); + return; + } + + /** + * Do nothing when caret doesn not reaches the end of last child + */ + var caretInLastChild = false, + caretAtTheEndOfText = false; + + var lastChild, deepestTextnode; + + lastChild = focusedNode.childNodes[focusedNode.childNodes.length - 1]; + + if (editor.core.isDomNode(lastChild)) { + deepestTextnode = editor.content.getDeepestTextNodeFromPosition(lastChild, lastChild.childNodes.length); + } else { + deepestTextnode = lastChild; + } + + caretInLastChild = selection.anchorNode == deepestTextnode; + caretAtTheEndOfText = deepestTextnode.length == selection.anchorOffset; + + if (!caretInLastChild || !caretAtTheEndOfText) { + editor.core.log('arrow [down|right] : caret does not reached the end'); + return false; + } + + editor.caret.setToNextBlock(editableElementIndex); + }; + + /** + * LEFT or UP keydowns on block + * + * @param {Object} event + * @private + * + * watches the selection and gets closest editable element. + * Uses method getDeepestTextNodeFromPosition to get the last node of previous block + * Sets caret if it is contenteditable + * + */ + var blockLeftOrUpArrowPressed_ = function blockLeftOrUpArrowPressed_(event) { + var selection = window.getSelection(), + inputs = editor.state.inputs, + focusedNode = selection.anchorNode, + focusedNodeHolder; + + /** Check for caret existance */ + if (!focusedNode) { + return false; + } + + /** + * LEFT or UP not at the beginning + */ + if (selection.anchorOffset !== 0) { + return false; + } + + /** Looking for parent contentEditable block */ + while (focusedNode.contentEditable != 'true') { + focusedNodeHolder = focusedNode.parentNode; + focusedNode = focusedNodeHolder; + } + + /** Input index in DOM level */ + var editableElementIndex = 0; + + while (focusedNode != inputs[editableElementIndex]) { + editableElementIndex++; + } + + /** + * Do nothing if caret is not at the beginning of first child + */ + var caretInFirstChild = false, + caretAtTheBeginning = false; + + var firstChild, deepestTextnode; + + /** + * Founded contentEditable element doesn't have childs + * Or maybe New created block + */ + if (!focusedNode.textContent) { + editor.caret.setToPreviousBlock(editableElementIndex); + return; + } + + firstChild = focusedNode.childNodes[0]; + + if (editor.core.isDomNode(firstChild)) { + deepestTextnode = editor.content.getDeepestTextNodeFromPosition(firstChild, 0); + } else { + deepestTextnode = firstChild; + } + + caretInFirstChild = selection.anchorNode == deepestTextnode; + caretAtTheBeginning = selection.anchorOffset === 0; + + if (caretInFirstChild && caretAtTheBeginning) { + editor.caret.setToPreviousBlock(editableElementIndex); + } + }; + + /** + * Handles backspace keydown + * + * @param {Element} block + * @param {Object} event + * @private + * + * @description if block is empty, delete the block and set caret to the previous block + * If block is not empty, try to merge two blocks - current and previous + * But it we try'n to remove first block, then we should set caret to the next block, not previous. + * If we removed the last block, create new one + */ + var backspacePressed_ = function backspacePressed_(block, event) { + var currentInputIndex = editor.caret.getCurrentInputIndex(), + range, + selectionLength, + firstLevelBlocksCount; + + if (editor.core.isNativeInput(event.target)) { + /** If input value is empty - remove block */ + if (event.target.value.trim() == '') { + block.remove(); + } else { + return; + } + } + + if (block.textContent.trim()) { + range = editor.content.getRange(); + selectionLength = range.endOffset - range.startOffset; + + if (editor.caret.position.atStart() && !selectionLength && editor.state.inputs[currentInputIndex - 1]) { + editor.content.mergeBlocks(currentInputIndex); + } else { + return; + } + } + + if (!selectionLength) { + block.remove(); + } + + firstLevelBlocksCount = editor.nodes.redactor.childNodes.length; + + /** + * If all blocks are removed + */ + if (firstLevelBlocksCount === 0) { + /** update currentNode variable */ + editor.content.currentNode = null; + + /** Inserting new empty initial block */ + editor.ui.addInitialBlock(); + + /** Updating inputs state after deleting last block */ + editor.ui.saveInputs(); + + /** Set to current appended block */ + window.setTimeout(function () { + editor.caret.setToPreviousBlock(1); + }, 10); + } else { + if (editor.caret.inputIndex !== 0) { + /** Target block is not first */ + editor.caret.setToPreviousBlock(editor.caret.inputIndex); + } else { + /** If we try to delete first block */ + editor.caret.setToNextBlock(editor.caret.inputIndex); + } + } + + editor.toolbar.move(); + + if (!editor.toolbar.opened) { + editor.toolbar.open(); + } + + /** Updating inputs state */ + editor.ui.saveInputs(); + + /** Prevent default browser behaviour */ + event.preventDefault(); + }; + + /** + * used by UI module + * Clicks on block settings button + * + * @param {Object} event + * @protected + * @description Opens toolbar settings + */ + callbacks.showSettingsButtonClicked = function (event) { + /** + * Get type of current block + * It uses to append settings from tool.settings property. + * ... + * Type is stored in data-type attribute on block + */ + var currentToolType = editor.content.currentNode.dataset.tool; + + editor.toolbar.settings.toggle(currentToolType); + + /** Close toolbox when settings button is active */ + editor.toolbar.toolbox.close(); + editor.toolbar.settings.hideRemoveActions(); + }; + + return callbacks; +}({}); + +/***/ }), + +/***/ "./src/components/modules/_caret.js": +/*!******************************************!*\ + !*** ./src/components/modules/_caret.js ***! + \******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Codex Editor Caret Module + * + * @author Codex Team + * @version 1.0 + */ + +module.exports = function (caret) { + var editor = codex.editor; + + /** + * @var {int} InputIndex - editable element in DOM + */ + caret.inputIndex = null; + + /** + * @var {int} offset - caret position in a text node. + */ + caret.offset = null; + + /** + * @var {int} focusedNodeIndex - we get index of child node from first-level block + */ + caret.focusedNodeIndex = null; + + /** + * Creates Document Range and sets caret to the element. + * @protected + * @uses caret.save — if you need to save caret position + * @param {Element} el - Changed Node. + */ + caret.set = function (el, index, offset) { + offset = offset || caret.offset || 0; + index = index || caret.focusedNodeIndex || 0; + + var childs = el.childNodes, + nodeToSet; + + if (childs.length === 0) { + nodeToSet = el; + } else { + nodeToSet = childs[index]; + } + + /** If Element is INPUT */ + if (el.contentEditable != 'true') { + el.focus(); + return; + } + + if (editor.core.isDomNode(nodeToSet)) { + nodeToSet = editor.content.getDeepestTextNodeFromPosition(nodeToSet, nodeToSet.childNodes.length); + } + + var range = document.createRange(), + selection = window.getSelection(); + + window.setTimeout(function () { + range.setStart(nodeToSet, offset); + range.setEnd(nodeToSet, offset); + + selection.removeAllRanges(); + selection.addRange(range); + + editor.caret.saveCurrentInputIndex(); + }, 20); + }; + + /** + * @protected + * Updates index of input and saves it in caret object + */ + caret.saveCurrentInputIndex = function () { + /** Index of Input that we paste sanitized content */ + var selection = window.getSelection(), + inputs = editor.state.inputs, + focusedNode = selection.anchorNode, + focusedNodeHolder; + + if (!focusedNode) { + return; + } + + /** Looking for parent contentEditable block */ + while (focusedNode.contentEditable != 'true') { + focusedNodeHolder = focusedNode.parentNode; + focusedNode = focusedNodeHolder; + } + + /** Input index in DOM level */ + var editableElementIndex = 0; + + while (focusedNode != inputs[editableElementIndex]) { + editableElementIndex++; + } + + caret.inputIndex = editableElementIndex; + }; + + /** + * Returns current input index (caret object) + */ + caret.getCurrentInputIndex = function () { + return caret.inputIndex; + }; + + /** + * @param {int} index - index of first-level block after that we set caret into next input + */ + caret.setToNextBlock = function (index) { + var inputs = editor.state.inputs, + nextInput = inputs[index + 1]; + + if (!nextInput) { + editor.core.log('We are reached the end'); + return; + } + + /** + * When new Block created or deleted content of input + * We should add some text node to set caret + */ + if (!nextInput.childNodes.length) { + var emptyTextElement = document.createTextNode(''); + + nextInput.appendChild(emptyTextElement); + } + + editor.caret.inputIndex = index + 1; + editor.caret.set(nextInput, 0, 0); + editor.content.workingNodeChanged(nextInput); + }; + + /** + * @param {int} index - index of target input. + * Sets caret to input with this index + */ + caret.setToBlock = function (index) { + var inputs = editor.state.inputs, + targetInput = inputs[index]; + + if (!targetInput) { + return; + } + + /** + * When new Block created or deleted content of input + * We should add some text node to set caret + */ + if (!targetInput.childNodes.length) { + var emptyTextElement = document.createTextNode(''); + + targetInput.appendChild(emptyTextElement); + } + + editor.caret.inputIndex = index; + editor.caret.set(targetInput, 0, 0); + editor.content.workingNodeChanged(targetInput); + }; + + /** + * @param {int} index - index of input + */ + caret.setToPreviousBlock = function (index) { + index = index || 0; + + var inputs = editor.state.inputs, + previousInput = inputs[index - 1], + lastChildNode, + lengthOfLastChildNode, + emptyTextElement; + + if (!previousInput) { + editor.core.log('We are reached first node'); + return; + } + + lastChildNode = editor.content.getDeepestTextNodeFromPosition(previousInput, previousInput.childNodes.length); + lengthOfLastChildNode = lastChildNode.length; + + /** + * When new Block created or deleted content of input + * We should add some text node to set caret + */ + if (!previousInput.childNodes.length) { + emptyTextElement = document.createTextNode(''); + previousInput.appendChild(emptyTextElement); + } + editor.caret.inputIndex = index - 1; + editor.caret.set(previousInput, previousInput.childNodes.length - 1, lengthOfLastChildNode); + editor.content.workingNodeChanged(inputs[index - 1]); + }; + + caret.position = { + + atStart: function atStart() { + var selection = window.getSelection(), + anchorOffset = selection.anchorOffset, + anchorNode = selection.anchorNode, + firstLevelBlock = editor.content.getFirstLevelBlock(anchorNode), + pluginsRender = firstLevelBlock.childNodes[0]; + + if (!editor.core.isDomNode(anchorNode)) { + anchorNode = anchorNode.parentNode; + } + + var isFirstNode = anchorNode === pluginsRender.childNodes[0], + isOffsetZero = anchorOffset === 0; + + return isFirstNode && isOffsetZero; + }, + + atTheEnd: function atTheEnd() { + var selection = window.getSelection(), + anchorOffset = selection.anchorOffset, + anchorNode = selection.anchorNode; + + /** Caret is at the end of input */ + return !anchorNode || !anchorNode.length || anchorOffset === anchorNode.length; + } + }; + + /** + * Inserts node at the caret location + * @param {HTMLElement|DocumentFragment} node + */ + caret.insertNode = function (node) { + var selection, + range, + lastNode = node; + + if (node.nodeType == editor.core.nodeTypes.DOCUMENT_FRAGMENT) { + lastNode = node.lastChild; + } + + selection = window.getSelection(); + + range = selection.getRangeAt(0); + range.deleteContents(); + + range.insertNode(node); + + range.setStartAfter(lastNode); + range.collapse(true); + + selection.removeAllRanges(); + selection.addRange(range); + }; + + return caret; +}({}); + +/***/ }), + +/***/ "./src/components/modules/_content.js": +/*!********************************************!*\ + !*** ./src/components/modules/_content.js ***! + \********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * Codex Editor Content Module + * Works with DOM + * + * @class Content + * @classdesc Class works provides COdex Editor appearance logic + * + * @author Codex Team + * @version 2.0.0 + */ + +var _dom = __webpack_require__(/*! ../dom */ "./src/components/dom.js"); + +var _dom2 = _interopRequireDefault(_dom); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +module.exports = function () { + _createClass(Content, null, [{ + key: 'name', + + /** + * Module key name + * @returns {string} + */ + get: function get() { + return 'Content'; + } + + /** + * @constructor + * + * @param {EditorConfig} config + */ + + }]); + + function Content(config) { + _classCallCheck(this, Content); + + this.config = config; + this.Editor = null; + + this.CSS = { + block: 'ce-block', + content: 'ce-block__content', + stretched: 'ce-block--stretched', + highlighted: 'ce-block--highlighted' + }; + + this._currentNode = null; + this._currentIndex = 0; + } + + /** + * Editor modules setter + * @param {object} Editor + */ + + + _createClass(Content, [{ + key: 'composeBlock_', + + + /** + * @private + * @param pluginHTML + * @param {Boolean} isStretched - make stretched block or not + * + * @description adds necessary information to wrap new created block by first-level holder + */ + value: function composeBlock_(pluginHTML) { + var isStretched = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var block = _dom2.default.make('DIV', this.CSS.block), + blockContent = _dom2.default.make('DIV', this.CSS.content); + + blockContent.appendChild(pluginHTML); + block.appendChild(blockContent); + + if (isStretched) { + blockContent.classList.add(this.CSS.stretched); + } + + block.dataset.toolId = this._currentIndex++; + + return block; + } + }, { + key: 'getFirstLevelBlock', + + + /** + * Finds first-level block + * @description looks for first-level block. + * gets parent while node is not first-level + * + * @param {Element} node - selected or clicked in redactors area node + * @protected + * + */ + value: function getFirstLevelBlock(node) { + if (!_dom2.default.isElement(node)) { + node = node.parentNode; + } + + if (node === this.Editor.ui.nodes.redactor || node === document.body) { + return null; + } else { + while (node.classList && !node.classList.contains(this.CSS.block)) { + node = node.parentNode; + } + + return node; + } + } + }, { + key: 'insertBlock', + + + /** + * Insert new block to working area + * + * @param {HTMLElement} tool + * + * @returns {Number} tool index + * + */ + value: function insertBlock(tool) { + var newBlock = this.composeBlock_(tool); + + if (this.currentNode) { + this.currentNode.insertAdjacentElement('afterend', newBlock); + } else { + /** + * If redactor is empty, append as first child + */ + this.Editor.ui.nodes.redactor.appendChild(newBlock); + } + + /** + * Set new node as current + */ + this.currentNode = newBlock; + + return newBlock.dataset.toolId; + } + }, { + key: 'state', + set: function set(Editor) { + this.Editor = Editor; + } + + /** + * Get current working node + * + * @returns {null|HTMLElement} + */ + + }, { + key: 'currentNode', + get: function get() { + return this._currentNode; + } + + /** + * Set working node. Working node should be first level block, so we find it before set one to _currentNode property + * + * @param {HTMLElement} node + */ + , + set: function set(node) { + var firstLevelBlock = this.getFirstLevelBlock(node); + + this._currentNode = firstLevelBlock; + } + }]); + + return Content; +}(); + +// module.exports = (function (content) { +// +// let editor = codex.editor; +// +// /** +// * Links to current active block +// * @type {null | Element} +// */ +// content.currentNode = null; +// +// /** +// * clicked in redactor area +// * @type {null | Boolean} +// */ +// content.editorAreaHightlighted = null; +// +// /** +// * @deprecated +// * Synchronizes redactor with original textarea +// */ +// content.sync = function () { +// +// editor.core.log('syncing...'); +// +// /** +// * Save redactor content to editor.state +// */ +// editor.state.html = editor.nodes.redactor.innerHTML; +// +// }; +// +// /** +// * Appends background to the block +// * +// * @description add CSS class to highlight visually first-level block area +// */ +// content.markBlock = function () { +// +// editor.content.currentNode.classList.add(editor.ui.className.BLOCK_HIGHLIGHTED); +// +// }; +// +// /** +// * Clear background +// * +// * @description clears styles that highlights block +// */ +// content.clearMark = function () { +// +// if (editor.content.currentNode) { +// +// editor.content.currentNode.classList.remove(editor.ui.className.BLOCK_HIGHLIGHTED); +// +// } +// +// }; +// +// /** +// * Finds first-level block +// * +// * @param {Element} node - selected or clicked in redactors area node +// * @protected +// * +// * @description looks for first-level block. +// * gets parent while node is not first-level +// */ +// content.getFirstLevelBlock = function (node) { +// +// if (!editor.core.isDomNode(node)) { +// +// node = node.parentNode; +// +// } +// +// if (node === editor.nodes.redactor || node === document.body) { +// +// return null; +// +// } else { +// +// while(!node.classList.contains(editor.ui.className.BLOCK_CLASSNAME)) { +// +// node = node.parentNode; +// +// } +// +// return node; +// +// } +// +// }; +// +// /** +// * Trigger this event when working node changed +// * @param {Element} targetNode - first-level of this node will be current +// * @protected +// * +// * @description If targetNode is first-level then we set it as current else we look for parents to find first-level +// */ +// content.workingNodeChanged = function (targetNode) { +// +// /** Clear background from previous marked block before we change */ +// editor.content.clearMark(); +// +// if (!targetNode) { +// +// return; +// +// } +// +// content.currentNode = content.getFirstLevelBlock(targetNode); +// +// }; +// +// /** +// * Replaces one redactor block with another +// * @protected +// * @param {Element} targetBlock - block to replace. Mostly currentNode. +// * @param {Element} newBlock +// * @param {string} newBlockType - type of new block; we need to store it to data-attribute +// * +// * [!] Function does not saves old block content. +// * You can get it manually and pass with newBlock.innerHTML +// */ +// content.replaceBlock = function (targetBlock, newBlock) { +// +// if (!targetBlock || !newBlock) { +// +// editor.core.log('replaceBlock: missed params'); +// return; +// +// } +// +// /** If target-block is not a frist-level block, then we iterate parents to find it */ +// while(!targetBlock.classList.contains(editor.ui.className.BLOCK_CLASSNAME)) { +// +// targetBlock = targetBlock.parentNode; +// +// } +// +// /** Replacing */ +// editor.nodes.redactor.replaceChild(newBlock, targetBlock); +// +// /** +// * Set new node as current +// */ +// editor.content.workingNodeChanged(newBlock); +// +// /** +// * Add block handlers +// */ +// editor.ui.addBlockHandlers(newBlock); +// +// /** +// * Save changes +// */ +// editor.ui.saveInputs(); +// +// }; +// +// /** +// * @protected +// * +// * Inserts new block to redactor +// * Wrapps block into a DIV with BLOCK_CLASSNAME class +// * +// * @param blockData {object} +// * @param blockData.block {Element} element with block content +// * @param blockData.type {string} block plugin +// * @param needPlaceCaret {bool} pass true to set caret in new block +// * +// */ +// content.insertBlock = function ( blockData, needPlaceCaret ) { +// +// var workingBlock = editor.content.currentNode, +// newBlockContent = blockData.block, +// blockType = blockData.type, +// isStretched = blockData.stretched; +// +// var newBlock = composeNewBlock_(newBlockContent, blockType, isStretched); +// +// if (workingBlock) { +// +// editor.core.insertAfter(workingBlock, newBlock); +// +// } else { +// +// /** +// * If redactor is empty, append as first child +// */ +// editor.nodes.redactor.appendChild(newBlock); +// +// } +// +// /** +// * Block handler +// */ +// editor.ui.addBlockHandlers(newBlock); +// +// /** +// * Set new node as current +// */ +// editor.content.workingNodeChanged(newBlock); +// +// /** +// * Save changes +// */ +// editor.ui.saveInputs(); +// +// +// if ( needPlaceCaret ) { +// +// /** +// * If we don't know input index then we set default value -1 +// */ +// var currentInputIndex = editor.caret.getCurrentInputIndex() || -1; +// +// +// if (currentInputIndex == -1) { +// +// +// var editableElement = newBlock.querySelector('[contenteditable]'), +// emptyText = document.createTextNode(''); +// +// editableElement.appendChild(emptyText); +// editor.caret.set(editableElement, 0, 0); +// +// editor.toolbar.move(); +// editor.toolbar.showPlusButton(); +// +// +// } else { +// +// if (currentInputIndex === editor.state.inputs.length - 1) +// return; +// +// /** Timeout for browsers execution */ +// window.setTimeout(function () { +// +// /** Setting to the new input */ +// editor.caret.setToNextBlock(currentInputIndex); +// editor.toolbar.move(); +// editor.toolbar.open(); +// +// }, 10); +// +// } +// +// } +// +// /** +// * Block is inserted, wait for new click that defined focusing on editors area +// * @type {boolean} +// */ +// content.editorAreaHightlighted = false; +// +// }; +// +// /** +// * Replaces blocks with saving content +// * @protected +// * @param {Element} noteToReplace +// * @param {Element} newNode +// * @param {Element} blockType +// */ +// content.switchBlock = function (blockToReplace, newBlock, tool) { +// +// tool = tool || editor.content.currentNode.dataset.tool; +// var newBlockComposed = composeNewBlock_(newBlock, tool); +// +// /** Replacing */ +// editor.content.replaceBlock(blockToReplace, newBlockComposed); +// +// /** Save new Inputs when block is changed */ +// editor.ui.saveInputs(); +// +// }; +// +// /** +// * Iterates between child noted and looking for #text node on deepest level +// * @protected +// * +// * @param {Element} block - node where find +// * @param {int} postiton - starting postion +// * Example: childNodex.length to find from the end +// * or 0 to find from the start +// * @return {Text} block +// * @uses DFS +// */ +// content.getDeepestTextNodeFromPosition = function (block, position) { +// +// /** +// * Clear Block from empty and useless spaces with trim. +// * Such nodes we should remove +// */ +// var blockChilds = block.childNodes, +// index, +// node, +// text; +// +// for(index = 0; index < blockChilds.length; index++) { +// +// node = blockChilds[index]; +// +// if (node.nodeType == editor.core.nodeTypes.TEXT) { +// +// text = node.textContent.trim(); +// +// /** Text is empty. We should remove this child from node before we start DFS +// * decrease the quantity of childs. +// */ +// if (text === '') { +// +// block.removeChild(node); +// position--; +// +// } +// +// } +// +// } +// +// if (block.childNodes.length === 0) { +// +// return document.createTextNode(''); +// +// } +// +// /** Setting default position when we deleted all empty nodes */ +// if ( position < 0 ) +// position = 1; +// +// var lookingFromStart = false; +// +// /** For looking from START */ +// if (position === 0) { +// +// lookingFromStart = true; +// position = 1; +// +// } +// +// while ( position ) { +// +// /** initial verticle of node. */ +// if ( lookingFromStart ) { +// +// block = block.childNodes[0]; +// +// } else { +// +// block = block.childNodes[position - 1]; +// +// } +// +// if ( block.nodeType == editor.core.nodeTypes.TAG ) { +// +// position = block.childNodes.length; +// +// } else if (block.nodeType == editor.core.nodeTypes.TEXT ) { +// +// position = 0; +// +// } +// +// } +// +// return block; +// +// }; +// +// /** +// * @private +// * @param {Element} block - current plugins render +// * @param {String} tool - plugins name +// * @param {Boolean} isStretched - make stretched block or not +// * +// * @description adds necessary information to wrap new created block by first-level holder +// */ +// var composeNewBlock_ = function (block, tool, isStretched) { +// +// var newBlock = editor.draw.node('DIV', editor.ui.className.BLOCK_CLASSNAME, {}), +// blockContent = editor.draw.node('DIV', editor.ui.className.BLOCK_CONTENT, {}); +// +// blockContent.appendChild(block); +// newBlock.appendChild(blockContent); +// +// if (isStretched) { +// +// blockContent.classList.add(editor.ui.className.BLOCK_STRETCHED); +// +// } +// +// newBlock.dataset.tool = tool; +// return newBlock; +// +// }; +// +// /** +// * Returns Range object of current selection +// * @protected +// */ +// content.getRange = function () { +// +// var selection = window.getSelection().getRangeAt(0); +// +// return selection; +// +// }; +// +// /** +// * Divides block in two blocks (after and before caret) +// * +// * @protected +// * @param {int} inputIndex - target input index +// * +// * @description splits current input content to the separate blocks +// * When enter is pressed among the words, that text will be splited. +// */ +// content.splitBlock = function (inputIndex) { +// +// var selection = window.getSelection(), +// anchorNode = selection.anchorNode, +// anchorNodeText = anchorNode.textContent, +// caretOffset = selection.anchorOffset, +// textBeforeCaret, +// textNodeBeforeCaret, +// textAfterCaret, +// textNodeAfterCaret; +// +// var currentBlock = editor.content.currentNode.querySelector('[contentEditable]'); +// +// +// textBeforeCaret = anchorNodeText.substring(0, caretOffset); +// textAfterCaret = anchorNodeText.substring(caretOffset); +// +// textNodeBeforeCaret = document.createTextNode(textBeforeCaret); +// +// if (textAfterCaret) { +// +// textNodeAfterCaret = document.createTextNode(textAfterCaret); +// +// } +// +// var previousChilds = [], +// nextChilds = [], +// reachedCurrent = false; +// +// if (textNodeAfterCaret) { +// +// nextChilds.push(textNodeAfterCaret); +// +// } +// +// for ( var i = 0, child; !!(child = currentBlock.childNodes[i]); i++) { +// +// if ( child != anchorNode ) { +// +// if ( !reachedCurrent ) { +// +// previousChilds.push(child); +// +// } else { +// +// nextChilds.push(child); +// +// } +// +// } else { +// +// reachedCurrent = true; +// +// } +// +// } +// +// /** Clear current input */ +// editor.state.inputs[inputIndex].innerHTML = ''; +// +// /** +// * Append all childs founded before anchorNode +// */ +// var previousChildsLength = previousChilds.length; +// +// for(i = 0; i < previousChildsLength; i++) { +// +// editor.state.inputs[inputIndex].appendChild(previousChilds[i]); +// +// } +// +// editor.state.inputs[inputIndex].appendChild(textNodeBeforeCaret); +// +// /** +// * Append text node which is after caret +// */ +// var nextChildsLength = nextChilds.length, +// newNode = document.createElement('div'); +// +// for(i = 0; i < nextChildsLength; i++) { +// +// newNode.appendChild(nextChilds[i]); +// +// } +// +// newNode = newNode.innerHTML; +// +// /** This type of block creates when enter is pressed */ +// var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin; +// +// /** +// * Make new paragraph with text after caret +// */ +// editor.content.insertBlock({ +// type : NEW_BLOCK_TYPE, +// block : editor.tools[NEW_BLOCK_TYPE].render({ +// text : newNode +// }) +// }, true ); +// +// }; +// +// /** +// * Merges two blocks — current and target +// * If target index is not exist, then previous will be as target +// * +// * @protected +// * @param {int} currentInputIndex +// * @param {int} targetInputIndex +// * +// * @description gets two inputs indexes and merges into one +// */ +// content.mergeBlocks = function (currentInputIndex, targetInputIndex) { +// +// /** If current input index is zero, then prevent method execution */ +// if (currentInputIndex === 0) { +// +// return; +// +// } +// +// var targetInput, +// currentInputContent = editor.state.inputs[currentInputIndex].innerHTML; +// +// if (!targetInputIndex) { +// +// targetInput = editor.state.inputs[currentInputIndex - 1]; +// +// } else { +// +// targetInput = editor.state.inputs[targetInputIndex]; +// +// } +// +// targetInput.innerHTML += currentInputContent; +// +// }; +// +// /** +// * Iterates all right siblings and parents, which has right siblings +// * while it does not reached the first-level block +// * +// * @param {Element} node +// * @return {boolean} +// */ +// content.isLastNode = function (node) { +// +// // console.log('погнали перебор родителей'); +// +// var allChecked = false; +// +// while ( !allChecked ) { +// +// // console.log('Смотрим на %o', node); +// // console.log('Проверим, пустые ли соседи справа'); +// +// if ( !allSiblingsEmpty_(node) ) { +// +// // console.log('Есть непустые соседи. Узел не последний. Выходим.'); +// return false; +// +// } +// +// node = node.parentNode; +// +// /** +// * Проверяем родителей до тех пор, пока не найдем блок первого уровня +// */ +// if ( node.classList.contains(editor.ui.className.BLOCK_CONTENT) ) { +// +// allChecked = true; +// +// } +// +// } +// +// return true; +// +// }; +// +// /** +// * Checks if all element right siblings is empty +// * @param node +// */ +// var allSiblingsEmpty_ = function (node) { +// +// /** +// * Нужно убедиться, что после пустого соседа ничего нет +// */ +// var sibling = node.nextSibling; +// +// while ( sibling ) { +// +// if (sibling.textContent.length) { +// +// return false; +// +// } +// +// sibling = sibling.nextSibling; +// +// } +// +// return true; +// +// }; +// +// /** +// * @public +// * +// * @param {string} htmlData - html content as string +// * @param {string} plainData - plain text +// * @return {string} - html content as string +// */ +// content.wrapTextWithParagraphs = function (htmlData, plainData) { +// +// if (!htmlData.trim()) { +// +// return wrapPlainTextWithParagraphs(plainData); +// +// } +// +// var wrapper = document.createElement('DIV'), +// newWrapper = document.createElement('DIV'), +// i, +// paragraph, +// firstLevelBlocks = ['DIV', 'P'], +// blockTyped, +// node; +// +// /** +// * Make HTML Element to Wrap Text +// * It allows us to work with input data as HTML content +// */ +// wrapper.innerHTML = htmlData; +// paragraph = document.createElement('P'); +// +// for (i = 0; i < wrapper.childNodes.length; i++) { +// +// node = wrapper.childNodes[i]; +// +// blockTyped = firstLevelBlocks.indexOf(node.tagName) != -1; +// +// /** +// * If node is first-levet +// * we add this node to our new wrapper +// */ +// if ( blockTyped ) { +// +// /** +// * If we had splitted inline nodes to paragraph before +// */ +// if ( paragraph.childNodes.length ) { +// +// newWrapper.appendChild(paragraph.cloneNode(true)); +// +// /** empty paragraph */ +// paragraph = null; +// paragraph = document.createElement('P'); +// +// } +// +// newWrapper.appendChild(node.cloneNode(true)); +// +// } else { +// +// /** Collect all inline nodes to one as paragraph */ +// paragraph.appendChild(node.cloneNode(true)); +// +// /** if node is last we should append this node to paragraph and paragraph to new wrapper */ +// if ( i == wrapper.childNodes.length - 1 ) { +// +// newWrapper.appendChild(paragraph.cloneNode(true)); +// +// } +// +// } +// +// } +// +// return newWrapper.innerHTML; +// +// }; +// +// /** +// * Splits strings on new line and wraps paragraphs with

tag +// * @param plainText +// * @returns {string} +// */ +// var wrapPlainTextWithParagraphs = function (plainText) { +// +// if (!plainText) return ''; +// +// return '

' + plainText.split('\n\n').join('

') + '

'; +// +// }; +// +// /** +// * Finds closest Contenteditable parent from Element +// * @param {Element} node element looking from +// * @return {Element} node contenteditable +// */ +// content.getEditableParent = function (node) { +// +// while (node && node.contentEditable != 'true') { +// +// node = node.parentNode; +// +// } +// +// return node; +// +// }; +// +// /** +// * Clear editors content +// * +// * @param {Boolean} all — if true, delete all article data (content, id, etc.) +// */ +// content.clear = function (all) { +// +// editor.nodes.redactor.innerHTML = ''; +// editor.content.sync(); +// editor.ui.saveInputs(); +// if (all) { +// +// editor.state.blocks = {}; +// +// } else if (editor.state.blocks) { +// +// editor.state.blocks.items = []; +// +// } +// +// editor.content.currentNode = null; +// +// }; +// +// /** +// * +// * Load new data to editor +// * If editor is not empty, just append articleData.items +// * +// * @param articleData.items +// */ +// content.load = function (articleData) { +// +// var currentContent = Object.assign({}, editor.state.blocks); +// +// editor.content.clear(); +// +// if (!Object.keys(currentContent).length) { +// +// editor.state.blocks = articleData; +// +// } else if (!currentContent.items) { +// +// currentContent.items = articleData.items; +// editor.state.blocks = currentContent; +// +// } else { +// +// currentContent.items = currentContent.items.concat(articleData.items); +// editor.state.blocks = currentContent; +// +// } +// +// editor.renderer.makeBlocksFromData(); +// +// }; +// +// return content; +// +// })({}); + +/***/ }), + +/***/ "./src/components/modules/_destroyer.js": +/*!**********************************************!*\ + !*** ./src/components/modules/_destroyer.js ***! + \**********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +/** + * Codex Editor Destroyer module + * + * @auhor Codex Team + * @version 1.0 + */ + +module.exports = function (destroyer) { + var editor = codex.editor; + + destroyer.removeNodes = function () { + editor.nodes.wrapper.remove(); + editor.nodes.notifications.remove(); + }; + + destroyer.destroyPlugins = function () { + for (var tool in editor.tools) { + if (typeof editor.tools[tool].destroy === 'function') { + editor.tools[tool].destroy(); + } + } + }; + + destroyer.destroyScripts = function () { + var scripts = document.getElementsByTagName('SCRIPT'); + + for (var i = 0; i < scripts.length; i++) { + if (scripts[i].id.indexOf(editor.scriptPrefix) + 1) { + scripts[i].remove(); + i--; + } + } + }; + + /** + * Delete editor data from webpage. + * You should send settings argument with boolean flags: + * @param settings.ui- remove redactor event listeners and DOM nodes + * @param settings.scripts - remove redactor scripts from DOM + * @param settings.plugins - remove plugin's objects + * @param settings.core - remove editor core. You can remove core only if UI and scripts flags is true + * } + * + */ + destroyer.destroy = function (settings) { + if (!settings || (typeof settings === 'undefined' ? 'undefined' : _typeof(settings)) !== 'object') { + return; + } + + if (settings.ui) { + destroyer.removeNodes(); + editor.listeners.removeAll(); + } + + if (settings.scripts) { + destroyer.destroyScripts(); + } + + if (settings.plugins) { + destroyer.destroyPlugins(); + } + + if (settings.ui && settings.scripts && settings.core) { + delete codex.editor; + } + }; + + return destroyer; +}({}); + +/***/ }), + +/***/ "./src/components/modules/_notifications.js": +/*!**************************************************!*\ + !*** ./src/components/modules/_notifications.js ***! + \**************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Codex Editor Notification Module + * + * @author Codex Team + * @version 1.0 + */ + +module.exports = function (notifications) { + var editor = codex.editor; + + var queue = []; + + var addToQueue = function addToQueue(settings) { + queue.push(settings); + + var index = 0; + + while (index < queue.length && queue.length > 5) { + if (queue[index].type == 'confirm' || queue[index].type == 'prompt') { + index++; + continue; + } + + queue[index].close(); + queue.splice(index, 1); + } + }; + + notifications.createHolder = function () { + var holder = editor.draw.node('DIV', 'cdx-notifications-block'); + + editor.nodes.notifications = document.body.appendChild(holder); + + return holder; + }; + + /** + * Error notificator. Shows block with message + * @protected + */ + notifications.errorThrown = function (errorMsg, event) { + editor.notifications.notification({ message: 'This action is not available currently', type: event.type }); + }; + + /** + * + * Appends notification + * + * settings = { + * type - notification type (reserved types: alert, confirm, prompt). Just add class 'cdx-notification-'+type + * message - notification message + * okMsg - confirm button text (default - 'Ok') + * cancelBtn - cancel button text (default - 'Cancel'). Only for confirm and prompt types + * confirm - function-handler for ok button click + * cancel - function-handler for cancel button click. Only for confirm and prompt types + * time - time (in seconds) after which notification will close (default - 10s) + * } + * + * @param settings + */ + notifications.notification = function (constructorSettings) { + /** Private vars and methods */ + var notification = null, + cancel = null, + type = null, + confirm = null, + inputField = null; + + var confirmHandler = function confirmHandler() { + close(); + + if (typeof confirm !== 'function') { + return; + } + + if (type == 'prompt') { + confirm(inputField.value); + return; + } + + confirm(); + }; + + var cancelHandler = function cancelHandler() { + close(); + + if (typeof cancel !== 'function') { + return; + } + + cancel(); + }; + + /** Public methods */ + function create(settings) { + if (!(settings && settings.message)) { + editor.core.log('Can\'t create notification. Message is missed'); + return; + } + + settings.type = settings.type || 'alert'; + settings.time = settings.time * 1000 || 10000; + + var wrapper = editor.draw.node('DIV', 'cdx-notification'), + message = editor.draw.node('DIV', 'cdx-notification__message'), + input = editor.draw.node('INPUT', 'cdx-notification__input'), + okBtn = editor.draw.node('SPAN', 'cdx-notification__ok-btn'), + cancelBtn = editor.draw.node('SPAN', 'cdx-notification__cancel-btn'); + + message.textContent = settings.message; + okBtn.textContent = settings.okMsg || 'ОК'; + cancelBtn.textContent = settings.cancelMsg || 'Отмена'; + + editor.listeners.add(okBtn, 'click', confirmHandler); + editor.listeners.add(cancelBtn, 'click', cancelHandler); + + wrapper.appendChild(message); + + if (settings.type == 'prompt') { + wrapper.appendChild(input); + } + + wrapper.appendChild(okBtn); + + if (settings.type == 'prompt' || settings.type == 'confirm') { + wrapper.appendChild(cancelBtn); + } + + wrapper.classList.add('cdx-notification-' + settings.type); + wrapper.dataset.type = settings.type; + + notification = wrapper; + type = settings.type; + confirm = settings.confirm; + cancel = settings.cancel; + inputField = input; + + if (settings.type != 'prompt' && settings.type != 'confirm') { + window.setTimeout(close, settings.time); + } + }; + + /** + * Show notification block + */ + function send() { + editor.nodes.notifications.appendChild(notification); + inputField.focus(); + + editor.nodes.notifications.classList.add('cdx-notification__notification-appending'); + + window.setTimeout(function () { + editor.nodes.notifications.classList.remove('cdx-notification__notification-appending'); + }, 100); + + addToQueue({ type: type, close: close }); + }; + + /** + * Remove notification block + */ + function close() { + notification.remove(); + }; + + if (constructorSettings) { + create(constructorSettings); + send(); + } + + return { + create: create, + send: send, + close: close + }; + }; + + notifications.clear = function () { + editor.nodes.notifications.innerHTML = ''; + queue = []; + }; + + return notifications; +}({}); + +/***/ }), + +/***/ "./src/components/modules/_parser.js": +/*!*******************************************!*\ + !*** ./src/components/modules/_parser.js ***! + \*******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Codex Editor Parser Module + * + * @author Codex Team + * @version 1.1 + */ + +module.exports = function (parser) { + var editor = codex.editor; + + /** inserting text */ + parser.insertPastedContent = function (blockType, tag) { + editor.content.insertBlock({ + type: blockType.type, + block: blockType.render({ + text: tag.innerHTML + }) + }); + }; + + /** + * Check DOM node for display style: separated block or child-view + */ + parser.isFirstLevelBlock = function (node) { + return node.nodeType == editor.core.nodeTypes.TAG && node.classList.contains(editor.ui.className.BLOCK_CLASSNAME); + }; + + return parser; +}({}); + +/***/ }), + +/***/ "./src/components/modules/_paste.js": +/*!******************************************!*\ + !*** ./src/components/modules/_paste.js ***! + \******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Codex Editor Paste module + * + * @author Codex Team + * @version 1.1.1 + */ + +module.exports = function (paste) { + var editor = codex.editor; + + var patterns = []; + + paste.prepare = function () { + var tools = editor.tools; + + for (var tool in tools) { + if (!tools[tool].renderOnPastePatterns || !Array.isArray(tools[tool].renderOnPastePatterns)) { + continue; + } + + tools[tool].renderOnPastePatterns.map(function (pattern) { + patterns.push(pattern); + }); + } + + return Promise.resolve(); + }; + + /** + * Saves data + * @param event + */ + paste.pasted = function (event) { + var clipBoardData = event.clipboardData || window.clipboardData, + content = clipBoardData.getData('Text'); + + var result = analize(content); + + if (result) { + event.preventDefault(); + event.stopImmediatePropagation(); + } + + return result; + }; + + /** + * Analizes pated string and calls necessary method + */ + + var analize = function analize(string) { + var result = false, + content = editor.content.currentNode, + plugin = content.dataset.tool; + + patterns.map(function (pattern) { + var execArray = pattern.regex.exec(string), + match = execArray && execArray[0]; + + if (match && match === string.trim()) { + /** current block is not empty */ + if (content.textContent.trim() && plugin == editor.settings.initialBlockPlugin) { + pasteToNewBlock_(); + } + + pattern.callback(string, pattern); + result = true; + } + }); + + return result; + }; + + var pasteToNewBlock_ = function pasteToNewBlock_() { + /** Create new initial block */ + editor.content.insertBlock({ + + type: editor.settings.initialBlockPlugin, + block: editor.tools[editor.settings.initialBlockPlugin].render({ + text: '' + }) + + }, false); + }; + + /** + * This method prevents default behaviour. + * + * @param {Object} event + * @protected + * + * @description We get from clipboard pasted data, sanitize, make a fragment that contains of this sanitized nodes. + * Firstly, we need to memorize the caret position. We can do that by getting the range of selection. + * After all, we insert clear fragment into caret placed position. Then, we should move the caret to the last node + */ + paste.blockPasteCallback = function (event) { + if (!needsToHandlePasteEvent(event.target)) { + return; + } + + /** Prevent default behaviour */ + event.preventDefault(); + + /** get html pasted data - dirty data */ + var htmlData = event.clipboardData.getData('text/html'), + plainData = event.clipboardData.getData('text/plain'); + + /** Temporary DIV that is used to work with text's paragraphs as DOM-elements*/ + var paragraphs = editor.draw.node('DIV', '', {}), + cleanData, + wrappedData; + + /** Create fragment, that we paste to range after proccesing */ + cleanData = editor.sanitizer.clean(htmlData); + + /** + * We wrap pasted text with

tags to split it logically + * @type {string} + */ + wrappedData = editor.content.wrapTextWithParagraphs(cleanData, plainData); + paragraphs.innerHTML = wrappedData; + + /** + * If there only one paragraph, just insert in at the caret location + */ + if (paragraphs.childNodes.length == 1) { + emulateUserAgentBehaviour(paragraphs.firstChild); + return; + } + + insertPastedParagraphs(paragraphs.childNodes); + }; + + /** + * Checks if we should handle paste event on block + * @param block + * + * @return {boolean} + */ + var needsToHandlePasteEvent = function needsToHandlePasteEvent(block) { + /** If area is input or textarea then allow default behaviour */ + if (editor.core.isNativeInput(block)) { + return false; + } + + var editableParent = editor.content.getEditableParent(block); + + /** Allow paste when event target placed in Editable element */ + if (!editableParent) { + return false; + } + + return true; + }; + + /** + * Inserts new initial plugin blocks with data in paragraphs + * + * @param {Array} paragraphs - array of paragraphs (

) whit content, that should be inserted + */ + var insertPastedParagraphs = function insertPastedParagraphs(paragraphs) { + var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin, + currentNode = editor.content.currentNode; + + paragraphs.forEach(function (paragraph) { + /** Don't allow empty paragraphs */ + if (editor.core.isBlockEmpty(paragraph)) { + return; + } + + editor.content.insertBlock({ + type: NEW_BLOCK_TYPE, + block: editor.tools[NEW_BLOCK_TYPE].render({ + text: paragraph.innerHTML + }) + }); + + editor.caret.inputIndex++; + }); + + editor.caret.setToPreviousBlock(editor.caret.getCurrentInputIndex() + 1); + + /** + * If there was no data in working node, remove it + */ + if (editor.core.isBlockEmpty(currentNode)) { + currentNode.remove(); + editor.ui.saveInputs(); + } + }; + + /** + * Inserts node content at the caret position + * + * @param {Node} node - DOM node (could be DocumentFragment), that should be inserted at the caret location + */ + var emulateUserAgentBehaviour = function emulateUserAgentBehaviour(node) { + var newNode; + + if (node.childElementCount) { + newNode = document.createDocumentFragment(); + + node.childNodes.forEach(function (current) { + if (!editor.core.isDomNode(current) && current.data.trim() === '') { + return; + } + + newNode.appendChild(current.cloneNode(true)); + }); + } else { + newNode = document.createTextNode(node.textContent); + } + + editor.caret.insertNode(newNode); + }; + + return paste; +}({}); + +/***/ }), + +/***/ "./src/components/modules/_transport.js": +/*!**********************************************!*\ + !*** ./src/components/modules/_transport.js ***! + \**********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * + * Codex.Editor Transport Module + * + * @copyright 2017 Codex-Team + * @version 1.2.0 + */ + +module.exports = function (transport) { + var editor = codex.editor; + + /** + * @private {Object} current XmlHttpRequest instance + */ + var currentRequest = null; + + /** + * @type {null} | {DOMElement} input - keeps input element in memory + */ + transport.input = null; + + /** + * @property {Object} arguments - keep plugin settings and defined callbacks + */ + transport.arguments = null; + + /** + * Prepares input element where will be files + */ + transport.prepare = function () { + var input = editor.draw.node('INPUT', '', { type: 'file' }); + + editor.listeners.add(input, 'change', editor.transport.fileSelected); + editor.transport.input = input; + }; + + /** Clear input when files is uploaded */ + transport.clearInput = function () { + /** Remove old input */ + transport.input = null; + + /** Prepare new one */ + transport.prepare(); + }; + + /** + * Callback for file selection + * @param {Event} event + */ + transport.fileSelected = function () { + var input = this, + i, + files = input.files, + formData = new FormData(); + + if (editor.transport.arguments.multiple === true) { + for (i = 0; i < files.length; i++) { + formData.append('files[]', files[i], files[i].name); + } + } else { + formData.append('files', files[0], files[0].name); + } + + currentRequest = editor.core.ajax({ + type: 'POST', + data: formData, + url: editor.transport.arguments.url, + beforeSend: editor.transport.arguments.beforeSend, + success: editor.transport.arguments.success, + error: editor.transport.arguments.error, + progress: editor.transport.arguments.progress + }); + + /** Clear input */ + transport.clearInput(); + }; + + /** + * Use plugin callbacks + * @protected + * + * @param {Object} args - can have : + * @param {String} args.url - fetch URL + * @param {Function} args.beforeSend - function calls before sending ajax + * @param {Function} args.success - success callback + * @param {Function} args.error - on error handler + * @param {Function} args.progress - xhr onprogress handler + * @param {Boolean} args.multiple - allow select several files + * @param {String} args.accept - adds accept attribute + */ + transport.selectAndUpload = function (args) { + transport.arguments = args; + + if (args.multiple === true) { + transport.input.setAttribute('multiple', 'multiple'); + } + + if (args.accept) { + transport.input.setAttribute('accept', args.accept); + } + + transport.input.click(); + }; + + transport.abort = function () { + currentRequest.abort(); + + currentRequest = null; + }; + + return transport; +}({}); /***/ }), @@ -6931,6 +9761,947 @@ module.exports = exports['default']; /***/ }), +/***/ "./src/components/modules/toolbar/inline.js": +/*!**************************************************!*\ + !*** ./src/components/modules/toolbar/inline.js ***! + \**************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Inline toolbar + * + * Contains from tools: + * Bold, Italic, Underline and Anchor + * + * @author Codex Team + * @version 1.0 + */ + +module.exports = function (inline) { + var editor = codex.editor; + + inline.buttonsOpened = null; + inline.actionsOpened = null; + inline.wrappersOffset = null; + + /** + * saving selection that need for execCommand for styling + * + */ + inline.storedSelection = null; + + /** + * @protected + * + * Open inline toobar + */ + inline.show = function () { + var currentNode = editor.content.currentNode, + tool = currentNode.dataset.tool, + plugin; + + /** + * tool allowed to open inline toolbar + */ + plugin = editor.tools[tool]; + + if (!plugin.showInlineToolbar) return; + + var selectedText = inline.getSelectionText(), + toolbar = editor.nodes.inlineToolbar.wrapper; + + if (selectedText.length > 0) { + /** Move toolbar and open */ + editor.toolbar.inline.move(); + + /** Open inline toolbar */ + toolbar.classList.add('opened'); + + /** show buttons of inline toolbar */ + editor.toolbar.inline.showButtons(); + } + }; + + /** + * @protected + * + * Closes inline toolbar + */ + inline.close = function () { + var toolbar = editor.nodes.inlineToolbar.wrapper; + + toolbar.classList.remove('opened'); + }; + + /** + * @private + * + * Moving toolbar + */ + inline.move = function () { + if (!this.wrappersOffset) { + this.wrappersOffset = this.getWrappersOffset(); + } + + var coords = this.getSelectionCoords(), + defaultOffset = 0, + toolbar = editor.nodes.inlineToolbar.wrapper, + newCoordinateX, + newCoordinateY; + + if (toolbar.offsetHeight === 0) { + defaultOffset = 40; + } + + newCoordinateX = coords.x - this.wrappersOffset.left; + newCoordinateY = coords.y + window.scrollY - this.wrappersOffset.top - defaultOffset - toolbar.offsetHeight; + + toolbar.style.transform = 'translate3D(' + Math.floor(newCoordinateX) + 'px, ' + Math.floor(newCoordinateY) + 'px, 0)'; + + /** Close everything */ + editor.toolbar.inline.closeButtons(); + editor.toolbar.inline.closeAction(); + }; + + /** + * @private + * + * Tool Clicked + */ + + inline.toolClicked = function (event, type) { + /** + * For simple tools we use default browser function + * For more complicated tools, we should write our own behavior + */ + switch (type) { + case 'createLink': + editor.toolbar.inline.createLinkAction(event, type);break; + default: + editor.toolbar.inline.defaultToolAction(type);break; + } + + /** + * highlight buttons + * after making some action + */ + editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight); + }; + + /** + * @private + * + * Saving wrappers offset in DOM + */ + inline.getWrappersOffset = function () { + var wrapper = editor.nodes.wrapper, + offset = this.getOffset(wrapper); + + this.wrappersOffset = offset; + return offset; + }; + + /** + * @private + * + * Calculates offset of DOM element + * + * @param el + * @returns {{top: number, left: number}} + */ + inline.getOffset = function (el) { + var _x = 0; + var _y = 0; + + while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) { + _x += el.offsetLeft + el.clientLeft; + _y += el.offsetTop + el.clientTop; + el = el.offsetParent; + } + return { top: _y, left: _x }; + }; + + /** + * @private + * + * Calculates position of selected text + * @returns {{x: number, y: number}} + */ + inline.getSelectionCoords = function () { + var sel = document.selection, + range; + var x = 0, + y = 0; + + if (sel) { + if (sel.type != 'Control') { + range = sel.createRange(); + range.collapse(true); + x = range.boundingLeft; + y = range.boundingTop; + } + } else if (window.getSelection) { + sel = window.getSelection(); + + if (sel.rangeCount) { + range = sel.getRangeAt(0).cloneRange(); + if (range.getClientRects) { + range.collapse(true); + var rect = range.getClientRects()[0]; + + if (!rect) { + return; + } + + x = rect.left; + y = rect.top; + } + } + } + return { x: x, y: y }; + }; + + /** + * @private + * + * Returns selected text as String + * @returns {string} + */ + inline.getSelectionText = function () { + var selectedText = ''; + + // all modern browsers and IE9+ + if (window.getSelection) { + selectedText = window.getSelection().toString(); + } + + return selectedText; + }; + + /** Opens buttons block */ + inline.showButtons = function () { + var buttons = editor.nodes.inlineToolbar.buttons; + + buttons.classList.add('opened'); + + editor.toolbar.inline.buttonsOpened = true; + + /** highlight buttons */ + editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight); + }; + + /** Makes buttons disappear */ + inline.closeButtons = function () { + var buttons = editor.nodes.inlineToolbar.buttons; + + buttons.classList.remove('opened'); + + editor.toolbar.inline.buttonsOpened = false; + }; + + /** Open buttons defined action if exist */ + inline.showActions = function () { + var action = editor.nodes.inlineToolbar.actions; + + action.classList.add('opened'); + + editor.toolbar.inline.actionsOpened = true; + }; + + /** Close actions block */ + inline.closeAction = function () { + var action = editor.nodes.inlineToolbar.actions; + + action.innerHTML = ''; + action.classList.remove('opened'); + editor.toolbar.inline.actionsOpened = false; + }; + + /** + * Callback for keydowns in inline toolbar "Insert link..." input + */ + var inlineToolbarAnchorInputKeydown_ = function inlineToolbarAnchorInputKeydown_(event) { + if (event.keyCode != editor.core.keys.ENTER) { + return; + } + + var editable = editor.content.currentNode, + storedSelection = editor.toolbar.inline.storedSelection; + + editor.toolbar.inline.restoreSelection(editable, storedSelection); + editor.toolbar.inline.setAnchor(this.value); + + /** + * Preventing events that will be able to happen + */ + event.preventDefault(); + event.stopImmediatePropagation(); + + editor.toolbar.inline.clearRange(); + }; + + /** Action for link creation or for setting anchor */ + inline.createLinkAction = function (event) { + var isActive = this.isLinkActive(); + + var editable = editor.content.currentNode, + storedSelection = editor.toolbar.inline.saveSelection(editable); + + /** Save globally selection */ + editor.toolbar.inline.storedSelection = storedSelection; + + if (isActive) { + /** + * Changing stored selection. if we want to remove anchor from word + * we should remove anchor from whole word, not only selected part. + * The solution is than we get the length of current link + * Change start position to - end of selection minus length of anchor + */ + editor.toolbar.inline.restoreSelection(editable, storedSelection); + + editor.toolbar.inline.defaultToolAction('unlink'); + } else { + /** Create input and close buttons */ + var action = editor.draw.inputForLink(); + + editor.nodes.inlineToolbar.actions.appendChild(action); + + editor.toolbar.inline.closeButtons(); + editor.toolbar.inline.showActions(); + + /** + * focus to input + * Solution: https://developer.mozilla.org/ru/docs/Web/API/HTMLElement/focus + * Prevents event after showing input and when we need to focus an input which is in unexisted form + */ + action.focus(); + event.preventDefault(); + + /** Callback to link action */ + editor.listeners.add(action, 'keydown', inlineToolbarAnchorInputKeydown_, false); + } + }; + + inline.isLinkActive = function () { + var isActive = false; + + editor.nodes.inlineToolbar.buttons.childNodes.forEach(function (tool) { + var dataType = tool.dataset.type; + + if (dataType == 'link' && tool.classList.contains('hightlighted')) { + isActive = true; + } + }); + + return isActive; + }; + + /** default action behavior of tool */ + inline.defaultToolAction = function (type) { + document.execCommand(type, false, null); + }; + + /** + * @private + * + * Sets URL + * + * @param {String} url - URL + */ + inline.setAnchor = function (url) { + document.execCommand('createLink', false, url); + + /** Close after URL inserting */ + editor.toolbar.inline.closeAction(); + }; + + /** + * @private + * + * Saves selection + */ + inline.saveSelection = function (containerEl) { + var range = window.getSelection().getRangeAt(0), + preSelectionRange = range.cloneRange(), + start; + + preSelectionRange.selectNodeContents(containerEl); + preSelectionRange.setEnd(range.startContainer, range.startOffset); + + start = preSelectionRange.toString().length; + + return { + start: start, + end: start + range.toString().length + }; + }; + + /** + * @private + * + * Sets to previous selection (Range) + * + * @param {Element} containerEl - editable element where we restore range + * @param {Object} savedSel - range basic information to restore + */ + inline.restoreSelection = function (containerEl, savedSel) { + var range = document.createRange(), + charIndex = 0; + + range.setStart(containerEl, 0); + range.collapse(true); + + var nodeStack = [containerEl], + node, + foundStart = false, + stop = false, + nextCharIndex; + + while (!stop && (node = nodeStack.pop())) { + if (node.nodeType == 3) { + nextCharIndex = charIndex + node.length; + + if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) { + range.setStart(node, savedSel.start - charIndex); + foundStart = true; + } + if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) { + range.setEnd(node, savedSel.end - charIndex); + stop = true; + } + charIndex = nextCharIndex; + } else { + var i = node.childNodes.length; + + while (i--) { + nodeStack.push(node.childNodes[i]); + } + } + } + + var sel = window.getSelection(); + + sel.removeAllRanges(); + sel.addRange(range); + }; + + /** + * @private + * + * Removes all ranges from window selection + */ + inline.clearRange = function () { + var selection = window.getSelection(); + + selection.removeAllRanges(); + }; + + /** + * @private + * + * sets or removes hightlight + */ + inline.hightlight = function (tool) { + var dataType = tool.dataset.type; + + if (document.queryCommandState(dataType)) { + editor.toolbar.inline.setButtonHighlighted(tool); + } else { + editor.toolbar.inline.removeButtonsHighLight(tool); + } + + /** + * + * hightlight for anchors + */ + var selection = window.getSelection(), + tag = selection.anchorNode.parentNode; + + if (tag.tagName == 'A' && dataType == 'link') { + editor.toolbar.inline.setButtonHighlighted(tool); + } + }; + + /** + * @private + * + * Mark button if text is already executed + */ + inline.setButtonHighlighted = function (button) { + button.classList.add('hightlighted'); + + /** At link tool we also change icon */ + if (button.dataset.type == 'link') { + var icon = button.childNodes[0]; + + icon.classList.remove('ce-icon-link'); + icon.classList.add('ce-icon-unlink'); + } + }; + + /** + * @private + * + * Removes hightlight + */ + inline.removeButtonsHighLight = function (button) { + button.classList.remove('hightlighted'); + + /** At link tool we also change icon */ + if (button.dataset.type == 'link') { + var icon = button.childNodes[0]; + + icon.classList.remove('ce-icon-unlink'); + icon.classList.add('ce-icon-link'); + } + }; + + return inline; +}({}); + +/***/ }), + +/***/ "./src/components/modules/toolbar/settings.js": +/*!****************************************************!*\ + !*** ./src/components/modules/toolbar/settings.js ***! + \****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Toolbar settings + * + * @version 1.0.5 + */ + +module.exports = function (settings) { + var editor = codex.editor; + + settings.opened = false; + + settings.setting = null; + settings.actions = null; + + /** + * Append and open settings + */ + settings.open = function (toolType) { + /** + * Append settings content + * It's stored in tool.settings + */ + if (!editor.tools[toolType] || !editor.tools[toolType].renderSettings) { + return; + } + + /** + * Draw settings block + */ + var settingsBlock = editor.tools[toolType].renderSettings(); + + editor.nodes.pluginSettings.appendChild(settingsBlock); + + /** Open settings block */ + editor.nodes.blockSettings.classList.add('opened'); + this.opened = true; + }; + + /** + * Close and clear settings + */ + settings.close = function () { + editor.nodes.blockSettings.classList.remove('opened'); + editor.nodes.pluginSettings.innerHTML = ''; + + this.opened = false; + }; + + /** + * @param {string} toolType - plugin type + */ + settings.toggle = function (toolType) { + if (!this.opened) { + this.open(toolType); + } else { + this.close(); + } + }; + + /** + * Here we will draw buttons and add listeners to components + */ + settings.makeRemoveBlockButton = function () { + var removeBlockWrapper = editor.draw.node('SPAN', 'ce-toolbar__remove-btn', {}), + settingButton = editor.draw.node('SPAN', 'ce-toolbar__remove-setting', { innerHTML: '' }), + actionWrapper = editor.draw.node('DIV', 'ce-toolbar__remove-confirmation', {}), + confirmAction = editor.draw.node('DIV', 'ce-toolbar__remove-confirm', { textContent: 'Удалить блок' }), + cancelAction = editor.draw.node('DIV', 'ce-toolbar__remove-cancel', { textContent: 'Отмена' }); + + editor.listeners.add(settingButton, 'click', editor.toolbar.settings.removeButtonClicked, false); + + editor.listeners.add(confirmAction, 'click', editor.toolbar.settings.confirmRemovingRequest, false); + + editor.listeners.add(cancelAction, 'click', editor.toolbar.settings.cancelRemovingRequest, false); + + actionWrapper.appendChild(confirmAction); + actionWrapper.appendChild(cancelAction); + + removeBlockWrapper.appendChild(settingButton); + removeBlockWrapper.appendChild(actionWrapper); + + /** Save setting */ + editor.toolbar.settings.setting = settingButton; + editor.toolbar.settings.actions = actionWrapper; + + return removeBlockWrapper; + }; + + settings.removeButtonClicked = function () { + var action = editor.toolbar.settings.actions; + + if (action.classList.contains('opened')) { + editor.toolbar.settings.hideRemoveActions(); + } else { + editor.toolbar.settings.showRemoveActions(); + } + + editor.toolbar.toolbox.close(); + editor.toolbar.settings.close(); + }; + + settings.cancelRemovingRequest = function () { + editor.toolbar.settings.actions.classList.remove('opened'); + }; + + settings.confirmRemovingRequest = function () { + var currentBlock = editor.content.currentNode, + firstLevelBlocksCount; + + currentBlock.remove(); + + firstLevelBlocksCount = editor.nodes.redactor.childNodes.length; + + /** + * If all blocks are removed + */ + if (firstLevelBlocksCount === 0) { + /** update currentNode variable */ + editor.content.currentNode = null; + + /** Inserting new empty initial block */ + editor.ui.addInitialBlock(); + } + + editor.ui.saveInputs(); + + editor.toolbar.close(); + }; + + settings.showRemoveActions = function () { + editor.toolbar.settings.actions.classList.add('opened'); + }; + + settings.hideRemoveActions = function () { + editor.toolbar.settings.actions.classList.remove('opened'); + }; + + return settings; +}({}); + +/***/ }), + +/***/ "./src/components/modules/toolbar/toolbar.js": +/*!***************************************************!*\ + !*** ./src/components/modules/toolbar/toolbar.js ***! + \***************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Codex Editor toolbar module + * + * Contains: + * - Inline toolbox + * - Toolbox within plus button + * - Settings section + * + * @author Codex Team + * @version 1.0 + */ + +module.exports = function (toolbar) { + var editor = codex.editor; + + toolbar.settings = __webpack_require__(/*! ./settings */ "./src/components/modules/toolbar/settings.js"); + toolbar.inline = __webpack_require__(/*! ./inline */ "./src/components/modules/toolbar/inline.js"); + toolbar.toolbox = __webpack_require__(/*! ./toolbox */ "./src/components/modules/toolbar/toolbox.js"); + + /** + * Margin between focused node and toolbar + */ + toolbar.defaultToolbarHeight = 49; + + toolbar.defaultOffset = 34; + + toolbar.opened = false; + + toolbar.current = null; + + /** + * @protected + */ + toolbar.open = function () { + if (editor.hideToolbar) { + return; + } + + var toolType = editor.content.currentNode.dataset.tool; + + if (!editor.tools[toolType] || !editor.tools[toolType].renderSettings) { + editor.nodes.showSettingsButton.classList.add('hide'); + } else { + editor.nodes.showSettingsButton.classList.remove('hide'); + } + + editor.nodes.toolbar.classList.add('opened'); + this.opened = true; + }; + + /** + * @protected + */ + toolbar.close = function () { + editor.nodes.toolbar.classList.remove('opened'); + + toolbar.opened = false; + toolbar.current = null; + + for (var button in editor.nodes.toolbarButtons) { + editor.nodes.toolbarButtons[button].classList.remove('selected'); + } + + /** Close toolbox when toolbar is not displayed */ + editor.toolbar.toolbox.close(); + editor.toolbar.settings.close(); + }; + + toolbar.toggle = function () { + if (!this.opened) { + this.open(); + } else { + this.close(); + } + }; + + toolbar.hidePlusButton = function () { + editor.nodes.plusButton.classList.add('hide'); + }; + + toolbar.showPlusButton = function () { + editor.nodes.plusButton.classList.remove('hide'); + }; + + /** + * Moving toolbar to the specified node + */ + toolbar.move = function () { + /** Close Toolbox when we move toolbar */ + editor.toolbar.toolbox.close(); + + if (!editor.content.currentNode) { + return; + } + + var newYCoordinate = editor.content.currentNode.offsetTop - editor.toolbar.defaultToolbarHeight / 2 + editor.toolbar.defaultOffset; + + editor.nodes.toolbar.style.transform = 'translate3D(0, ' + Math.floor(newYCoordinate) + 'px, 0)'; + + /** Close trash actions */ + editor.toolbar.settings.hideRemoveActions(); + }; + + return toolbar; +}({}); + +/***/ }), + +/***/ "./src/components/modules/toolbar/toolbox.js": +/*!***************************************************!*\ + !*** ./src/components/modules/toolbar/toolbox.js ***! + \***************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Codex Editor toolbox + * + * All tools be able to appended here + * + * @author Codex Team + * @version 1.0 + */ + +module.exports = function (toolbox) { + var editor = codex.editor; + + toolbox.opened = false; + toolbox.openedOnBlock = null; + + /** Shows toolbox */ + toolbox.open = function () { + /** Close setting if toolbox is opened */ + if (editor.toolbar.settings.opened) { + editor.toolbar.settings.close(); + } + + /** Add 'toolbar-opened' class for current block **/ + toolbox.openedOnBlock = editor.content.currentNode; + toolbox.openedOnBlock.classList.add('toolbar-opened'); + + /** display toolbox */ + editor.nodes.toolbox.classList.add('opened'); + + /** Animate plus button */ + editor.nodes.plusButton.classList.add('clicked'); + + /** toolbox state */ + editor.toolbar.toolbox.opened = true; + }; + + /** Closes toolbox */ + toolbox.close = function () { + /** Remove 'toolbar-opened' class from current block **/ + if (toolbox.openedOnBlock) toolbox.openedOnBlock.classList.remove('toolbar-opened'); + toolbox.openedOnBlock = null; + + /** Makes toolbox disappear */ + editor.nodes.toolbox.classList.remove('opened'); + + /** Rotate plus button */ + editor.nodes.plusButton.classList.remove('clicked'); + + /** toolbox state */ + editor.toolbar.toolbox.opened = false; + + editor.toolbar.current = null; + }; + + toolbox.leaf = function () { + var currentTool = editor.toolbar.current, + tools = Object.keys(editor.tools), + barButtons = editor.nodes.toolbarButtons, + nextToolIndex = 0, + toolToSelect = void 0, + visibleTool = void 0, + tool = void 0; + + if (!currentTool) { + /** Get first tool from object*/ + for (tool in editor.tools) { + if (editor.tools[tool].displayInToolbox) { + break; + } + + nextToolIndex++; + } + } else { + nextToolIndex = (tools.indexOf(currentTool) + 1) % tools.length; + visibleTool = tools[nextToolIndex]; + + while (!editor.tools[visibleTool].displayInToolbox) { + nextToolIndex = (nextToolIndex + 1) % tools.length; + visibleTool = tools[nextToolIndex]; + } + } + + toolToSelect = tools[nextToolIndex]; + + for (var button in barButtons) { + barButtons[button].classList.remove('selected'); + } + + barButtons[toolToSelect].classList.add('selected'); + editor.toolbar.current = toolToSelect; + }; + + /** + * Transforming selected node type into selected toolbar element type + * @param {event} event + */ + toolbox.toolClicked = function (event) { + /** + * UNREPLACEBLE_TOOLS this types of tools are forbidden to replace even they are empty + */ + var UNREPLACEBLE_TOOLS = ['image', 'link', 'list', 'instagram', 'twitter', 'embed'], + tool = editor.tools[editor.toolbar.current], + workingNode = editor.content.currentNode, + currentInputIndex = editor.caret.inputIndex, + newBlockContent, + appendCallback, + blockData; + + /** Make block from plugin */ + newBlockContent = tool.render(); + + /** information about block */ + blockData = { + block: newBlockContent, + type: tool.type, + stretched: false + }; + + if (workingNode && UNREPLACEBLE_TOOLS.indexOf(workingNode.dataset.tool) === -1 && workingNode.textContent.trim() === '') { + /** Replace current block */ + editor.content.switchBlock(workingNode, newBlockContent, tool.type); + } else { + /** Insert new Block from plugin */ + editor.content.insertBlock(blockData); + + /** increase input index */ + currentInputIndex++; + } + + /** Fire tool append callback */ + appendCallback = tool.appendCallback; + + if (appendCallback && typeof appendCallback == 'function') { + appendCallback.call(event); + } + + window.setTimeout(function () { + /** Set caret to current block */ + editor.caret.setToBlock(currentInputIndex); + }, 10); + + /** + * Changing current Node + */ + editor.content.workingNodeChanged(); + + /** + * Move toolbar when node is changed + */ + editor.toolbar.move(); + }; + + return toolbox; +}({}); + +/***/ }), + /***/ "./src/components/modules/tools.js": /*!*****************************************!*\ !*** ./src/components/modules/tools.js ***! @@ -8560,7 +12331,7 @@ exports = module.exports = __webpack_require__(/*! ../../node_modules/css-loader // module -exports.push([module.i, ":root {\n /**\n * Selection color\n */\n --selectionColor: rgba(61,166,239,0.63);\n\n /**\n * Toolbar buttons\n */\n --bg-light: #eff2f5;\n\n /**\n * All gray texts: placeholders, settings\n */\n --grayText: #707684;\n\n /** Blue icons */\n --color-active-icon: #388AE5;\n\n /**\n * Block content width\n */\n --content-width: 650px;\n\n /**\n * Toolbar buttons height and width\n */\n --toolbar-buttons-size: 34px;\n\n /**\n * Toolbar Plus Button and Toolbox buttons height and width\n */\n --toolbox-buttons-size: 20px;\n\n /**\n * Confirm deletion bg\n */\n --color-confirm: #E24A4A;\n}\n/**\n* Editor wrapper\n*/\n.codex-editor {\n position: relative;\n box-sizing: border-box;\n}\n.codex-editor .hide {\n display: none;\n }\n.codex-editor__redactor {\n padding-bottom: 300px;\n }\n.codex-editor svg {\n fill: currentColor;\n vertical-align: middle;\n max-height: 100%;\n }\n/**\n * Set color for native selection\n */\n::-moz-selection{\n background-color: rgba(61,166,239,0.63);\n background-color: var(--selectionColor);\n}\n::selection{\n background-color: rgba(61,166,239,0.63);\n background-color: var(--selectionColor);\n}\n/**\n * Add placeholder to content editable elements with data attribute\n * data-placeholder=\"Hello world!\"\n */\n[contentEditable=true][data-placeholder]:empty:not(:focus):before{\n content: attr(data-placeholder);\n color: #707684;\n color: var(--grayText);\n}\n.ce-toolbar {\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n /*opacity: 0;*/\n /*visibility: hidden;*/\n transition: opacity 100ms ease;\n will-change: opacity, transform;\n display: none;\n}\n.ce-toolbar--opened {\n display: block;\n /*opacity: 1;*/\n /*visibility: visible;*/\n }\n.ce-toolbar__content {\n max-width: 650px;\n max-width: var(--content-width);\n margin: 0 auto;\n position: relative;\n }\n.ce-toolbar__plus {\n color: #707684;\n color: var(--grayText);\n cursor: pointer;\n display: inline-block;\n width: 20px;\n width: var(--toolbox-buttons-size);\n height: 20px;\n height: var(--toolbox-buttons-size);\n line-height: 20px;\n line-height: var(--toolbox-buttons-size)\n }\n.ce-toolbar__plus:not(:last-of-type){\n margin-right: 3px;\n }\n.ce-toolbar__plus:hover {\n color: #388AE5;\n color: var(--color-active-icon);\n }\n.ce-toolbar__plus {\n\n position: absolute;\n top: -1px;\n left: calc(calc(20px + 10px) * -1);\n left: calc(calc(var(--toolbox-buttons-size) + 10px) * -1);\n }\n.ce-toolbar__plus--hidden {\n display: none;\n }\n/**\n * Block actions Zone\n * -------------------------\n */\n.ce-toolbar__actions {\n position: absolute;\n right: 0;\n top: 0;\n padding-right: 16px;\n }\n.ce-toolbar__actions-buttons {\n text-align: right;\n }\n.ce-toolbar__settings-btn {\n display: inline-block;\n width: 24px;\n height: 24px;\n color: #707684;\n color: var(--grayText);\n cursor: pointer;\n }\n.ce-toolbox {\n position: absolute;\n visibility: hidden;\n transition: opacity 100ms ease;\n will-change: opacity;\n}\n.ce-toolbox--opened {\n opacity: 1;\n visibility: visible;\n }\n.ce-toolbox__button {\n color: #707684;\n color: var(--grayText);\n cursor: pointer;\n display: inline-block;\n width: 20px;\n width: var(--toolbox-buttons-size);\n height: 20px;\n height: var(--toolbox-buttons-size);\n line-height: 20px;\n line-height: var(--toolbox-buttons-size);\n }\n.ce-toolbox__button:not(:last-of-type){\n margin-right: 3px;\n }\n.ce-toolbox__button:hover {\n color: #388AE5;\n color: var(--color-active-icon);\n }\n.ce-inline-toolbar {\n position: absolute;\n background-color: #FFFFFF;\n box-shadow: 0 8px 23px -6px rgba(21,40,54,0.31), 22px -14px 34px -18px rgba(33,48,73,0.26);\n border-radius: 4px;\n z-index: 2\n}\n.ce-inline-toolbar::before {\n content: '';\n width: 15px;\n height: 15px;\n position: absolute;\n top: -7px;\n left: 50%;\n margin-left: -7px;\n transform: rotate(-45deg);\n background-color: #fff;\n z-index: -1;\n }\n.ce-inline-toolbar {\n padding: 6px;\n transform: translateX(-50%);\n display: none;\n box-shadow: 0 6px 12px -6px rgba(131, 147, 173, 0.46),\n 5px -12px 34px -13px rgba(97, 105, 134, 0.6),\n 0 26px 52px 3px rgba(147, 165, 186, 0.24);\n}\n.ce-inline-toolbar--showed {\n display: block;\n }\n.ce-inline-tool {\n display: inline-block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n border-radius: 3px;\n cursor: pointer;\n border: 0;\n outline: none;\n background-color: transparent;\n vertical-align: bottom;\n color: #707684;\n color: var(--grayText)\n}\n.ce-inline-tool:not(:last-of-type){\n margin-right: 5px;\n }\n.ce-inline-tool:hover {\n background-color: #eff2f5;\n background-color: var(--bg-light);\n }\n.ce-inline-tool {\n line-height: normal;\n}\n.ce-inline-tool--active {\n color: #388AE5;\n color: var(--color-active-icon);\n }\n.ce-inline-tool--link .icon {\n margin-top: -2px;\n }\n.ce-inline-tool--link .icon--unlink {\n display: none;\n }\n.ce-inline-tool--unlink .icon--link {\n display: none;\n }\n.ce-inline-tool--unlink .icon--unlink {\n display: inline-block;\n }\n.ce-inline-tool-input {\n background-color: #eff2f5;\n background-color: var(--bg-light);\n outline: none;\n border: 0;\n border-radius: 3px;\n margin: 6px 0 0;\n font-size: 13px;\n padding: 8px;\n width: 100%;\n box-sizing: border-box;\n display: none\n }\n.ce-inline-tool-input::-webkit-input-placeholder {\n color: #707684;\n color: var(--grayText);\n }\n.ce-inline-tool-input:-ms-input-placeholder {\n color: #707684;\n color: var(--grayText);\n }\n.ce-inline-tool-input::placeholder {\n color: #707684;\n color: var(--grayText);\n }\n.ce-inline-tool-input--showed {\n display: block;\n }\n.ce-settings {\n position: absolute;\n background-color: #FFFFFF;\n box-shadow: 0 8px 23px -6px rgba(21,40,54,0.31), 22px -14px 34px -18px rgba(33,48,73,0.26);\n border-radius: 4px;\n z-index: 2\n}\n.ce-settings::before {\n content: '';\n width: 15px;\n height: 15px;\n position: absolute;\n top: -7px;\n left: 50%;\n margin-left: -7px;\n transform: rotate(-45deg);\n background-color: #fff;\n z-index: -1;\n }\n.ce-settings {\n right: 5px;\n top: 35px;\n min-width: 124px\n}\n.ce-settings::before{\n left: auto;\n right: 12px;\n }\n.ce-settings {\n\n display: none;\n}\n.ce-settings--opened {\n display: block;\n }\n.ce-settings__plugin-zone:not(:empty){\n padding: 6px 6px 0;\n }\n.ce-settings__default-zone:not(:empty){\n padding: 6px;\n }\n.ce-settings__button {\n display: inline-block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n border-radius: 3px;\n cursor: pointer;\n border: 0;\n outline: none;\n background-color: transparent;\n vertical-align: bottom;\n color: #707684;\n color: var(--grayText)\n }\n.ce-settings__button:not(:last-of-type){\n margin-right: 5px;\n }\n.ce-settings__button:hover {\n background-color: #eff2f5;\n background-color: var(--bg-light);\n }\n.ce-settings__button--active {\n color: #388AE5;\n color: var(--color-active-icon);\n }\n.ce-settings__button--disabled {\n cursor: not-allowed !important;\n opacity: .3;\n }\n.ce-settings__button--selected {\n color: #388AE5;\n color: var(--color-active-icon);\n }\n.ce-settings__button--delete {\n transition: background-color 300ms ease;\n will-change: background-color;\n }\n.ce-settings__button--delete .icon {\n transition: transform 200ms ease-out;\n will-change: transform;\n }\n.ce-settings__button--confirm {\n background-color: #E24A4A;\n background-color: var(--color-confirm);\n color: #fff\n }\n.ce-settings__button--confirm:hover {\n background-color: rgb(213, 74, 74) !important;\n background-color: rgb(213, 74, 74) !important;\n }\n.ce-settings__button--confirm .icon {\n transform: rotate(90deg);\n }\n.ce-block:first-of-type {\n margin-top: 0;\n }\n.ce-block--selected {\n background-image: linear-gradient(17deg, rgba(243, 248, 255, 0.03) 63.45%, rgba(207, 214, 229, 0.27) 98%);\n border-radius: 3px;\n }\n.ce-block__content {\n max-width: 650px;\n max-width: var(--content-width);\n margin: 0 auto;\n }\n.wobble {\n animation-name: wobble;\n animation-duration: 400ms;\n}\n/**\n * @author Nick Pettit - https://github.com/nickpettit/glide\n */\n@keyframes wobble {\n from {\n transform: translate3d(0, 0, 0);\n }\n\n 15% {\n transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -5deg);\n }\n\n 30% {\n transform: translate3d(2%, 0, 0) rotate3d(0, 0, 1, 3deg);\n }\n\n 45% {\n transform: translate3d(-3%, 0, 0) rotate3d(0, 0, 1, -3deg);\n }\n\n 60% {\n transform: translate3d(2%, 0, 0) rotate3d(0, 0, 1, 2deg);\n }\n\n 75% {\n transform: translate3d(-1%, 0, 0) rotate3d(0, 0, 1, -1deg);\n }\n\n to {\n transform: translate3d(0, 0, 0);\n }\n}\n", ""]); +exports.push([module.i, ":root {\r\n /**\r\n * Selection color\r\n */\r\n --selectionColor: rgba(61,166,239,0.63);\r\n\r\n /**\r\n * Toolbar buttons\r\n */\r\n --bg-light: #eff2f5;\r\n\r\n /**\r\n * All gray texts: placeholders, settings\r\n */\r\n --grayText: #707684;\r\n\r\n /** Blue icons */\r\n --color-active-icon: #388AE5;\r\n\r\n /**\r\n * Block content width\r\n */\r\n --content-width: 650px;\r\n\r\n /**\r\n * Toolbar buttons height and width\r\n */\r\n --toolbar-buttons-size: 34px;\r\n\r\n /**\r\n * Toolbar Plus Button and Toolbox buttons height and width\r\n */\r\n --toolbox-buttons-size: 20px;\r\n\r\n /**\r\n * Confirm deletion bg\r\n */\r\n --color-confirm: #E24A4A;\r\n}\r\n/**\r\n* Editor wrapper\r\n*/\r\n.codex-editor {\r\n position: relative;\r\n box-sizing: border-box;\r\n}\r\n.codex-editor .hide {\r\n display: none;\r\n }\r\n.codex-editor__redactor {\r\n padding-bottom: 300px;\r\n }\r\n.codex-editor svg {\r\n fill: currentColor;\r\n vertical-align: middle;\r\n max-height: 100%;\r\n }\r\n/**\r\n * Set color for native selection\r\n */\r\n::-moz-selection{\r\n background-color: rgba(61,166,239,0.63);\r\n background-color: var(--selectionColor);\r\n}\r\n::selection{\r\n background-color: rgba(61,166,239,0.63);\r\n background-color: var(--selectionColor);\r\n}\r\n/**\r\n * Add placeholder to content editable elements with data attribute\r\n * data-placeholder=\"Hello world!\"\r\n */\r\n[contentEditable=true][data-placeholder]:empty:not(:focus):before{\r\n content: attr(data-placeholder);\r\n color: #707684;\r\n color: var(--grayText);\r\n}\r\n.ce-toolbar {\r\n position: absolute;\r\n left: 0;\r\n right: 0;\r\n top: 0;\r\n /*opacity: 0;*/\r\n /*visibility: hidden;*/\r\n transition: opacity 100ms ease;\r\n will-change: opacity, transform;\r\n display: none;\r\n}\r\n.ce-toolbar--opened {\r\n display: block;\r\n /*opacity: 1;*/\r\n /*visibility: visible;*/\r\n }\r\n.ce-toolbar__content {\r\n max-width: 650px;\r\n max-width: var(--content-width);\r\n margin: 0 auto;\r\n position: relative;\r\n }\r\n.ce-toolbar__plus {\r\n color: #707684;\r\n color: var(--grayText);\r\n cursor: pointer;\r\n display: inline-block;\r\n width: 20px;\r\n width: var(--toolbox-buttons-size);\r\n height: 20px;\r\n height: var(--toolbox-buttons-size);\r\n line-height: 20px;\r\n line-height: var(--toolbox-buttons-size)\r\n }\r\n.ce-toolbar__plus:not(:last-of-type){\r\n margin-right: 3px;\r\n }\r\n.ce-toolbar__plus:hover {\r\n color: #388AE5;\r\n color: var(--color-active-icon);\r\n }\r\n.ce-toolbar__plus {\r\n\r\n position: absolute;\r\n top: -1px;\r\n left: calc(calc(20px + 10px) * -1);\r\n left: calc(calc(var(--toolbox-buttons-size) + 10px) * -1);\r\n }\r\n.ce-toolbar__plus--hidden {\r\n display: none;\r\n }\r\n/**\r\n * Block actions Zone\r\n * -------------------------\r\n */\r\n.ce-toolbar__actions {\r\n position: absolute;\r\n right: 0;\r\n top: 0;\r\n padding-right: 16px;\r\n }\r\n.ce-toolbar__actions-buttons {\r\n text-align: right;\r\n }\r\n.ce-toolbar__settings-btn {\r\n display: inline-block;\r\n width: 24px;\r\n height: 24px;\r\n color: #707684;\r\n color: var(--grayText);\r\n cursor: pointer;\r\n }\r\n.ce-toolbox {\r\n position: absolute;\r\n visibility: hidden;\r\n transition: opacity 100ms ease;\r\n will-change: opacity;\r\n}\r\n.ce-toolbox--opened {\r\n opacity: 1;\r\n visibility: visible;\r\n }\r\n.ce-toolbox__button {\r\n color: #707684;\r\n color: var(--grayText);\r\n cursor: pointer;\r\n display: inline-block;\r\n width: 20px;\r\n width: var(--toolbox-buttons-size);\r\n height: 20px;\r\n height: var(--toolbox-buttons-size);\r\n line-height: 20px;\r\n line-height: var(--toolbox-buttons-size);\r\n }\r\n.ce-toolbox__button:not(:last-of-type){\r\n margin-right: 3px;\r\n }\r\n.ce-toolbox__button:hover {\r\n color: #388AE5;\r\n color: var(--color-active-icon);\r\n }\r\n.ce-inline-toolbar {\r\n position: absolute;\r\n background-color: #FFFFFF;\r\n box-shadow: 0 8px 23px -6px rgba(21,40,54,0.31), 22px -14px 34px -18px rgba(33,48,73,0.26);\r\n border-radius: 4px;\r\n z-index: 2\r\n}\r\n.ce-inline-toolbar::before {\r\n content: '';\r\n width: 15px;\r\n height: 15px;\r\n position: absolute;\r\n top: -7px;\r\n left: 50%;\r\n margin-left: -7px;\r\n transform: rotate(-45deg);\r\n background-color: #fff;\r\n z-index: -1;\r\n }\r\n.ce-inline-toolbar {\r\n padding: 6px;\r\n transform: translateX(-50%);\r\n display: none;\r\n box-shadow: 0 6px 12px -6px rgba(131, 147, 173, 0.46),\r\n 5px -12px 34px -13px rgba(97, 105, 134, 0.6),\r\n 0 26px 52px 3px rgba(147, 165, 186, 0.24);\r\n}\r\n.ce-inline-toolbar--showed {\r\n display: block;\r\n }\r\n.ce-inline-tool {\r\n display: inline-block;\r\n width: 34px;\r\n height: 34px;\r\n line-height: 34px;\r\n text-align: center;\r\n border-radius: 3px;\r\n cursor: pointer;\r\n border: 0;\r\n outline: none;\r\n background-color: transparent;\r\n vertical-align: bottom;\r\n color: #707684;\r\n color: var(--grayText)\r\n}\r\n.ce-inline-tool:not(:last-of-type){\r\n margin-right: 5px;\r\n }\r\n.ce-inline-tool:hover {\r\n background-color: #eff2f5;\r\n background-color: var(--bg-light);\r\n }\r\n.ce-inline-tool {\r\n line-height: normal;\r\n}\r\n.ce-inline-tool--active {\r\n color: #388AE5;\r\n color: var(--color-active-icon);\r\n }\r\n.ce-inline-tool--link .icon {\r\n margin-top: -2px;\r\n }\r\n.ce-inline-tool--link .icon--unlink {\r\n display: none;\r\n }\r\n.ce-inline-tool--unlink .icon--link {\r\n display: none;\r\n }\r\n.ce-inline-tool--unlink .icon--unlink {\r\n display: inline-block;\r\n }\r\n.ce-inline-tool-input {\r\n background-color: #eff2f5;\r\n background-color: var(--bg-light);\r\n outline: none;\r\n border: 0;\r\n border-radius: 3px;\r\n margin: 6px 0 0;\r\n font-size: 13px;\r\n padding: 8px;\r\n width: 100%;\r\n box-sizing: border-box;\r\n display: none\r\n }\r\n.ce-inline-tool-input::-webkit-input-placeholder {\r\n color: #707684;\r\n color: var(--grayText);\r\n }\r\n.ce-inline-tool-input:-ms-input-placeholder {\r\n color: #707684;\r\n color: var(--grayText);\r\n }\r\n.ce-inline-tool-input::placeholder {\r\n color: #707684;\r\n color: var(--grayText);\r\n }\r\n.ce-inline-tool-input--showed {\r\n display: block;\r\n }\r\n.ce-settings {\r\n position: absolute;\r\n background-color: #FFFFFF;\r\n box-shadow: 0 8px 23px -6px rgba(21,40,54,0.31), 22px -14px 34px -18px rgba(33,48,73,0.26);\r\n border-radius: 4px;\r\n z-index: 2\r\n}\r\n.ce-settings::before {\r\n content: '';\r\n width: 15px;\r\n height: 15px;\r\n position: absolute;\r\n top: -7px;\r\n left: 50%;\r\n margin-left: -7px;\r\n transform: rotate(-45deg);\r\n background-color: #fff;\r\n z-index: -1;\r\n }\r\n.ce-settings {\r\n right: 5px;\r\n top: 35px;\r\n min-width: 124px\r\n}\r\n.ce-settings::before{\r\n left: auto;\r\n right: 12px;\r\n }\r\n.ce-settings {\r\n\r\n display: none;\r\n}\r\n.ce-settings--opened {\r\n display: block;\r\n }\r\n.ce-settings__plugin-zone:not(:empty){\r\n padding: 6px 6px 0;\r\n }\r\n.ce-settings__default-zone:not(:empty){\r\n padding: 6px;\r\n }\r\n.ce-settings__button {\r\n display: inline-block;\r\n width: 34px;\r\n height: 34px;\r\n line-height: 34px;\r\n text-align: center;\r\n border-radius: 3px;\r\n cursor: pointer;\r\n border: 0;\r\n outline: none;\r\n background-color: transparent;\r\n vertical-align: bottom;\r\n color: #707684;\r\n color: var(--grayText)\r\n }\r\n.ce-settings__button:not(:last-of-type){\r\n margin-right: 5px;\r\n }\r\n.ce-settings__button:hover {\r\n background-color: #eff2f5;\r\n background-color: var(--bg-light);\r\n }\r\n.ce-settings__button--active {\r\n color: #388AE5;\r\n color: var(--color-active-icon);\r\n }\r\n.ce-settings__button--disabled {\r\n cursor: not-allowed !important;\r\n opacity: .3;\r\n }\r\n.ce-settings__button--selected {\r\n color: #388AE5;\r\n color: var(--color-active-icon);\r\n }\r\n.ce-settings__button--delete {\r\n transition: background-color 300ms ease;\r\n will-change: background-color;\r\n }\r\n.ce-settings__button--delete .icon {\r\n transition: transform 200ms ease-out;\r\n will-change: transform;\r\n }\r\n.ce-settings__button--confirm {\r\n background-color: #E24A4A;\r\n background-color: var(--color-confirm);\r\n color: #fff\r\n }\r\n.ce-settings__button--confirm:hover {\r\n background-color: rgb(213, 74, 74) !important;\r\n background-color: rgb(213, 74, 74) !important;\r\n }\r\n.ce-settings__button--confirm .icon {\r\n transform: rotate(90deg);\r\n }\r\n.ce-block:first-of-type {\r\n margin-top: 0;\r\n }\r\n.ce-block--selected {\r\n background-image: linear-gradient(17deg, rgba(243, 248, 255, 0.03) 63.45%, rgba(207, 214, 229, 0.27) 98%);\r\n border-radius: 3px;\r\n }\r\n.ce-block__content {\r\n max-width: 650px;\r\n max-width: var(--content-width);\r\n margin: 0 auto;\r\n }\r\n.wobble {\r\n animation-name: wobble;\r\n animation-duration: 400ms;\r\n}\r\n/**\r\n * @author Nick Pettit - https://github.com/nickpettit/glide\r\n */\r\n@keyframes wobble {\r\n from {\r\n transform: translate3d(0, 0, 0);\r\n }\r\n\r\n 15% {\r\n transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -5deg);\r\n }\r\n\r\n 30% {\r\n transform: translate3d(2%, 0, 0) rotate3d(0, 0, 1, 3deg);\r\n }\r\n\r\n 45% {\r\n transform: translate3d(-3%, 0, 0) rotate3d(0, 0, 1, -3deg);\r\n }\r\n\r\n 60% {\r\n transform: translate3d(2%, 0, 0) rotate3d(0, 0, 1, 2deg);\r\n }\r\n\r\n 75% {\r\n transform: translate3d(-1%, 0, 0) rotate3d(0, 0, 1, -1deg);\r\n }\r\n\r\n to {\r\n transform: translate3d(0, 0, 0);\r\n }\r\n}\r\n", ""]); // exports diff --git a/build/codex-editor.js.map b/build/codex-editor.js.map index f4d5d369..008ec574 100644 --- a/build/codex-editor.js.map +++ b/build/codex-editor.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack://CodexEditor/webpack/universalModuleDefinition","webpack://CodexEditor/webpack/bootstrap","webpack://CodexEditor/./build/sprite.svg","webpack://CodexEditor/./node_modules/css-loader/lib/css-base.js","webpack://CodexEditor/./node_modules/html-janitor/src/html-janitor.js","webpack://CodexEditor/./src/codex.js","webpack://CodexEditor/./src/components/__module.ts","webpack://CodexEditor/./src/components/block-tunes/block-tune-delete.ts","webpack://CodexEditor/./src/components/block-tunes/block-tune-move-down.ts","webpack://CodexEditor/./src/components/block-tunes/block-tune-move-up.ts","webpack://CodexEditor/./src/components/block.js","webpack://CodexEditor/./src/components/dom.js","webpack://CodexEditor/./src/components/inline-tools/inline-tool-bold.ts","webpack://CodexEditor/./src/components/inline-tools/inline-tool-italic.ts","webpack://CodexEditor/./src/components/inline-tools/inline-tool-link.ts","webpack://CodexEditor/./src/components/modules sync nonrecursive [^_](api-blocks.ts|api-events.ts|api-listener.ts|api-sanitizer.ts|api-saver.ts|api-selection.ts|api-toolbar.ts|api.ts|block-events.ts|blockManager.js|caret.js|events.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$","webpack://CodexEditor/./src/components/modules/api-blocks.ts","webpack://CodexEditor/./src/components/modules/api-events.ts","webpack://CodexEditor/./src/components/modules/api-listener.ts","webpack://CodexEditor/./src/components/modules/api-sanitizer.ts","webpack://CodexEditor/./src/components/modules/api-saver.ts","webpack://CodexEditor/./src/components/modules/api-selection.ts","webpack://CodexEditor/./src/components/modules/api-toolbar.ts","webpack://CodexEditor/./src/components/modules/api.ts","webpack://CodexEditor/./src/components/modules/block-events.ts","webpack://CodexEditor/./src/components/modules/blockManager.js","webpack://CodexEditor/./src/components/modules/caret.js","webpack://CodexEditor/./src/components/modules/events.js","webpack://CodexEditor/./src/components/modules/listeners.js","webpack://CodexEditor/./src/components/modules/renderer.js","webpack://CodexEditor/./src/components/modules/sanitizer.js","webpack://CodexEditor/./src/components/modules/saver.js","webpack://CodexEditor/./src/components/modules/toolbar-blockSettings.js","webpack://CodexEditor/./src/components/modules/toolbar-inline.ts","webpack://CodexEditor/./src/components/modules/toolbar-toolbox.js","webpack://CodexEditor/./src/components/modules/toolbar.js","webpack://CodexEditor/./src/components/modules/tools.js","webpack://CodexEditor/./src/components/modules/ui.js","webpack://CodexEditor/./src/components/polyfills.js","webpack://CodexEditor/./src/components/selection.js","webpack://CodexEditor/./src/components/utils.js","webpack://CodexEditor/./src/styles/main.css"],"names":["modules","editorModules","map","module","CodexEditor","config","moduleInstances","Promise","resolve","then","configuration","init","start","methods","API","method","console","log","catch","error","constructModules","configureModules","forEach","Module","displayName","e","name","state","getModulesDiff","diff","moduleName","prepareDecorator","prepare","Tools","UI","BlockManager","Renderer","render","data","items","initialBlock","type","holderId","placeholder","sanitizer","p","b","a","hideToolbar","tools","toolsConfig","_","isEmpty","length","new","target","TypeError","Editor","DeleteTune","api","CSS","wrapper","button","buttonDelete","buttonConfirm","nodes","resetConfirmation","setConfirmation","$","make","appendChild","svg","listener","on","event","handleClick","needConfirmation","events","off","blocks","delete","classList","add","MoveDownTune","animation","moveDownButton","currentBlockIndex","getCurrentBlockIndex","getBlocksCount","window","setTimeout","remove","nextBlockElement","getBlockByIndex","holder","nextBlockCoords","getBoundingClientRect","scrollOffset","Math","abs","innerHeight","offsetHeight","top","scrollY","scrollTo","swap","MoveUpTune","moveUpButton","currentBlockElement","previousBlockElement","currentBlockCoords","previousBlockCoords","scrollUpOffset","scrollBy","Block","toolName","toolInstance","settings","apiMethods","tool","compose","tunes","makeTunes","contentNode","content","pluginsContent","methodName","params","Function","call","merge","extractedBlock","save","measuringStart","performance","now","measuringEnd","finishedExtraction","time","isValid","validate","tunesList","tune","tunesElement","document","createDocumentFragment","append","querySelector","childNodes","contentless","emptyText","emptyMedia","hasMedia","mediaTags","join","selected","Dom","tag","tagName","includes","classNames","attributes","el","createElement","Array","isArray","attrName","createTextNode","width","height","icon","createElementNS","setAttribute","innerHTML","parent","elements","el1","el2","temp","parentNode","insertBefore","removeChild","selector","querySelectorAll","node","atLast","child","sibling","nodeType","Node","ELEMENT_NODE","nodeChild","isSingleTag","getDeepestNode","nativeInputs","nodeText","isElement","isNativeInput","value","textContent","replace","trim","treeWalker","leafs","isNodeEmpty","push","firstChild","shift","isLeaf","nextSibling","every","leaf","BoldInlineTool","commandName","buttonActive","buttonModifier","range","execCommand","selection","isActive","queryCommandState","toggle","ItalicInlineTool","LinkInlineTool","commandLink","commandUnlink","ENTER_KEY","buttonUnlink","input","inputShowed","inputOpened","inlineToolbar","toolbar","Selection","addEventListener","keyCode","enterPressed","parentAnchor","findParentTag","expandToTag","unlink","closeActions","checkState","close","toggleActions","anchorTag","openActions","hrefAttr","getAttribute","needFocus","focus","clearSavedSelection","clearSaved","restore","preventDefault","validateURL","prepareLink","insertLink","stopPropagation","stopImmediatePropagation","str","test","link","addProtocol","isInternal","isAnchor","substring","isProtocolRelative","BlocksAPI","index","fromIndex","toIndex","Toolbar","move","blockIndex","removeBlock","insert","Caret","setToBlock","currentBlock","navigatePrevious","clear","EventsAPI","eventName","callback","Events","emit","ListenerAPI","element","eventType","handler","useCapture","Listeners","SanitizerAPI","taintString","Sanitizer","clean","SaverAPI","Saver","SelectionAPI","className","ToolbarAPI","open","caret","saver","BlockEvents","beforeKeydownProcessing","keyCodes","BACKSPACE","backspace","ENTER","enter","DOWN","RIGHT","arrowRightAndDown","UP","LEFT","arrowLeftAndUp","defaultHandler","clearHighlightings","InlineToolbar","handleShowingEvent","apiSettings","IS_ENABLED_LINE_BREAKS","shiftKey","split","newCurrent","isInitial","plusButton","show","BM","isFirstBlock","canMergeBlocks","isAtStart","targetBlock","blockToMerge","mergeable","createShadow","mergeBlocks","restoreCaret","normalize","navigateNext","_blocks","Blocks","redactor","Proxy","set","get","construct","block","bindEvents","keydown","mouseUp","keyup","composeBlock","blockToMergeIndex","indexOf","blockToMergeInfo","mergeWith","extractedFragment","extractFragmentFromCaretPosition","text","blockInserted","currentNode","firstLevelBlock","closest","childNode","parentFirstLevelBlock","Error","needAddInitialBlock","removeAll","dropPointer","isLastBlock","array","workingArea","first","second","secondBlock","deleteCount","splice","previousBlock","insertAdjacentElement","nextBlock","isNaN","newBlock","children","instance","Number","offset","atEnd","nodeToSet","delay","createRange","setStart","setEnd","removeAllRanges","addRange","lastBlock","insertAtEnd","rangeCount","selectRange","getRangeAt","blockElem","deleteContents","cloneRange","selectNodeContents","endContainer","endOffset","extractContents","from","direction","current","siblings","contentEditable","force","isAtEnd","shadowCaret","sel","newRange","selectNode","isCollapsed","anchorNode","firstNode","firstLetterPosition","search","leftSiblings","getHigherLevelSiblings","nothingAtLeft","anchorOffset","lastNode","nothingAtRight","rightTrimmedText","subscribers","reduce","previousData","currentHandler","newData","i","allListeners","assignedEventData","alreadyExist","findOne","existingListeners","findAll","removeEventListener","listenersOnElement","listenersWithType","listenersWithHandler","foundListeners","found","foundByElements","findByElement","filter","chainData","function","insertBlock","sequence","item","available","defaultConfig","_sanitizerInstance","sanitizerConfig","sanitizerInstance","require","customConfig","library","tags","href","rel","newInstance","output","blocksData","all","allExtractedData","makeOutput","outputData","totalTime","groupCollapsed","extraction","groupEnd","Date","version","VERSION","BlockSettings","toolSettings","defaultSettings","renderSettings","renderTunes","wrapperOpened","addToolSettings","addDefaultSettings","opened","closed","contains","inlineToolbarShowed","buttonsWrapper","actionsWrapper","buttons","actions","toolbarVerticalMargin","addTools","allowedToShow","checkToolsState","selectionRect","rect","wrapperOffset","newCoords","x","left","y","floor","style","tagsConflictsWithSelection","currentSelection","selectedText","getBlock","toolConfig","IS_ENABLED_INLINE_TOOLBAR","addTool","renderActions","toolClicked","surround","toolsInstances","inline","Tool","Toolbox","toolbox","toolsAvailable","IS_DISPLAYED_IN_TOOLBOX","TOOLBAR_ICON_CLASS","toolboxButton","title","dataset","buttonClicked","toolButton","toolClasses","IS_IRREPLACEBLE_TOOL","toolboxOpened","blockActionsButtons","settingsToggler","plusButtonClicked","settingsIcon","forceClose","defaultToolbarHeight","defaultOffset","newYCoordinate","offsetTop","transform","toolbarOpened","settingsTogglerClicked","hide","plusButtonHidden","toolsUnavailable","Object","values","IS_INLINE","inlineToolRequiredMethods","notImplementedMethods","hasOwnProperty","reject","sequenceData","getListOfPrepareFunctions","success","fallback","toolPreparationList","toolClass","plugin","appendSVGSprite","loadStyles","getElementById","editorWrapper","editorZone","styles","toString","head","redactorClicked","documentKeydown","documentClicked","defaultBehaviour","keyDownOnEditor","hasPointerToBlock","isAtEditor","highlightCurrentNode","clickedOnInlineToolbarButton","clickedInsideofEditor","clickedNode","setCurrentBlockByChildNode","setToTheLastBlock","isInitialBlock","isEmptyBlock","spriteHolder","sprite","Element","prototype","matches","msMatchesSelector","webkitMatchesSelector","s","documentElement","parentElement","savedSelectionRange","getSelection","searchDepth","parentTag","focusNode","boundNodes","searchDepthIterable","selectedNode","TEXT_NODE","boundingLeft","boundingTop","boundingWidth","boundingHeight","span","insertNode","spanParent","Util","msg","args","chains","previousValue","currentValue","iteration","waitNextBlock","successCallback","fallbackCallback","collection","slice","object","keys","constructor","timeout","context","arguments","apply","TAB","SHIFT","CTRL","ALT","ESC","SPACE","DELETE","META"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;AClFA,4+H;;;;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,mCAAmC,gBAAgB;AACnD,IAAI;AACJ;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAgB,iBAAiB;AACjC;AACA;AACA;AACA;AACA,YAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oDAAoD,cAAc;;AAElE;AACA;;;;;;;;;;;;AC3EA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA,GAAG,QAIH;AACA,CAAC;;AAED;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB;AACA;;AAEA;AACA;;AAEA;AACA,wBAAwB,iCAAiC,EAAE;AAC3D,6BAA6B,uEAAuE,EAAE;;AAEtG;AACA;AACA;;AA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AL,CAAYiC,IAAZ,CAAiBC,KAAjB,GAAyB,CAAEC,YAAF,CAAzB;AACD,OAHD,MAGO;AACL,YAAI,CAAC,KAAKnC,MAAL,CAAYiC,IAAZ,CAAiBC,KAAlB,IAA2B,KAAKlC,MAAL,CAAYiC,IAAZ,CAAiBC,KAAjB,CAAuBc,MAAvB,KAAkC,CAAjE,EAAoE;AAClE,eAAKhD,MAAL,CAAYiC,IAAZ,CAAiBC,KAAjB,GAAyB,CAAEC,YAAF,CAAzB;AACD;AACF;;AAED;;;AAGA,UAAI,CAACnC,OAAOmC,YAAZ,EAA0B;AACxB,aAAK,KAAKnC,MAAL,CAAYmC,YAAjB,IAAiC,KAAKnC,MAAL,CAAY4C,KAA7C;AAAoD;AAApD;AACD,OAFD,MAEO;AACL,aAAK5C,MAAL,CAAYmC,YAAZ,GAA2BnC,OAAOmC,YAAlC;AACD;AACF;;AAED;;;;;wBAIoB;AAClB,aAAO,KAAKnC,MAAZ;AACD;;;;;;;kBAlHkBD,W;AA6MpB;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;AClZA;;;;;;;;;IASqBmB,M;AACjB;;;;AAIA,0BAAwB;AAAA,YAAVlB,MAAU,QAAVA,MAAU;;AAAA;;AACpB,YAAIiD,IAA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AAP;AAKD;;AAED;;;;;;;;+BAKWF,gB,EAAkB;AAC3B,UAAIlb,QAAQ,EAAZ;AAAA,UACEqb,YAAY,CADd;;AAGA5c,cAAQ6c,cAAR,CAAuB,uBAAvB;;AAEAJ,uBAAiBnc,OAAjB,CAAyB,UAACwc,UAAD,EAAgB;AACvC;AACA9c,gBAAQC,GAAR,UAAgB6c,WAAWvW,IAA3B,uBAAgDuW,UAAhD;AACAF,qBAAaE,WAAWpV,IAAxB;AACAnG,cAAMsK,IAAN,CAAW;AACTpK,gBAAMqb,WAAWvW,IADR;AAETjF,gBAAMwb,WAAWxb;AAFR,SAAX;AAID,OARD;;AAUAtB,cAAQC,GAAR,CAAY,OAAZ,EAAqB2c,SAArB;AACA5c,cAAQ+c,QAAR;;AAEA,aAAO;AACLrV,cAAU,CAAC,IAAIsV,IAAJ,EADN;AAELzb,eAAUA,KAFL;AAGL0b,iBAAU,OAAAC;AAHL,OAAP;AAKD;;;;EA5DgC3c,M;;AA+DnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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A;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;kBA5gBqBW,E;;;;;;;;;;;;;;;;AC9BrB;;;;;AAKA,IAAI,CAAC8iB,QAAQC,SAAR,CAAkBC,OAAvB,EACEF,QAAQC,SAAR,CAAkBC,OAAlB,GAA4BF,QAAQC,SAAR,CAAkBE,iBAAlB,IACtBH,QAAQC,SAAR,CAAkBG,qBADxB;;AAGF,IAAI,CAACJ,QAAQC,SAAR,CAAkBpO,OAAvB,EACEmO,QAAQC,SAAR,CAAkBpO,OAAlB,GAA4B,UAAUwO,CAAV,EAAa;AACvC,MAAInb,KAAK,IAAT;;AAEA,MAAI,CAAClB,SAASsc,eAAT,C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","file":"codex-editor.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"CodexEditor\"] = factory();\n\telse\n\t\troot[\"CodexEditor\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/codex.js\");\n","module.exports = \"\\n\\n\\n \\n\\n\\n\\n \\n\\n\\n\\n \\n\\n\\n\\n \\n\\n\\n\\n \\n \\n \\n \\n \\n\\n\\n\\n \\n\\n\\n\\n \\n\\n\\n\\n \\n\\n\\n\\n \\n\\n\"","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\nmodule.exports = function(useSourceMap) {\n\tvar list = [];\n\n\t// return the list of modules as css string\n\tlist.toString = function toString() {\n\t\treturn this.map(function (item) {\n\t\t\tvar content = cssWithMappingToString(item, useSourceMap);\n\t\t\tif(item[2]) {\n\t\t\t\treturn \"@media \" + item[2] + \"{\" + content + \"}\";\n\t\t\t} else {\n\t\t\t\treturn content;\n\t\t\t}\n\t\t}).join(\"\");\n\t};\n\n\t// import a list of modules into the list\n\tlist.i = function(modules, mediaQuery) {\n\t\tif(typeof modules === \"string\")\n\t\t\tmodules = [[null, modules, \"\"]];\n\t\tvar alreadyImportedModules = {};\n\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\tvar id = this[i][0];\n\t\t\tif(typeof id === \"number\")\n\t\t\t\talreadyImportedModules[id] = true;\n\t\t}\n\t\tfor(i = 0; i < modules.length; i++) {\n\t\t\tvar item = modules[i];\n\t\t\t// skip already imported module\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\n\t\t\t// when a module is imported multiple times with different media queries.\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\n\t\t\t\tif(mediaQuery && !item[2]) {\n\t\t\t\t\titem[2] = mediaQuery;\n\t\t\t\t} else if(mediaQuery) {\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\n\t\t\t\t}\n\t\t\t\tlist.push(item);\n\t\t\t}\n\t\t}\n\t};\n\treturn list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n\tvar content = item[1] || '';\n\tvar cssMapping = item[3];\n\tif (!cssMapping) {\n\t\treturn content;\n\t}\n\n\tif (useSourceMap && typeof btoa === 'function') {\n\t\tvar sourceMapping = toComment(cssMapping);\n\t\tvar sourceURLs = cssMapping.sources.map(function (source) {\n\t\t\treturn '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'\n\t\t});\n\n\t\treturn [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n\t}\n\n\treturn [content].join('\\n');\n}\n\n// Adapted from convert-source-map (MIT)\nfunction toComment(sourceMap) {\n\t// eslint-disable-next-line no-undef\n\tvar base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n\tvar data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;\n\n\treturn '/*# ' + data + ' */';\n}\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 var sandbox = document.createElement('div');\n sandbox.innerHTML = html;\n\n this._sanitize(sandbox);\n\n return sandbox.innerHTML;\n };\n\n HTMLJanitor.prototype._sanitize = function (parentNode) {\n var treeWalker = createTreeWalker(parentNode);\n var node = treeWalker.firstChild();\n if (!node) { return; }\n\n do {\n // Ignore nodes that have already been sanitized\n if (node._sanitized) {\n continue;\n }\n\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(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(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.
  • ...); 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(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(node);\n\n // Mark node as sanitized so it's ignored in future runs\n node._sanitized = true;\n } while ((node = treeWalker.nextSibling()));\n };\n\n function createTreeWalker(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","/**\n * Codex Editor\n *\n * Short Description (눈_눈;)\n * @version 2.0.0\n *\n * How to start?\n * Example:\n * new CodexEditor({\n * holderId : 'codex-editor',\n * initialBlock : 'text',\n * placeholder : 'Write your story....',\n * tools: {\n * quote: Quote,\n * anotherTool : AnotherTool\n * },\n * toolsConfig: {\n * quote: {\n * iconClassname : 'quote-icon',\n * displayInToolbox : true,\n * enableLineBreaks : true\n * },\n * anotherTool: {\n * iconClassname : 'tool-icon'\n * }\n * }\n * });\n *\n * - tools is an object: {\n * pluginName: PluginClass,\n * .....\n * }\n * - toolsConfig is an additional configuration that uses Codex Editor API\n * iconClassname - CSS classname of toolbox icon\n * displayInToolbox - if you want to see your Tool in toolbox hided in \"plus\" button, than set \"True\". By default : \"False\"\n * enableLineBreaks - by default enter creates new block that set as initialblock, but if you set this property \"True\", enter will break the lines in current block\n *\n * @author CodeX-Team \n *\n */\n\n/**\n * @typedef {CodexEditor} CodexEditor - editor class\n */\n\n/**\n * @typedef {Object} EditorConfig\n * @property {String} holderId - Element to append Editor\n * @property {Array} data - Blocks list in JSON-format\n * @property {Object} tools - Map for used Tools in format { name : Class, ... }\n * @property {String} initialBlock - This Tool will be added by default\n * @property {String} placeholder - First Block placeholder\n * @property {Object} sanitizer - @todo fill desc\n * @property {Boolean} hideToolbar - @todo fill desc\n * @property {Object} toolsConfig - tools configuration {@link tools#ToolConfig}\n */\n\n/**\n * Dynamically imported utils\n *\n * @typedef {Dom} $ - {@link components/dom.js}\n * @typedef {Util} _ - {@link components/utils.js}\n */\n\n'use strict';\n\n/**\n * Apply polyfills\n */\nimport 'components/polyfills';\n\n/**\n * Require Editor modules places in components/modules dir\n */\n// eslint-disable-next-line\nlet modules = editorModules.map( module => require('./components/modules/' + module ));\n\n/**\n * @class\n *\n * @classdesc CodeX Editor base class\n *\n * @property this.config - all settings\n * @property this.moduleInstances - constructed editor components\n *\n * @type {CodexEditor}\n */\nexport default class CodexEditor {\n /** Editor version */\n static get version() {\n return VERSION;\n }\n\n /**\n * @param {EditorConfig} config - user configuration\n *\n */\n constructor(config) {\n /**\n * Configuration object\n * @type {EditorConfig}\n */\n this.config = {};\n\n /**\n * @typedef {Object} EditorComponents\n * @property {BlockManager} BlockManager\n * @property {Tools} Tools\n * @property {Events} Events\n * @property {UI} UI\n * @property {Toolbar} Toolbar\n * @property {Toolbox} Toolbox\n * @property {BlockSettings} BlockSettings\n * @property {Renderer} Renderer\n * @property {InlineToolbar} InlineToolbar\n */\n this.moduleInstances = {};\n\n Promise.resolve()\n .then(() => {\n this.configuration = config;\n })\n .then(() => this.init())\n .then(() => this.start())\n .then(() => {\n let methods = this.moduleInstances.API.methods;\n\n /**\n * Make API methods available from inside easier\n */\n for (let method in methods) {\n this[method] = methods[method];\n }\n\n // todo Is it necessary?\n delete this.moduleInstances;\n })\n .then(() => {\n console.log('CodeX Editor is ready!');\n })\n .catch(error => {\n console.log('CodeX Editor does not ready because of %o', error);\n });\n }\n\n /**\n * Setting for configuration\n * @param {EditorConfig} config\n */\n set configuration(config) {\n /**\n * Initlai block type\n * Uses in case when there is no items passed\n * @type {{type: (*), data: {text: null}}}\n */\n let initialBlock = {\n type : config.initialBlock,\n data : {}\n };\n\n this.config.holderId = config.holderId;\n this.config.placeholder = config.placeholder || 'write your story...';\n this.config.sanitizer = config.sanitizer || {\n p: true,\n b: true,\n a: true\n };\n\n this.config.hideToolbar = config.hideToolbar ? config.hideToolbar : false;\n this.config.tools = config.tools || {};\n this.config.toolsConfig = config.toolsConfig || {};\n this.config.data = config.data || {};\n\n /**\n * Initialize items to pass data to the Renderer\n */\n if (_.isEmpty(this.config.data)) {\n this.config.data = {};\n this.config.data.items = [ initialBlock ];\n } else {\n if (!this.config.data.items || this.config.data.items.length === 0) {\n this.config.data.items = [ initialBlock ];\n }\n }\n\n /**\n * If initial Block's Tool was not passed, use the first Tool in config.tools\n */\n if (!config.initialBlock) {\n for (this.config.initialBlock in this.config.tools) break;\n } else {\n this.config.initialBlock = config.initialBlock;\n }\n }\n\n /**\n * Returns private property\n * @returns {EditorConfig}\n */\n get configuration() {\n return this.config;\n }\n\n /**\n * Initializes modules:\n * - make and save instances\n * - configure\n */\n init() {\n /**\n * Make modules instances and save it to the @property this.moduleInstances\n */\n this.constructModules();\n\n /**\n * Modules configuration\n */\n this.configureModules();\n }\n\n /**\n * Make modules instances and save it to the @property this.moduleInstances\n */\n constructModules() {\n modules.forEach( Module => {\n try {\n /**\n * We use class name provided by displayName property\n *\n * On build, Babel will transform all Classes to the Functions so, name will always be 'Function'\n * To prevent this, we use 'babel-plugin-class-display-name' plugin\n * @see https://www.npmjs.com/package/babel-plugin-class-display-name\n */\n this.moduleInstances[Module.displayName] = new Module({\n config : this.configuration\n });\n } catch ( e ) {\n console.log('Module %o skipped because %o', Module, e);\n }\n });\n }\n\n /**\n * Modules instances configuration:\n * - pass other modules to the 'state' property\n * - ...\n */\n configureModules() {\n for(let name in this.moduleInstances) {\n /**\n * Module does not need self-instance\n */\n this.moduleInstances[name].state = this.getModulesDiff( name );\n }\n }\n\n /**\n * Return modules without passed name\n */\n getModulesDiff( name ) {\n let diff = {};\n\n for(let moduleName in this.moduleInstances) {\n /**\n * Skip module with passed name\n */\n if (moduleName === name) {\n continue;\n }\n diff[moduleName] = this.moduleInstances[moduleName];\n }\n\n return diff;\n }\n\n /**\n * Start Editor!\n *\n * Get list of modules that needs to be prepared and return a sequence (Promise)\n * @return {Promise}\n */\n start() {\n let prepareDecorator = module => module.prepare();\n\n return Promise.resolve()\n .then(prepareDecorator(this.moduleInstances.Tools))\n .then(prepareDecorator(this.moduleInstances.UI))\n .then(prepareDecorator(this.moduleInstances.BlockManager))\n .then(() => {\n return this.moduleInstances.Renderer.render(this.config.data.items);\n });\n }\n};\n\n// module.exports = (function (editor) {\n//\n// 'use strict';\n//\n// editor.version = VERSION;\n// editor.scriptPrefix = 'cdx-script-';\n//\n// var init = function () {\n//\n// editor.core = require('./modules/core');\n// editor.tools = require('./modules/tools');\n// editor.ui = require('./modules/ui');\n// editor.transport = require('./modules/transport');\n// editor.renderer = require('./modules/renderer');\n// editor.saver = require('./modules/saver');\n// editor.content = require('./modules/content');\n// editor.toolbar = require('./modules/toolbar/toolbar');\n// editor.callback = require('./modules/callbacks');\n// editor.draw = require('./modules/draw');\n// editor.caret = require('./modules/caret');\n// editor.notifications = require('./modules/notifications');\n// editor.parser = require('./modules/parser');\n// editor.sanitizer = require('./modules/sanitizer');\n// editor.listeners = require('./modules/listeners');\n// editor.destroyer = require('./modules/destroyer');\n// editor.paste = require('./modules/paste');\n//\n// };\n//\n// /**\n// * @public\n// * holds initial settings\n// */\n// editor.settings = {\n// tools : ['text', 'header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'],\n// holderId : 'codex-editor',\n//\n// // Type of block showing on empty editor\n// initialBlockPlugin: 'text'\n// };\n//\n// /**\n// * public\n// *\n// * Static nodes\n// */\n// editor.nodes = {\n// holder : null,\n// wrapper : null,\n// toolbar : null,\n// inlineToolbar : {\n// wrapper : null,\n// buttons : null,\n// actions : null\n// },\n// toolbox : null,\n// notifications : null,\n// plusButton : null,\n// showSettingsButton: null,\n// showTrashButton : null,\n// blockSettings : null,\n// pluginSettings : null,\n// defaultSettings : null,\n// toolbarButtons : {}, // { type : DomEl, ... }\n// redactor : null\n// };\n//\n// /**\n// * @public\n// *\n// * Output state\n// */\n// editor.state = {\n// jsonOutput : [],\n// blocks : [],\n// inputs : []\n// };\n//\n// /**\n// * @public\n// * Editor plugins\n// */\n// editor.tools = {};\n//\n// editor.start = function (userSettings) {\n//\n// init();\n//\n// editor.core.prepare(userSettings)\n//\n// // If all ok, make UI, bind events and parse initial-content\n// .then(editor.ui.prepare)\n// .then(editor.tools.prepare)\n// .then(editor.sanitizer.prepare)\n// .then(editor.paste.prepare)\n// .then(editor.transport.prepare)\n// .then(editor.renderer.makeBlocksFromData)\n// .then(editor.ui.saveInputs)\n// .catch(function (error) {\n//\n// editor.core.log('Initialization failed with error: %o', 'warn', error);\n//\n// });\n//\n// };\n//\n// return editor;\n//\n// })({});\n","/**\n * @abstract\n * @class Module\n * @classdesc All modules inherits from this class.\n *\n * @typedef {Module} Module\n * @property {Object} config - Editor user settings\n * @property {IEditorConfig} Editor - List of Editor modules\n */\nexport default class Module {\n /**\n * @constructor\n * @param {IModuleConfig}\n */\n constructor({ config }) {\n if (new.target === Module) {\n throw new TypeError('Constructors for abstract class Module are not allowed.');\n }\n this.config = config;\n }\n /**\n * Editor modules setter\n * @param {IEditor} Editor\n */\n set state(Editor) {\n this.Editor = Editor;\n }\n}\n","export default class DeleteTune {\n /**\n * DeleteTune constructor\n *\n * @param {Object} api\n */\n constructor({ api }) {\n /**\n * Styles\n * @type {{wrapper: string}}\n */\n this.CSS = {\n wrapper: 'ass',\n button: 'ce-settings__button',\n buttonDelete: 'ce-settings__button--delete',\n buttonConfirm: 'ce-settings__button--confirm',\n };\n /**\n * Tune nodes\n */\n this.nodes = {\n button: null,\n };\n this.api = api;\n this.resetConfirmation = () => {\n this.setConfirmation(false);\n };\n }\n /**\n * Create \"Delete\" button and add click event listener\n * @returns [Element}\n */\n render() {\n this.nodes.button = $.make('div', [this.CSS.button, this.CSS.buttonDelete], {});\n this.nodes.button.appendChild($.svg('cross', 12, 12));\n this.api.listener.on(this.nodes.button, 'click', (event) => this.handleClick(event), false);\n return this.nodes.button;\n }\n /**\n * Delete block conditions passed\n * @param {MouseEvent} event\n */\n handleClick(event) {\n /**\n * if block is not waiting the confirmation, subscribe on block-settings-closing event to reset\n * otherwise delete block\n */\n if (!this.needConfirmation) {\n this.setConfirmation(true);\n /**\n * Subscribe on event.\n * When toolbar block settings is closed but block deletion is not confirmed,\n * then reset confirmation state\n */\n this.api.events.on('block-settings-closed', this.resetConfirmation);\n }\n else {\n /**\n * Unsubscribe from block-settings closing event\n */\n this.api.events.off('block-settings-closed', this.resetConfirmation);\n this.api.blocks.delete();\n }\n }\n /**\n * change tune state\n */\n setConfirmation(state) {\n this.needConfirmation = state;\n this.nodes.button.classList.add(this.CSS.buttonConfirm);\n }\n}\n","export default class MoveDownTune {\n /**\n * MoveDownTune constructor\n *\n * @param {Object} api\n */\n constructor({ api }) {\n /**\n * Styles\n * @type {{wrapper: string}}\n */\n this.CSS = {\n button: 'ce-settings__button',\n wrapper: 'ce-tune-move-down',\n animation: 'wobble',\n };\n this.api = api;\n }\n /**\n * Return 'move down' button\n */\n render() {\n const moveDownButton = $.make('div', [this.CSS.button, this.CSS.wrapper], {});\n moveDownButton.appendChild($.svg('arrow-down', 14, 14));\n this.api.listener.on(moveDownButton, 'click', (event) => this.handleClick(event, moveDownButton), false);\n return moveDownButton;\n }\n /**\n * Handle clicks on 'move down' button\n * @param {MouseEvent} event\n * @param {HTMLElement} button\n */\n handleClick(event, button) {\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\n // If Block is last do nothing\n if (currentBlockIndex === this.api.blocks.getBlocksCount() - 1) {\n button.classList.add(this.CSS.animation);\n window.setTimeout(() => {\n button.classList.remove(this.CSS.animation);\n }, 500);\n return;\n }\n const nextBlockElement = this.api.blocks.getBlockByIndex(currentBlockIndex + 1).holder, nextBlockCoords = nextBlockElement.getBoundingClientRect();\n let scrollOffset = Math.abs(window.innerHeight - nextBlockElement.offsetHeight);\n /**\n * Next block ends on screen.\n * Increment scroll by next block's height to save element onscreen-position\n */\n if (nextBlockCoords.top < window.innerHeight) {\n scrollOffset = window.scrollY + nextBlockElement.offsetHeight;\n }\n window.scrollTo(0, scrollOffset);\n /** Change blocks positions */\n this.api.blocks.swap(currentBlockIndex, currentBlockIndex + 1);\n }\n}\n","export default class MoveUpTune {\n /**\n * MoveUpTune constructor\n *\n * @param {Object} api\n */\n constructor({ api }) {\n /**\n * Styles\n * @type {{wrapper: string}}\n */\n this.CSS = {\n button: 'ce-settings__button',\n wrapper: 'ce-tune-move-up',\n animation: 'wobble',\n };\n this.api = api;\n }\n /**\n * Create \"MoveUp\" button and add click event listener\n * @returns [Element}\n */\n render() {\n const moveUpButton = $.make('div', [this.CSS.button, this.CSS.wrapper], {});\n moveUpButton.appendChild($.svg('arrow-up', 14, 14));\n this.api.listener.on(moveUpButton, 'click', (event) => this.handleClick(event, moveUpButton), false);\n return moveUpButton;\n }\n /**\n * Move current block up\n * @param {MouseEvent} event\n * @param {HTMLElement} button\n */\n handleClick(event, button) {\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\n if (currentBlockIndex === 0) {\n button.classList.add(this.CSS.animation);\n window.setTimeout(() => {\n button.classList.remove(this.CSS.animation);\n }, 500);\n return;\n }\n const currentBlockElement = this.api.blocks.getBlockByIndex(currentBlockIndex).holder, previousBlockElement = this.api.blocks.getBlockByIndex(currentBlockIndex - 1).holder;\n /**\n * Here is two cases:\n * - when previous block has negative offset and part of it is visible on window, then we scroll\n * by window's height and add offset which is mathematically difference between two blocks\n *\n * - when previous block is visible and has offset from the window,\n * than we scroll window to the difference between this offsets.\n */\n const currentBlockCoords = currentBlockElement.getBoundingClientRect(), previousBlockCoords = previousBlockElement.getBoundingClientRect();\n let scrollUpOffset;\n if (previousBlockCoords.top > 0) {\n scrollUpOffset = Math.abs(currentBlockCoords.top) - Math.abs(previousBlockCoords.top);\n }\n else {\n scrollUpOffset = window.innerHeight - Math.abs(currentBlockCoords.top) + Math.abs(previousBlockCoords.top);\n }\n window.scrollBy(0, -1 * scrollUpOffset);\n /** Change blocks positions */\n this.api.blocks.swap(currentBlockIndex, currentBlockIndex - 1);\n }\n}\n","/**\n * @class Block\n * @classdesc This class describes editor`s block, including block`s HTMLElement, data and tool\n *\n * @property {Tool} tool — current block tool (Paragraph, for example)\n * @property {Object} CSS — block`s css classes\n *\n */\n\n/** Import default tunes */\nimport MoveUpTune from './block-tunes/block-tune-move-up';\nimport DeleteTune from './block-tunes/block-tune-delete';\nimport MoveDownTune from './block-tunes/block-tune-move-down';\n\n/**\n * @classdesc Abstract Block class that contains Block information, Tool name and Tool class instance\n *\n * @property tool - Tool instance\n * @property html - Returns HTML content of plugin\n * @property holder - Div element that wraps block content with Tool's content. Has `ce-block` CSS class\n * @property pluginsContent - HTML content that returns by Tool's render function\n */\nexport default class Block {\n /**\n * @constructor\n * @param {String} toolName - Tool name that passed on initialization\n * @param {Object} toolInstance — passed Tool`s instance that rendered the Block\n * @param {Object} settings - default settings\n * @param {Object} apiMethods - Editor API\n */\n constructor(toolName, toolInstance, settings, apiMethods) {\n this.name = toolName;\n this.tool = toolInstance;\n this.settings = settings;\n this.api = apiMethods;\n this.holder = this.compose();\n\n /**\n * @type {IBlockTune[]}\n */\n this.tunes = this.makeTunes();\n }\n\n /**\n * CSS classes for the Block\n * @return {{wrapper: string, content: string}}\n */\n static get CSS() {\n return {\n wrapper: 'ce-block',\n content: 'ce-block__content',\n selected: 'ce-block--selected'\n };\n }\n\n /**\n * Make default Block wrappers and put Tool`s content there\n * @returns {HTMLDivElement}\n */\n compose() {\n let wrapper = $.make('div', Block.CSS.wrapper),\n contentNode = $.make('div', Block.CSS.content),\n pluginsContent = this.tool.render();\n\n contentNode.appendChild(pluginsContent);\n wrapper.appendChild(contentNode);\n return wrapper;\n }\n\n /**\n * Calls Tool's method\n *\n * Method checks tool property {MethodName}. Fires method with passes params If it is instance of Function\n *\n * @param {String} methodName\n * @param {Object} params\n */\n call(methodName, params) {\n /**\n * call Tool's method with the instance context\n */\n if (this.tool[methodName] && this.tool[methodName] instanceof Function) {\n this.tool[methodName].call(this.tool, params);\n }\n }\n\n /**\n * Returns Plugins content\n * @return {Node}\n */\n get pluginsContent() {\n let pluginsContent = this.holder.querySelector(`.${Block.CSS.content}`);\n\n if (pluginsContent && pluginsContent.childNodes.length) {\n return pluginsContent.childNodes[0];\n }\n\n return null;\n }\n\n /**\n * Get Block's JSON data\n * @return {Object}\n */\n get data() {\n return this.save();\n }\n\n /**\n * is block mergeable\n * We plugin have merge function then we call it mergable\n * @return {boolean}\n */\n get mergeable() {\n return typeof this.tool.merge === 'function';\n }\n\n /**\n * Call plugins merge method\n * @param {Object} data\n */\n mergeWith(data) {\n return Promise.resolve()\n .then(() => {\n this.tool.merge(data);\n });\n }\n /**\n * Extracts data from Block\n * Groups Tool's save processing time\n * @return {Object}\n */\n save() {\n let extractedBlock = this.tool.save(this.pluginsContent);\n\n /** Measuring execution time*/\n let measuringStart = window.performance.now(),\n measuringEnd;\n\n return Promise.resolve(extractedBlock)\n .then((finishedExtraction) => {\n /** measure promise execution */\n measuringEnd = window.performance.now();\n\n return {\n tool: this.name,\n data: finishedExtraction,\n time : measuringEnd - measuringStart\n };\n })\n .catch(function (error) {\n _.log(`Saving proccess for ${this.tool.name} tool failed due to the ${error}`, 'log', 'red');\n });\n }\n\n /**\n * Uses Tool's validation method to check the correctness of output data\n * Tool's validation method is optional\n *\n * @description Method also can return data if it passed the validation\n *\n * @param {Object} data\n * @returns {Boolean|Object} valid\n */\n validateData(data) {\n let isValid = true;\n\n if (this.tool.validate instanceof Function) {\n isValid = this.tool.validate(data);\n }\n\n if (!isValid) {\n return false;\n }\n\n return data;\n }\n\n /**\n * Make an array with default settings\n * Each block has default tune instance that have states\n * @return {IBlockTune[]}\n */\n makeTunes() {\n let tunesList = [MoveUpTune, DeleteTune, MoveDownTune];\n\n // Pluck tunes list and return tune instances with passed Editor API and settings\n return tunesList.map( (tune) => {\n return new tune({\n api: this.api,\n settings: this.settings,\n });\n });\n }\n\n /**\n * Enumerates initialized tunes and returns fragment that can be appended to the toolbars area\n * @return {DocumentFragment}\n */\n renderTunes() {\n let tunesElement = document.createDocumentFragment();\n\n this.tunes.forEach( tune => {\n $.append(tunesElement, tune.render());\n });\n\n return tunesElement;\n }\n\n /**\n * Check block for emptiness\n * @return {Boolean}\n */\n get isEmpty() {\n /**\n * Allow Tool to represent decorative contentless blocks: for example \"* * *\"-tool\n * That Tools are not empty\n */\n if (this.tool.contentless) {\n return false;\n }\n\n let emptyText = $.isEmpty(this.pluginsContent),\n emptyMedia = !this.hasMedia;\n\n return emptyText && emptyMedia;\n }\n\n /**\n * Check if block has a media content such as images, iframes and other\n * @return {Boolean}\n */\n get hasMedia() {\n /**\n * This tags represents media-content\n * @type {string[]}\n */\n const mediaTags = [\n 'img',\n 'iframe',\n 'video',\n 'audio',\n 'source',\n 'input',\n 'textarea',\n 'twitterwidget'\n ];\n\n return !!this.holder.querySelector(mediaTags.join(','));\n }\n\n /**\n * Set selected state\n * @param {Boolean} state - 'true' to select, 'false' to remove selection\n */\n set selected(state) {\n /**\n * We don't need to mark Block as Selected when it is not empty\n */\n if (state === true && !this.isEmpty) {\n this.holder.classList.add(Block.CSS.selected);\n } else {\n this.holder.classList.remove(Block.CSS.selected);\n }\n }\n}\n","/**\n * DOM manipulations helper\n */\nexport default class Dom {\n /**\n * Check if passed tag has no closed tag\n * @param {Element} tag\n * @return {Boolean}\n */\n static isSingleTag(tag) {\n return tag.tagName && ['AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR'].includes(tag.tagName);\n };\n\n\n /**\n * Helper for making Elements with classname and attributes\n *\n * @param {string} tagName - new Element tag name\n * @param {array|string} classNames - list or name of CSS classname(s)\n * @param {Object} attributes - any attributes\n * @return {Element}\n */\n static make(tagName, classNames = null, attributes = {}) {\n let el = document.createElement(tagName);\n\n if ( Array.isArray(classNames) ) {\n el.classList.add(...classNames);\n } else if( classNames ) {\n el.classList.add(classNames);\n }\n\n for (let attrName in attributes) {\n el[attrName] = attributes[attrName];\n }\n\n return el;\n }\n\n /**\n * Creates Text Node with the passed content\n * @param {String} content - text content\n * @return {Text}\n */\n static text(content) {\n return document.createTextNode(content);\n }\n\n /**\n * Creates SVG icon linked to the sprite\n * @param {string} name - name (id) of icon from sprite\n * @param {number} width\n * @param {number} height\n * @return {SVGElement}\n */\n static svg(name, width = 14, height = 14) {\n let icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n\n icon.classList.add('icon', 'icon--' + name);\n icon.setAttribute('width', width + 'px');\n icon.setAttribute('height', height + 'px');\n icon.innerHTML = ``;\n\n return icon;\n }\n\n /**\n * Append one or several elements to the parent\n *\n * @param {Element} parent - where to append\n * @param {Element|Element[]} - element ore elements list\n */\n static append(parent, elements) {\n if ( Array.isArray(elements) ) {\n elements.forEach( el => parent.appendChild(el) );\n } else {\n parent.appendChild(elements);\n }\n }\n\n /**\n * Swap two elements in parent\n * @param {HTMLElement} el1 - from\n * @param {HTMLElement} el2 - to\n */\n static swap(el1, el2) {\n // create marker element and insert it where el1 is\n const temp = document.createElement('div'),\n parent = el1.parentNode;\n\n parent.insertBefore(temp, el1);\n\n // move el1 to right before el2\n parent.insertBefore(el1, el2);\n\n // move el2 to right before where el1 used to be\n parent.insertBefore(el2, temp);\n\n // remove temporary marker node\n parent.removeChild(temp);\n }\n\n /**\n * Selector Decorator\n *\n * Returns first match\n *\n * @param {Element} el - element we searching inside. Default - DOM Document\n * @param {String} selector - searching string\n *\n * @returns {Element}\n */\n static find(el = document, selector) {\n return el.querySelector(selector);\n }\n\n /**\n * Selector Decorator.\n *\n * Returns all matches\n *\n * @param {Element} el - element we searching inside. Default - DOM Document\n * @param {String} selector - searching string\n * @returns {NodeList}\n */\n static findAll(el = document, selector) {\n return el.querySelectorAll(selector);\n }\n\n /**\n * Search for deepest node which is Leaf.\n * Leaf is the vertex that doesn't have any child nodes\n *\n * @description Method recursively goes throw the all Node until it finds the Leaf\n *\n * @param {Node} node - root Node. From this vertex we start Deep-first search {@link https://en.wikipedia.org/wiki/Depth-first_search}\n * @param {Boolean} atLast - find last text node\n * @return {Node} - it can be text Node or Element Node, so that caret will able to work with it\n */\n static getDeepestNode(node, 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 * @type {string}\n */\n let child = atLast ? 'lastChild' : 'firstChild',\n sibling = atLast ? 'previousSibling' : 'nextSibling';\n\n if (node && node.nodeType === Node.ELEMENT_NODE && node[child]) {\n let nodeChild = node[child];\n\n /**\n * special case when child is single tag that can't contain any content\n */\n if (Dom.isSingleTag(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 } else if (nodeChild.parentNode[sibling]) {\n nodeChild = nodeChild.parentNode[sibling];\n } else {\n return nodeChild.parentNode;\n }\n }\n\n return this.getDeepestNode(nodeChild, atLast);\n }\n\n return node;\n }\n\n /**\n * Check if object is DOM node\n *\n * @param {Object} node\n * @returns {boolean}\n */\n static isElement(node) {\n return node && typeof node === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE;\n }\n\n /**\n * Checks target if it is native input\n * @param {Element|String|Node} target - HTML element or string\n * @return {Boolean}\n */\n static isNativeInput(target) {\n let nativeInputs = [\n 'INPUT',\n 'TEXTAREA'\n ];\n\n return target ? nativeInputs.includes(target.tagName) : false;\n }\n\n /**\n * Checks node if it is empty\n *\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 *\n * @param {Node} node\n * @return {Boolean} true if it is empty\n */\n static isNodeEmpty(node) {\n let nodeText;\n\n if ( this.isElement(node) && this.isNativeInput(node) ) {\n nodeText = node.value;\n } else {\n nodeText = node.textContent.replace('\\u200B', '');\n }\n\n return nodeText.trim().length === 0;\n }\n\n /**\n * checks node if it is doesn't have any child nodes\n * @param {Node} node\n * @return {boolean}\n */\n static isLeaf(node) {\n if (!node) {\n return false;\n }\n\n return node.childNodes.length === 0;\n }\n\n /**\n * breadth-first search (BFS)\n * {@link https://en.wikipedia.org/wiki/Breadth-first_search}\n *\n * @description Pushes to stack all DOM leafs and checks for emptiness\n *\n * @param {Node} node\n * @return {boolean}\n */\n static isEmpty(node) {\n let treeWalker = [],\n leafs = [];\n\n if (!node) {\n return true;\n }\n\n if (!node.childNodes.length) {\n return this.isNodeEmpty(node);\n }\n\n treeWalker.push(node.firstChild);\n\n while ( treeWalker.length > 0 ) {\n node = treeWalker.shift();\n\n if (!node) continue;\n\n if ( this.isLeaf(node) ) {\n leafs.push(node);\n } else {\n treeWalker.push(node.firstChild);\n }\n\n while ( node && node.nextSibling ) {\n node = node.nextSibling;\n\n if (!node) continue;\n\n treeWalker.push(node);\n }\n\n /**\n * If one of childs is not empty, checked Node is not empty too\n */\n if (node && !this.isNodeEmpty(node)) {\n return false;\n }\n }\n\n return leafs.every( leaf => this.isNodeEmpty(leaf) );\n }\n};\n","/**\n * Bold Tool\n *\n * Inline Toolbar Tool\n *\n * Makes selected text bolder\n */\nexport default class BoldInlineTool {\n constructor(api) {\n /**\n * Native Document's command that uses for Bold\n */\n this.commandName = 'bold';\n /**\n * Styles\n */\n this.CSS = {\n button: 'ce-inline-tool',\n buttonActive: 'ce-inline-tool--active',\n buttonModifier: 'ce-inline-tool--bold',\n };\n /**\n * Elements\n */\n this.nodes = {\n button: null,\n };\n console.log('Bold Inline Tool is ready');\n }\n /**\n * Create button for Inline Toolbar\n */\n render() {\n this.nodes.button = document.createElement('button');\n this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);\n this.nodes.button.appendChild($.svg('bold', 13, 15));\n return this.nodes.button;\n }\n /**\n * Wrap range with tag\n * @param {Range} range\n */\n surround(range) {\n document.execCommand(this.commandName);\n }\n /**\n * Check selection and set activated state to button if there are tag\n * @param {Selection} selection\n */\n checkState(selection) {\n const isActive = document.queryCommandState(this.commandName);\n this.nodes.button.classList.toggle(this.CSS.buttonActive, isActive);\n return isActive;\n }\n}\n","/**\n * Italic Tool\n *\n * Inline Toolbar Tool\n *\n * Style selected text with italic\n */\nexport default class ItalicInlineTool {\n constructor(api) {\n /**\n * Native Document's command that uses for Italic\n */\n this.commandName = 'italic';\n /**\n * Styles\n */\n this.CSS = {\n button: 'ce-inline-tool',\n buttonActive: 'ce-inline-tool--active',\n buttonModifier: 'ce-inline-tool--italic',\n };\n /**\n * Elements\n */\n this.nodes = {\n button: null,\n };\n console.log('Italic Inline Tool is ready');\n }\n /**\n * Create button for Inline Toolbar\n */\n render() {\n this.nodes.button = document.createElement('button');\n this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);\n this.nodes.button.appendChild($.svg('italic', 6, 15));\n return this.nodes.button;\n }\n /**\n * Wrap range with tag\n * @param {Range} range\n */\n surround(range) {\n document.execCommand(this.commandName);\n }\n /**\n * Check selection and set activated state to button if there are tag\n * @param {Selection} selection\n */\n checkState(selection) {\n const isActive = document.queryCommandState(this.commandName);\n this.nodes.button.classList.toggle(this.CSS.buttonActive, isActive);\n return isActive;\n }\n}\n","import Selection from '../selection';\n/**\n * Link Tool\n *\n * Inline Toolbar Tool\n *\n * Wrap selected text with tag\n */\nexport default class LinkInlineTool {\n /**\n * @param {object} api - CodeX Editor API\n * @param {object} api.toolbar - Inline Toolbar API\n */\n constructor(api) {\n /**\n * Native Document's commands for link/unlink\n */\n this.commandLink = 'createLink';\n this.commandUnlink = 'unlink';\n /**\n * Enter key code\n */\n this.ENTER_KEY = 13;\n /**\n * Styles\n */\n this.CSS = {\n button: 'ce-inline-tool',\n buttonActive: 'ce-inline-tool--active',\n buttonModifier: 'ce-inline-tool--link',\n buttonUnlink: 'ce-inline-tool--unlink',\n input: 'ce-inline-tool-input',\n inputShowed: 'ce-inline-tool-input--showed',\n };\n /**\n * Elements\n */\n this.nodes = {\n button: null,\n input: null,\n };\n /**\n * Input opening state\n */\n this.inputOpened = false;\n this.inlineToolbar = api.toolbar;\n this.selection = new Selection();\n }\n /**\n * Create button for Inline Toolbar\n */\n render() {\n this.nodes.button = document.createElement('button');\n this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);\n this.nodes.button.appendChild($.svg('link', 15, 14));\n this.nodes.button.appendChild($.svg('unlink', 16, 18));\n return this.nodes.button;\n }\n /**\n * Input for the link\n */\n renderActions() {\n this.nodes.input = document.createElement('input');\n this.nodes.input.placeholder = 'Add a link';\n this.nodes.input.classList.add(this.CSS.input);\n this.nodes.input.addEventListener('keydown', (event) => {\n if (event.keyCode === this.ENTER_KEY) {\n this.enterPressed(event);\n }\n });\n return this.nodes.input;\n }\n /**\n * Handle clicks on the Inline Toolbar icon\n * @param {Range} range\n */\n surround(range) {\n /**\n * Range will be null when user makes second click on the 'link icon' to close opened input\n */\n if (range) {\n /**\n * Save selection before change focus to the input\n */\n this.selection.save();\n const parentAnchor = this.selection.findParentTag('A');\n /**\n * Unlink icon pressed\n */\n if (parentAnchor) {\n this.selection.expandToTag(parentAnchor);\n this.unlink();\n this.closeActions();\n this.checkState();\n this.inlineToolbar.close();\n return;\n }\n }\n this.toggleActions();\n }\n /**\n * Check selection and set activated state to button if there are tag\n * @param {Selection} selection\n */\n checkState(selection) {\n const anchorTag = this.selection.findParentTag('A');\n if (anchorTag) {\n this.nodes.button.classList.add(this.CSS.buttonUnlink);\n this.nodes.button.classList.add(this.CSS.buttonActive);\n this.openActions();\n /**\n * Fill input value with link href\n */\n const hrefAttr = anchorTag.getAttribute('href');\n this.nodes.input.value = hrefAttr !== 'null' ? hrefAttr : '';\n this.selection.save();\n }\n else {\n this.nodes.button.classList.remove(this.CSS.buttonUnlink);\n this.nodes.button.classList.remove(this.CSS.buttonActive);\n }\n return !!anchorTag;\n }\n /**\n * Function called with Inline Toolbar closing\n */\n clear() {\n this.closeActions();\n }\n toggleActions() {\n if (!this.inputOpened) {\n this.openActions(true);\n }\n else {\n this.closeActions(false);\n }\n }\n /**\n * @param {boolean} needFocus - on link creation we need to focus input. On editing - nope.\n */\n openActions(needFocus = false) {\n this.nodes.input.classList.add(this.CSS.inputShowed);\n if (needFocus) {\n this.nodes.input.focus();\n }\n this.inputOpened = true;\n }\n /**\n * Close input\n * @param {boolean} clearSavedSelection — we don't need to clear saved selection\n * on toggle-clicks on the icon of opened Toolbar\n */\n closeActions(clearSavedSelection = true) {\n this.nodes.input.classList.remove(this.CSS.inputShowed);\n this.nodes.input.value = '';\n if (clearSavedSelection) {\n this.selection.clearSaved();\n }\n this.inputOpened = false;\n }\n /**\n * Enter pressed on input\n * @param {KeyboardEvent} event\n */\n enterPressed(event) {\n let value = this.nodes.input.value || '';\n if (!value.trim()) {\n this.selection.restore();\n this.unlink();\n event.preventDefault();\n this.closeActions();\n }\n if (!this.validateURL(value)) {\n /**\n * @todo show notification 'Incorrect Link'\n */\n _.log('Incorrect Link pasted', 'warn', value);\n return;\n }\n value = this.prepareLink(value);\n this.selection.restore();\n this.insertLink(value);\n /**\n * Preventing events that will be able to happen\n */\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n this.closeActions();\n this.inlineToolbar.close();\n this.checkState();\n }\n /**\n * Detects if passed string is URL\n * @param {string} str\n * @return {Boolean}\n */\n validateURL(str) {\n /**\n * Don't allow spaces\n */\n return !/\\s/.test(str);\n }\n /**\n * Process link before injection\n * - sanitize\n * - add protocol for links like 'google.com'\n * @param {string} link - raw user input\n */\n prepareLink(link) {\n link = link.trim();\n link = this.addProtocol(link);\n return link;\n }\n /**\n * Add 'http' protocol to the links like 'vc.ru', 'google.com'\n * @param {String} link\n */\n addProtocol(link) {\n /**\n * If protocol already exists, do nothing\n */\n if (/^(\\w+):\\/\\//.test(link)) {\n return link;\n }\n /**\n * We need to add missed HTTP protocol to the link, but skip 2 cases:\n * 1) Internal links like \"/general\"\n * 2) Anchors looks like \"#results\"\n * 3) Protocol-relative URLs like \"//google.com\"\n */\n const isInternal = /^\\/[^\\/\\s]/.test(link), isAnchor = link.substring(0, 1) === '#', isProtocolRelative = /^\\/\\/[^\\/\\s]/.test(link);\n if (!isInternal && !isAnchor && !isProtocolRelative) {\n link = 'http://' + link;\n }\n return link;\n }\n /**\n * Inserts tag with \"href\"\n * @param {string} link - \"href\" value\n */\n insertLink(link) {\n /**\n * Edit all link, not selected part\n */\n const anchorTag = this.selection.findParentTag('A');\n if (anchorTag) {\n this.selection.expandToTag(anchorTag);\n }\n document.execCommand(this.commandLink, false, link);\n }\n /**\n * Removes tag\n */\n unlink() {\n document.execCommand(this.commandUnlink);\n }\n}\n","var map = {\n\t\"./api-blocks.ts\": \"./src/components/modules/api-blocks.ts\",\n\t\"./api-events.ts\": \"./src/components/modules/api-events.ts\",\n\t\"./api-listener.ts\": \"./src/components/modules/api-listener.ts\",\n\t\"./api-sanitizer.ts\": \"./src/components/modules/api-sanitizer.ts\",\n\t\"./api-saver.ts\": \"./src/components/modules/api-saver.ts\",\n\t\"./api-selection.ts\": \"./src/components/modules/api-selection.ts\",\n\t\"./api-toolbar.ts\": \"./src/components/modules/api-toolbar.ts\",\n\t\"./api.ts\": \"./src/components/modules/api.ts\",\n\t\"./block-events.ts\": \"./src/components/modules/block-events.ts\",\n\t\"./blockManager.js\": \"./src/components/modules/blockManager.js\",\n\t\"./caret.js\": \"./src/components/modules/caret.js\",\n\t\"./events.js\": \"./src/components/modules/events.js\",\n\t\"./listeners.js\": \"./src/components/modules/listeners.js\",\n\t\"./renderer.js\": \"./src/components/modules/renderer.js\",\n\t\"./sanitizer.js\": \"./src/components/modules/sanitizer.js\",\n\t\"./saver.js\": \"./src/components/modules/saver.js\",\n\t\"./toolbar-blockSettings.js\": \"./src/components/modules/toolbar-blockSettings.js\",\n\t\"./toolbar-inline.ts\": \"./src/components/modules/toolbar-inline.ts\",\n\t\"./toolbar-toolbox.js\": \"./src/components/modules/toolbar-toolbox.js\",\n\t\"./toolbar.js\": \"./src/components/modules/toolbar.js\",\n\t\"./tools.js\": \"./src/components/modules/tools.js\",\n\t\"./ui.js\": \"./src/components/modules/ui.js\"\n};\n\n\nfunction webpackContext(req) {\n\tvar id = webpackContextResolve(req);\n\treturn __webpack_require__(id);\n}\nfunction webpackContextResolve(req) {\n\tvar id = map[req];\n\tif(!(id + 1)) { // check for number or string\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\treturn id;\n}\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = \"./src/components/modules sync [^_](api-blocks.ts|api-events.ts|api-listener.ts|api-sanitizer.ts|api-saver.ts|api-selection.ts|api-toolbar.ts|api.ts|block-events.ts|blockManager.js|caret.js|events.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$\";","/**\n * @class BlocksAPI\n * provides with methods working with Block\n */\nexport default class BlocksAPI extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n */\n constructor({ config }) {\n super({ config });\n }\n /**\n * Available methods\n * @return {IBlocksAPI}\n */\n get methods() {\n return {\n clear: () => this.clear(),\n render: (data) => this.render(data),\n delete: () => this.delete(),\n swap: (fromIndex, toIndex) => this.swap(fromIndex, toIndex),\n getBlockByIndex: (index) => this.getBlockByIndex(index),\n getCurrentBlockIndex: () => this.getCurrentBlockIndex(),\n getBlocksCount: () => this.getBlocksCount(),\n };\n }\n /**\n * Returns Blocks count\n * @return {number}\n */\n getBlocksCount() {\n return this.Editor.BlockManager.blocks.length;\n }\n /**\n * Returns current block index\n * @return {number}\n */\n getCurrentBlockIndex() {\n return this.Editor.BlockManager.currentBlockIndex;\n }\n /**\n * Returns Current Block\n * @param {Number} index\n *\n * @return {Object}\n */\n getBlockByIndex(index) {\n return this.Editor.BlockManager.getBlockByIndex(index);\n }\n /**\n * Call Block Manager method that swap Blocks\n * @param {number} fromIndex - position of first Block\n * @param {number} toIndex - position of second Block\n */\n swap(fromIndex, toIndex) {\n this.Editor.BlockManager.swap(fromIndex, toIndex);\n /**\n * Move toolbar\n * DO not close the settings\n */\n this.Editor.Toolbar.move(false);\n }\n /**\n * Deletes Block\n * @param blockIndex\n */\n delete(blockIndex) {\n this.Editor.BlockManager.removeBlock(blockIndex);\n /**\n * in case of last block deletion\n * Insert new initial empty block\n */\n if (this.Editor.BlockManager.blocks.length === 0) {\n this.Editor.BlockManager.insert();\n }\n /**\n * In case of deletion first block we need to set caret to the current Block\n */\n if (this.Editor.BlockManager.currentBlockIndex === 0) {\n this.Editor.Caret.setToBlock(this.Editor.BlockManager.currentBlock);\n }\n else {\n this.Editor.Caret.navigatePrevious(true);\n }\n this.Editor.Toolbar.close();\n }\n /**\n * Clear Editor's area\n */\n clear() {\n this.Editor.BlockManager.clear(true);\n }\n /**\n * Fills Editor with Blocks data\n * @param {IInputOutputData} data — Saved Editor data\n */\n render(data) {\n this.Editor.BlockManager.clear();\n this.Editor.Renderer.render(data.items);\n }\n}\n","/**\n * @class EventsAPI\n * provides with methods working with Toolbar\n */\nexport default class EventsAPI extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n */\n constructor({ config }) {\n super({ config });\n }\n /**\n * Available methods\n * @return {IEventsAPI}\n */\n get methods() {\n return {\n emit: (eventName, data) => this.emit(eventName, data),\n off: (eventName, callback) => this.off(eventName, callback),\n on: (eventName, callback) => this.on(eventName, callback),\n };\n }\n /**\n * Subscribe on Events\n * @param {String} eventName\n * @param {Function} callback\n */\n on(eventName, callback) {\n this.Editor.Events.on(eventName, callback);\n }\n /**\n * Emit event with data\n * @param {String} eventName\n * @param {Object} data\n */\n emit(eventName, data) {\n this.Editor.Events.emit(eventName, data);\n }\n /**\n * Unsubscribe from Event\n * @param {String} eventName\n * @param {Function} callback\n */\n off(eventName, callback) {\n this.Editor.Events.off(eventName, callback);\n }\n}\n","/**\n * @class API\n * Provides with methods working with DOM Listener\n */\nexport default class ListenerAPI extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n */\n constructor({ config }) {\n super({ config });\n }\n /**\n * Available methods\n * @return {IToolbarAPI}\n */\n get methods() {\n return {\n on: (element, eventType, handler, useCapture) => this.on(element, eventType, handler, useCapture),\n off: (element, eventType, handler) => this.off(element, eventType, handler),\n };\n }\n /**\n * adds DOM event listener\n *\n * @param {HTMLElement} element\n * @param {string} eventType\n * @param {() => void} handler\n * @param {boolean} useCapture\n */\n on(element, eventType, handler, useCapture) {\n this.Editor.Listeners.on(element, eventType, handler, useCapture);\n }\n /**\n * Removes DOM listener from element\n *\n * @param element\n * @param eventType\n * @param handler\n */\n off(element, eventType, handler) {\n this.Editor.Listeners.off(element, eventType, handler);\n }\n}\n","/**\n * @class API\n * Provides CodeX Editor Sanitizer that allows developers to clean their HTML\n */\nexport default class SanitizerAPI extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n */\n constructor({ config }) {\n super({ config });\n }\n /**\n * Available methods\n * @return {ISanitizerAPI}\n */\n get methods() {\n return {\n clean: (taintString, config) => this.clean(taintString, config),\n };\n }\n clean(taintString, config) {\n return this.Editor.Sanitizer.clean(taintString, config);\n }\n}\n","/**\n * @class SaverAPI\n * provides with methods to save data\n */\nexport default class SaverAPI extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n */\n constructor({ config }) {\n super({ config });\n }\n /**\n * Available methods\n * @return {ISaverAPI}\n */\n get methods() {\n return {\n save: () => this.save(),\n };\n }\n /**\n * Return Editor's data\n */\n save() {\n return this.Editor.Saver.save();\n }\n}\n","import Selection from '../selection';\n/**\n * @class API\n * Provides with methods working with Selection\n */\nexport default class SelectionAPI extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n */\n constructor({ config }) {\n super({ config });\n }\n /**\n * Available methods\n * @return {ISelectionAPI}\n */\n get methods() {\n return {\n findParentTag: (tagName, className) => this.findParentTag(tagName, className),\n expandToTag: (node) => this.expandToTag(node),\n };\n }\n /**\n * Looks ahead from selection and find passed tag with class name\n * @param {string} tagName - tag to find\n * @param {string} className - tag's class name\n * @return {HTMLElement|null}\n */\n findParentTag(tagName, className) {\n return new Selection().findParentTag(tagName, className);\n }\n /**\n * Expand selection to passed tag\n * @param {HTMLElement} node - tag that should contain selection\n */\n expandToTag(node) {\n new Selection().expandToTag(node);\n }\n}\n","/**\n * @class ToolbarsAPI\n * provides with methods working with Toolbar\n */\nexport default class ToolbarAPI extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n */\n constructor({ config }) {\n super({ config });\n }\n /**\n * Available methods\n * @return {IToolbarAPI}\n */\n get methods() {\n return {\n close: () => this.close(),\n open: () => this.open(),\n };\n }\n /**\n * Open toolbar\n */\n open() {\n this.Editor.Toolbar.open();\n }\n /**\n * Close toolbar and all included elements\n */\n close() {\n this.Editor.Toolbar.close();\n }\n}\n","/**\n * @class API\n */\nexport default class API extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n * @param {EditorConfig} config\n */\n constructor({ config }) {\n super({ config });\n }\n get methods() {\n return {\n blocks: this.Editor.BlocksAPI.methods,\n caret: {},\n events: this.Editor.EventsAPI.methods,\n listener: this.Editor.ListenerAPI.methods,\n sanitizer: this.Editor.SanitizerAPI.methods,\n saver: this.Editor.SaverAPI.methods,\n selection: this.Editor.SelectionAPI.methods,\n toolbar: this.Editor.ToolbarAPI.methods,\n };\n }\n}\n","export default class BlockEvents extends Module {\n /**\n * @constructor\n */\n constructor({ config }) {\n super({ config });\n }\n /**\n * All keydowns on Block\n * @param {KeyboardEvent} event - keydown\n */\n keydown(event) {\n /**\n * Run common method for all keydown events\n */\n this.beforeKeydownProcessing();\n /**\n * Fire keydown processor by event.keyCode\n */\n switch (event.keyCode) {\n case _.keyCodes.BACKSPACE:\n this.backspace(event);\n break;\n case _.keyCodes.ENTER:\n this.enter(event);\n break;\n case _.keyCodes.DOWN:\n case _.keyCodes.RIGHT:\n this.arrowRightAndDown();\n break;\n case _.keyCodes.UP:\n case _.keyCodes.LEFT:\n this.arrowLeftAndUp();\n break;\n default:\n this.defaultHandler();\n break;\n }\n }\n /**\n * Fires on keydown before event processing\n */\n beforeKeydownProcessing() {\n /**\n * Clear all highlightings\n */\n this.Editor.BlockManager.clearHighlightings();\n /**\n * Hide Toolbar\n */\n this.Editor.Toolbar.close();\n }\n /**\n * Key up on Block:\n * - shows Inline Toolbar if something selected\n */\n keyup(event) {\n this.Editor.InlineToolbar.handleShowingEvent(event);\n }\n /**\n * Mouse up on Block:\n * - shows Inline Toolbar if something selected\n */\n mouseUp(event) {\n this.Editor.InlineToolbar.handleShowingEvent(event);\n }\n /**\n * ENTER pressed on block\n * @param {KeyboardEvent} event - keydown\n */\n enter(event) {\n const currentBlock = this.Editor.BlockManager.currentBlock, toolsConfig = this.config.toolsConfig[currentBlock.name];\n /**\n * Don't handle Enter keydowns when Tool sets enableLineBreaks to true.\n * Uses for Tools like where line breaks should be handled by default behaviour.\n */\n if (toolsConfig && toolsConfig[this.Editor.Tools.apiSettings.IS_ENABLED_LINE_BREAKS]) {\n return;\n }\n /**\n * Allow to create linebreaks by Shift+Enter\n */\n if (event.shiftKey) {\n return;\n }\n /**\n * Split the Current Block into two blocks\n */\n this.Editor.BlockManager.split();\n /**\n * Renew local current node after split\n */\n const newCurrent = this.Editor.BlockManager.currentBlock;\n this.Editor.Toolbar.move();\n /**\n * If new Block is empty\n */\n if (this.Editor.Tools.isInitial(newCurrent.tool) && newCurrent.isEmpty) {\n /**\n * Show Toolbar\n */\n this.Editor.Toolbar.open();\n /**\n * Show Plus Button\n */\n this.Editor.Toolbar.plusButton.show();\n }\n event.preventDefault();\n }\n /**\n * Handle backspace keydown on Block\n * @param {KeyboardEvent} event - keydown\n */\n backspace(event) {\n const BM = this.Editor.BlockManager;\n const isFirstBlock = BM.currentBlockIndex === 0, canMergeBlocks = this.Editor.Caret.isAtStart && !isFirstBlock;\n /** If current Block is empty just remove this Block */\n if (this.Editor.BlockManager.currentBlock.isEmpty) {\n this.Editor.BlockManager.removeBlock();\n if (this.Editor.Caret.navigatePrevious(true)) {\n this.Editor.Toolbar.close();\n }\n return;\n }\n if (!canMergeBlocks) {\n return;\n }\n // preventing browser default behaviour\n event.preventDefault();\n const targetBlock = BM.getBlockByIndex(BM.currentBlockIndex - 1), blockToMerge = BM.currentBlock;\n /**\n * Blocks that can be merged:\n * 1) with the same Name\n * 2) Tool has 'merge' method\n *\n * other case will handle as usual ARROW LEFT behaviour\n */\n if (blockToMerge.name !== targetBlock.name || !targetBlock.mergeable) {\n if (this.Editor.Caret.navigatePrevious()) {\n this.Editor.Toolbar.close();\n }\n return;\n }\n this.Editor.Caret.createShadow(targetBlock.pluginsContent);\n BM.mergeBlocks(targetBlock, blockToMerge)\n .then(() => {\n /** Restore caret position after merge */\n this.Editor.Caret.restoreCaret(targetBlock.pluginsContent);\n targetBlock.pluginsContent.normalize();\n this.Editor.Toolbar.close();\n });\n }\n /**\n * Handle right and down keyboard keys\n */\n arrowRightAndDown() {\n this.Editor.Caret.navigateNext();\n }\n /**\n * Handle left and up keyboard keys\n */\n arrowLeftAndUp() {\n this.Editor.Caret.navigatePrevious();\n }\n /**\n * Default keydown handler\n */\n defaultHandler() { }\n}\n","/**\n * @class BlockManager\n * @classdesc Manage editor`s blocks storage and appearance\n *\n * @module BlockManager\n *\n * @version 2.0.0\n */\n\nimport Block from '../block';\n\n/**\n * @typedef {BlockManager} BlockManager\n * @property {Number} currentBlockIndex - Index of current working block\n * @property {Proxy} _blocks - Proxy for Blocks instance {@link Blocks}\n */\nexport default class BlockManager extends Module {\n /**\n * @constructor\n * @param {EditorConfig} config\n */\n constructor({config}) {\n super({config});\n\n /**\n * Proxy for Blocks instance {@link Blocks}\n *\n * @type {Proxy}\n * @private\n */\n this._blocks = null;\n\n /**\n * Index of current working block\n *\n * @type {number}\n * @private\n */\n this.currentBlockIndex = -1;\n }\n\n /**\n * Should be called after Editor.UI preparation\n * Define this._blocks property\n *\n * @returns {Promise}\n */\n prepare() {\n return new Promise(resolve => {\n let blocks = new Blocks(this.Editor.UI.nodes.redactor);\n\n /**\n * We need to use Proxy to overload set/get [] operator.\n * So we can use array-like syntax to access blocks\n *\n * @example\n * this._blocks[0] = new Block(...);\n *\n * block = this._blocks[0];\n *\n * @todo proxy the enumerate method\n *\n * @type {Proxy}\n * @private\n */\n this._blocks = new Proxy(blocks, {\n set: Blocks.set,\n get: Blocks.get\n });\n\n resolve();\n });\n }\n\n /**\n * Creates Block instance by tool name\n *\n * @param {String} toolName - tools passed in editor config {@link EditorConfig#tools}\n * @param {Object} data - constructor params\n * @param {Object} settings - block settings\n *\n * @return {Block}\n */\n composeBlock(toolName, data, settings) {\n let toolInstance = this.Editor.Tools.construct(toolName, data),\n block = new Block(toolName, toolInstance, settings, this.Editor.API.methods);\n\n this.bindEvents(block);\n /**\n * Apply callback before inserting html\n */\n block.call('appendCallback', {});\n\n return block;\n }\n\n /**\n * Bind Events\n * @param {Object} block\n */\n bindEvents(block) {\n this.Editor.Listeners.on(block.holder, 'keydown', (event) => this.Editor.BlockEvents.keydown(event));\n this.Editor.Listeners.on(block.holder, 'mouseup', (event) => this.Editor.BlockEvents.mouseUp(event));\n this.Editor.Listeners.on(block.holder, 'keyup', (event) => this.Editor.BlockEvents.keyup(event));\n }\n\n /**\n * Insert new block into _blocks\n *\n * @param {String} toolName — plugin name, by default method inserts initial block type\n * @param {Object} data — plugin data\n * @param {Object} settings - default settings\n *\n * @return {Block}\n */\n insert(toolName = this.config.initialBlock, data = {}, settings = {}) {\n let block = this.composeBlock(toolName, data, settings);\n\n this._blocks[++this.currentBlockIndex] = block;\n this.Editor.Caret.setToBlock(block);\n\n return block;\n }\n\n /**\n * Always inserts at the end\n */\n insertAtEnd() {\n /**\n * Define new value for current block index\n */\n this.currentBlockIndex = this.blocks.length - 1;\n\n /**\n * Insert initial typed block\n */\n this.insert();\n }\n\n /**\n * Merge two blocks\n * @param {Block} targetBlock - previous block will be append to this block\n * @param {Block} blockToMerge - block that will be merged with target block\n *\n * @return {Promise} - the sequence that can be continued\n */\n mergeBlocks(targetBlock, blockToMerge) {\n let blockToMergeIndex = this._blocks.indexOf(blockToMerge);\n\n return Promise.resolve()\n .then( () => {\n if (blockToMerge.isEmpty) {\n return;\n }\n\n return blockToMerge.data\n .then((blockToMergeInfo) => {\n targetBlock.mergeWith(blockToMergeInfo.data);\n });\n })\n .then( () => {\n this.removeBlock(blockToMergeIndex);\n this.currentBlockIndex = this._blocks.indexOf(targetBlock);\n });\n }\n\n /**\n * Remove block with passed index or remove last\n * @param {Number|null} index\n */\n removeBlock(index) {\n if (!index) {\n index = this.currentBlockIndex;\n }\n this._blocks.remove(index);\n }\n\n /**\n * Split current Block\n * 1. Extract content from Caret position to the Block`s end\n * 2. Insert a new Block below current one with extracted content\n */\n split() {\n let extractedFragment = this.Editor.Caret.extractFragmentFromCaretPosition(),\n wrapper = $.make('div');\n\n wrapper.append(extractedFragment);\n\n /**\n * @todo make object in accordance with Tool\n */\n let data = {\n text: $.isEmpty(wrapper) ? '' : wrapper.innerHTML,\n };\n\n /**\n * Renew current Block\n * @type {Block}\n */\n const blockInserted = this.insert(this.config.initialBlock, data);\n\n this.currentNode = blockInserted.pluginsContent;\n }\n\n /**\n * Replace current working block\n *\n * @param {String} toolName — plugin name\n * @param {Object} data — plugin data\n */\n replace(toolName, data = {}) {\n let block = this.composeBlock(toolName, data);\n\n this._blocks.insert(this.currentBlockIndex, block, true);\n }\n\n /**\n * returns last Block\n * @return {Block}\n */\n get lastBlock() {\n return this._blocks[this._blocks.length - 1];\n }\n\n /**\n * Returns Block by passed index\n * @param {Number} index\n * @return {Block}\n */\n getBlockByIndex(index) {\n return this._blocks[index];\n }\n\n /**\n * Get Block instance by html element\n * @param {Node} element\n * @returns {Block}\n */\n getBlock(element) {\n if (!$.isElement(element)) {\n element = element.parentNode;\n }\n\n let nodes = this._blocks.nodes,\n firstLevelBlock = element.closest(`.${Block.CSS.wrapper}`),\n index = nodes.indexOf(firstLevelBlock);\n\n if (index >= 0) {\n return this._blocks[index];\n }\n }\n\n /**\n * Get current Block instance\n *\n * @return {Block}\n */\n get currentBlock() {\n return this._blocks[this.currentBlockIndex];\n }\n\n /**\n * Returns next Block instance\n * @return {Block|null}\n */\n get nextBlock() {\n let isLastBlock = this.currentBlockIndex === (this._blocks.length - 1);\n\n if (isLastBlock) {\n return null;\n }\n\n return this._blocks[this.currentBlockIndex + 1];\n }\n\n /**\n * Returns previous Block instance\n * @return {Block|null}\n */\n get previousBlock() {\n let isFirstBlock = this.currentBlockIndex === 0;\n\n if (isFirstBlock) {\n return null;\n }\n\n return this._blocks[this.currentBlockIndex - 1];\n }\n\n /**\n * Get working html element\n *\n * @return {HTMLElement}\n */\n get currentNode() {\n return this._blocks.nodes[this.currentBlockIndex];\n }\n\n /**\n * Set currentBlockIndex to passed block\n * @param {Node} element\n */\n set currentNode(element) {\n let nodes = this._blocks.nodes,\n firstLevelBlock = element.closest(`.${Block.CSS.wrapper}`);\n\n /**\n * Update current Block's index\n * @type {number}\n */\n this.currentBlockIndex = nodes.indexOf(firstLevelBlock);\n }\n\n /**\n * Remove selection from all Blocks then highlight only Current Block\n */\n highlightCurrentNode() {\n /**\n * Remove previous selected Block's state\n */\n this.clearHighlightings();\n\n /**\n * Mark current Block as selected\n * @type {boolean}\n */\n this.currentBlock.selected = true;\n }\n\n /**\n * Remove selection from all Blocks\n */\n clearHighlightings() {\n this.blocks.forEach( block => block.selected = false);\n }\n\n /**\n * Get array of Block instances\n *\n * @returns {Block[]} {@link Blocks#array}\n */\n get blocks() {\n return this._blocks.array;\n }\n\n /**\n * 1) Find first-level Block from passed child Node\n * 2) Mark it as current\n *\n * @param {Element|Text} childNode - look ahead from this node.\n * @throws Error - when passed Node is not included at the Block\n */\n setCurrentBlockByChildNode(childNode) {\n /**\n * If node is Text TextNode\n */\n if (!$.isElement(childNode)) {\n childNode = childNode.parentNode;\n }\n\n let parentFirstLevelBlock = childNode.closest(`.${Block.CSS.wrapper}`);\n\n if (parentFirstLevelBlock) {\n this.currentNode = parentFirstLevelBlock;\n } else {\n throw new Error('Can not find a Block from this child Node');\n }\n }\n\n /**\n * Swap Blocks Position\n * @param {Number} fromIndex\n * @param {Number} toIndex\n */\n swap(fromIndex, toIndex) {\n /** Move up current Block */\n this._blocks.swap(fromIndex, toIndex);\n\n /** Now actual block moved up so that current block index decreased */\n this.currentBlockIndex = toIndex;\n }\n\n /**\n * Sets current Block Index -1 which means unknown\n * and clear highlightings\n */\n dropPointer() {\n this.currentBlockIndex = -1;\n this.clearHighlightings();\n }\n\n /**\n * Clears Editor\n * @param {boolean} needAddInitialBlock - 1) in internal calls (for example, in api.blocks.render)\n * we don't need to add empty initial block\n * 2) in api.blocks.clear we should add empty block\n */\n clear(needAddInitialBlock = false) {\n this._blocks.removeAll();\n this.dropPointer();\n\n if (needAddInitialBlock) {\n this.insert(this.config.initialBlock);\n }\n }\n};\n\n/**\n * @class Blocks\n * @classdesc Class to work with Block instances array\n *\n * @private\n *\n * @property {HTMLElement} workingArea — editor`s working node\n *\n */\nclass Blocks {\n /**\n * @constructor\n *\n * @param {HTMLElement} workingArea — editor`s working node\n */\n constructor(workingArea) {\n this.blocks = [];\n this.workingArea = workingArea;\n }\n\n /**\n * Push back new Block\n *\n * @param {Block} block\n */\n push(block) {\n this.blocks.push(block);\n this.workingArea.appendChild(block.holder);\n }\n\n /**\n * Swaps blocks with indexes first and second\n * @param {Number} first - first block index\n * @param {Number} second - second block index\n */\n swap(first, second) {\n let secondBlock = this.blocks[second];\n\n /**\n * Change in DOM\n */\n $.swap(this.blocks[first].holder, secondBlock.holder);\n\n /**\n * Change in array\n */\n this.blocks[second] = this.blocks[first];\n this.blocks[first] = secondBlock;\n }\n\n /**\n * Insert new Block at passed index\n *\n * @param {Number} index — index to insert Block\n * @param {Block} block — Block to insert\n * @param {Boolean} replace — it true, replace block on given index\n */\n insert(index, block, replace = false) {\n if (!this.length) {\n this.push(block);\n return;\n }\n\n if (index > this.length) {\n index = this.length;\n }\n\n if (replace) {\n this.blocks[index].holder.remove();\n }\n\n let deleteCount = replace ? 1 : 0;\n\n this.blocks.splice(index, deleteCount, block);\n\n if (index > 0) {\n let previousBlock = this.blocks[index - 1];\n\n previousBlock.holder.insertAdjacentElement('afterend', block.holder);\n } else {\n let nextBlock = this.blocks[index + 1];\n\n if (nextBlock) {\n nextBlock.holder.insertAdjacentElement('beforebegin', block.holder);\n } else {\n this.workingArea.appendChild(block.holder);\n }\n }\n }\n\n /**\n * Remove block\n * @param {Number|null} index\n */\n remove(index) {\n if (isNaN(index)) {\n index = this.length - 1;\n }\n\n this.blocks[index].holder.remove();\n this.blocks.splice(index, 1);\n }\n\n /**\n * Remove all blocks\n */\n removeAll() {\n this.workingArea.innerHTML = '';\n this.blocks.length = 0;\n }\n\n /**\n * Insert Block after passed target\n *\n * @todo decide if this method is necessary\n *\n * @param {Block} targetBlock — target after wich Block should be inserted\n * @param {Block} newBlock — Block to insert\n */\n insertAfter(targetBlock, newBlock) {\n let index = this.blocks.indexOf(targetBlock);\n\n this.insert(index + 1, newBlock);\n }\n\n /**\n * Get Block by index\n *\n * @param {Number} index — Block index\n * @returns {Block}\n */\n get(index) {\n return this.blocks[index];\n }\n\n /**\n * Return index of passed Block\n *\n * @param {Block} block\n * @returns {Number}\n */\n indexOf(block) {\n return this.blocks.indexOf(block);\n }\n\n /**\n * Get length of Block instances array\n *\n * @returns {Number}\n */\n get length() {\n return this.blocks.length;\n }\n\n /**\n * Get Block instances array\n *\n * @returns {Block[]}\n */\n get array() {\n return this.blocks;\n }\n\n /**\n * Get blocks html elements array\n *\n * @returns {HTMLElement[]}\n */\n get nodes() {\n return _.array(this.workingArea.children);\n }\n\n /**\n * Proxy trap to implement array-like setter\n *\n * @example\n * blocks[0] = new Block(...)\n *\n * @param {Blocks} instance — Blocks instance\n * @param {Number|String} index — block index\n * @param {Block} block — Block to set\n * @returns {Boolean}\n */\n static set(instance, index, block) {\n if (isNaN(Number(index))) {\n return false;\n }\n\n instance.insert(index, block);\n\n return true;\n }\n\n /**\n * Proxy trap to implement array-like getter\n *\n * @param {Blocks} instance — Blocks instance\n * @param {Number|String} index — Block index\n * @returns {Block|*}\n */\n static get(instance, index) {\n if (isNaN(Number(index))) {\n return instance[index];\n }\n\n return instance.get(index);\n }\n}\n","/**\n * @class Caret\n * @classdesc Contains methods for working Caret\n *\n * Uses Range methods to manipulate with caret\n *\n * @module Caret\n *\n * @version 2.0.0\n */\n\nimport Selection from '../selection';\n\n/**\n * @typedef {Caret} Caret\n */\nexport default class Caret extends Module {\n /**\n * @constructor\n */\n constructor({config}) {\n super({config});\n }\n\n /**\n * Elements styles that can be useful for Caret Module\n */\n static get CSS() {\n return {\n shadowCaret: 'cdx-shadow-caret'\n };\n };\n\n /**\n * Method gets Block instance and puts caret to the text node with offset\n * There two ways that method applies caret position:\n * - first found text node: sets at the beginning, but you can pass an offset\n * - last found text node: sets at the end of the node. Also, you can customize the behaviour\n *\n * @param {Block} block - Block class\n * @param {Number} offset - caret offset regarding to the text node\n * @param {Boolean} atEnd - put caret at the end of the text node or not\n */\n setToBlock(block, offset = 0, atEnd = false) {\n let element = block.pluginsContent;\n\n /** If Element is INPUT */\n if ($.isNativeInput(element)) {\n element.focus();\n return;\n }\n\n let nodeToSet = $.getDeepestNode(element, atEnd);\n\n if (atEnd || offset > nodeToSet.length) {\n offset = nodeToSet.length;\n }\n\n /** if found deepest node is native input */\n if ($.isNativeInput(nodeToSet)) {\n nodeToSet.focus();\n return;\n }\n\n /**\n * @todo try to fix via Promises or use querySelectorAll to not to use timeout\n */\n _.delay( () => {\n this.set(nodeToSet, offset);\n }, 20)();\n\n this.Editor.BlockManager.currentNode = block.holder;\n }\n\n /**\n * Creates Document Range and sets caret to the element with offset\n * @param {Element} element - target node.\n * @param {Number} offset - offset\n */\n set( element, offset = 0) {\n let range = document.createRange(),\n selection = Selection.get();\n\n range.setStart(element, offset);\n range.setEnd(element, offset);\n\n selection.removeAllRanges();\n selection.addRange(range);\n };\n\n /**\n * Set Caret to the last Block\n * If last block is not empty, append another empty block\n */\n setToTheLastBlock() {\n let lastBlock = this.Editor.BlockManager.lastBlock;\n\n if (!lastBlock) return;\n\n /**\n * If last block is empty and it is an initialBlock, set to that.\n * Otherwise, append new empty block and set to that\n */\n if (lastBlock.isEmpty) {\n this.setToBlock(lastBlock);\n } else {\n this.Editor.BlockManager.insertAtEnd();\n }\n }\n\n /**\n * Extract content fragment of current Block from Caret position to the end of the Block\n */\n extractFragmentFromCaretPosition() {\n let selection = Selection.get();\n\n if (selection.rangeCount) {\n let selectRange = selection.getRangeAt(0),\n blockElem = this.Editor.BlockManager.currentBlock.pluginsContent;\n\n selectRange.deleteContents();\n\n if (blockElem) {\n let range = selectRange.cloneRange(true);\n\n range.selectNodeContents(blockElem);\n range.setStart(selectRange.endContainer, selectRange.endOffset);\n return range.extractContents();\n }\n }\n }\n\n /**\n * Get all first-level (first child of [contenteditabel]) siblings from passed node\n * Then you can check it for emptiness\n *\n * @example\n *

    \n *

    |\n *

    | left first-level siblings\n *

    |\n *
    adaddad
    <-- passed node for example \n *

    |\n *

    | right first-level siblings\n *

    |\n *
    \n *\n * @return {Element[]}\n */\n getHigherLevelSiblings(from, direction ) {\n let current = from,\n siblings = [];\n\n /**\n * Find passed node's firs-level parent (in example - blockquote)\n */\n while (current.parentNode && current.parentNode.contentEditable !== 'true') {\n current = current.parentNode;\n }\n\n let sibling = direction === 'left' ? 'previousSibling' : 'nextSibling';\n\n /**\n * Find all left/right siblings\n */\n while (current[sibling]) {\n current = current[sibling];\n siblings.push(current);\n }\n\n return siblings;\n }\n\n /**\n * Set's caret to the next Block\n * Before moving caret, we should check if caret position is at the end of Plugins node\n * Using {@link Dom#getDeepestNode} to get a last node and match with current selection\n *\n * @param {Boolean} force - force navigation even if caret is not at the end\n *\n * @return {Boolean}\n */\n navigateNext(force = false) {\n let nextBlock = this.Editor.BlockManager.nextBlock;\n\n if (!nextBlock) {\n return false;\n }\n\n if (force || this.isAtEnd) {\n this.setToBlock(nextBlock);\n return true;\n }\n\n return false;\n }\n\n /**\n * Set's caret to the previous Block\n * Before moving caret, we should check if caret position is start of the Plugins node\n * Using {@link Dom#getDeepestNode} to get a last node and match with current selection\n *\n * @param {Boolean} force - force navigation even if caret is not at the start\n *\n * @return {Boolean}\n */\n navigatePrevious(force = false) {\n let previousBlock = this.Editor.BlockManager.previousBlock;\n\n if (!previousBlock) {\n return false;\n }\n\n if (force || this.isAtStart) {\n this.setToBlock( previousBlock, 0, true );\n return true;\n }\n\n return false;\n }\n\n /**\n * Get's deepest first node and checks if offset is zero\n * @return {boolean}\n */\n get isAtStart() {\n /**\n * Don't handle ranges\n */\n if (!Selection.isCollapsed) {\n return false;\n }\n\n let selection = Selection.get(),\n anchorNode = selection.anchorNode,\n firstNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent);\n\n /**\n * Workaround case when caret in the text like \" |Hello!\"\n * selection.anchorOffset is 1, but real caret visible position is 0\n * @type {number}\n */\n let firstLetterPosition = anchorNode.textContent.search(/\\S/);\n\n if (firstLetterPosition === -1) { // empty text\n firstLetterPosition = 0;\n }\n\n /**\n * In case of\n *
    \n *

    <-- first (and deepest) node is \n * |adaddad <-- anchor node\n *
    \n */\n if ($.isEmpty(firstNode)) {\n let leftSiblings = this.getHigherLevelSiblings(anchorNode, 'left'),\n nothingAtLeft = leftSiblings.every( node => $.isEmpty(node) );\n\n\n\n if (nothingAtLeft && selection.anchorOffset === firstLetterPosition) {\n return true;\n }\n }\n\n /**\n * We use <= comparison for case:\n * \"| Hello\" <--- selection.anchorOffset is 0, but firstLetterPosition is 1\n */\n return firstNode === null || anchorNode === firstNode && selection.anchorOffset <= firstLetterPosition;\n }\n\n /**\n * Get's deepest last node and checks if offset is last node text length\n * @return {boolean}\n */\n get isAtEnd() {\n /**\n * Don't handle ranges\n */\n if (!Selection.isCollapsed) {\n return false;\n }\n\n let selection = Selection.get(),\n anchorNode = selection.anchorNode,\n lastNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent, true);\n\n /**\n * In case of\n *
    \n * adaddad| <-- anchor node\n *

    <-- first (and deepest) node is \n *
    \n */\n if ($.isEmpty(lastNode)) {\n let leftSiblings = this.getHigherLevelSiblings(anchorNode, 'right'),\n nothingAtRight = leftSiblings.every( node => $.isEmpty(node) );\n\n if (nothingAtRight && selection.anchorOffset === anchorNode.textContent.length) {\n return true;\n }\n }\n\n /**\n * Workaround case:\n * hello | <--- anchorOffset will be 5, but textContent.length will be 6.\n * Why not regular .trim():\n * in case of ' hello |' trim() will also remove space at the beginning, so length will be lower than anchorOffset\n */\n let rightTrimmedText = lastNode.textContent.replace(/\\s+$/, '');\n\n /**\n * We use >= comparison for case:\n * \"Hello |\" <--- selection.anchorOffset is 7, but rightTrimmedText is 6\n */\n return anchorNode === lastNode && selection.anchorOffset >= rightTrimmedText.length;\n }\n\n /**\n * Inserts shadow element after passed element where caret can be placed\n * @param {Node} element\n */\n createShadow(element) {\n let shadowCaret = document.createElement('span');\n\n shadowCaret.classList.add(Caret.CSS.shadowCaret);\n element.insertAdjacentElement('beforeEnd', shadowCaret);\n }\n\n /**\n * Restores caret position\n * @param {Node} element\n */\n restoreCaret(element) {\n let shadowCaret = element.querySelector(`.${Caret.CSS.shadowCaret}`);\n\n if (!shadowCaret) {\n return;\n }\n\n /**\n * After we set the caret to the required place\n * we need to clear shadow caret\n *\n * - make new range\n * - select shadowed span\n * - use extractContent to remove it from DOM\n */\n let sel = new Selection();\n\n sel.expandToTag(shadowCaret);\n\n setTimeout(() => {\n let newRange = document.createRange();\n\n newRange.selectNode(shadowCaret);\n newRange.extractContents();\n }, 50);\n }\n}\n","/**\n * @module eventDispatcher\n *\n * Has two important methods:\n * - {Function} on - appends subscriber to the event. If event doesn't exist - creates new one\n * - {Function} emit - fires all subscribers with data\n * - {Function off - unsubsribes callback\n *\n * @version 1.0.0\n *\n * @typedef {Events} Events\n * @property {Object} subscribers - all subscribers grouped by event name\n */\nexport default class Events extends Module {\n /**\n * @constructor\n */\n constructor({config}) {\n super({config});\n this.subscribers = {};\n }\n\n /**\n * Subscribe any event on callback\n *\n * @param {String} eventName - event name\n * @param {Function} callback - subscriber\n */\n on(eventName, callback) {\n if (!(eventName in this.subscribers)) {\n this.subscribers[eventName] = [];\n }\n\n // group by events\n this.subscribers[eventName].push(callback);\n }\n\n /**\n * Emit callbacks with passed data\n *\n * @param {String} eventName - event name\n * @param {Object} data - subscribers get this data when they were fired\n */\n emit(eventName, data) {\n if (!this.subscribers[eventName]) {\n return;\n }\n\n this.subscribers[eventName].reduce(function (previousData, currentHandler) {\n let newData = currentHandler(previousData);\n\n return newData ? newData : previousData;\n }, data);\n }\n\n /**\n * Unsubsribe callback from event\n *\n * @param eventName\n * @param callback\n */\n off(eventName, callback) {\n for(let i = 0; i < this.subscribers[eventName].length; i++) {\n if (this.subscribers[eventName][i] === callback) {\n delete this.subscribers[eventName][i];\n break;\n }\n }\n }\n\n /**\n * Destroyer\n * clears subsribers list\n */\n destroy() {\n this.subscribers = null;\n }\n}\n","/**\n * Codex Editor Listeners module\n *\n * @module Listeners\n *\n * Module-decorator for event listeners assignment\n *\n * @author Codex Team\n * @version 2.0.0\n */\n\n/**\n * @typedef {Listeners} Listeners\n * @property {Array} allListeners\n */\nexport default class Listeners extends Module {\n /**\n * @constructor\n * @param {EditorConfig} config\n */\n constructor({config}) {\n super({config});\n this.allListeners = [];\n }\n\n /**\n * Assigns event listener on element\n *\n * @param {Element} element - DOM element that needs to be listened\n * @param {String} eventType - event type\n * @param {Function} handler - method that will be fired on event\n * @param {Boolean} useCapture - use event bubbling\n */\n on(element, eventType, handler, useCapture = false) {\n let assignedEventData = {\n element,\n eventType,\n handler,\n useCapture\n };\n\n let alreadyExist = this.findOne(element, eventType, handler);\n\n if (alreadyExist) return;\n\n this.allListeners.push(assignedEventData);\n element.addEventListener(eventType, handler, useCapture);\n }\n\n /**\n * Removes event listener from element\n *\n * @param {Element} element - DOM element that we removing listener\n * @param {String} eventType - event type\n * @param {Function} handler - remove handler, if element listens several handlers on the same event type\n * @param {Boolean} useCapture - use event bubbling\n */\n off(element, eventType, handler, useCapture = false) {\n let existingListeners = this.findAll(element, eventType, handler);\n\n for (let i = 0; i < existingListeners.length; i++) {\n let index = this.allListeners.indexOf(existingListeners[i]);\n\n if (index > 0) {\n this.allListeners.splice(index, 1);\n }\n }\n\n element.removeEventListener(eventType, handler, useCapture);\n }\n\n /**\n * Search method: looks for listener by passed element\n * @param {Element} element - searching element\n * @returns {Array} listeners that found on element\n */\n findByElement(element) {\n let listenersOnElement = [];\n\n for (let i = 0; i < this.allListeners.length; i++) {\n let listener = this.allListeners[i];\n\n if (listener.element === element) {\n listenersOnElement.push(listener);\n }\n }\n\n return listenersOnElement;\n }\n\n /**\n * Search method: looks for listener by passed event type\n * @param {String} eventType\n * @return {Array} listeners that found on element\n */\n findByType(eventType) {\n let listenersWithType = [];\n\n for (let i = 0; i < this.allListeners.length; i++) {\n let listener = this.allListeners[i];\n\n if (listener.type === eventType) {\n listenersWithType.push(listener);\n }\n }\n\n return listenersWithType;\n }\n\n /**\n * Search method: looks for listener by passed handler\n * @param {Function} handler\n * @return {Array} listeners that found on element\n */\n findByHandler(handler) {\n let listenersWithHandler = [];\n\n for (let i = 0; i < this.allListeners.length; i++) {\n let listener = this.allListeners[i];\n\n if (listener.handler === handler) {\n listenersWithHandler.push(listener);\n }\n }\n\n return listenersWithHandler;\n }\n\n /**\n * @param {Element} element\n * @param {String} eventType\n * @param {Function} handler\n * @return {Element|null}\n */\n findOne(element, eventType, handler) {\n let foundListeners = this.findAll(element, eventType, handler);\n\n return foundListeners.length > 0 ? foundListeners[0] : null;\n }\n\n /**\n * @param {Element} element\n * @param {String} eventType\n * @param {Function} handler\n * @return {Array}\n */\n findAll(element, eventType, handler) {\n let found,\n foundByElements = element ? this.findByElement(element) : [];\n // foundByEventType = eventType ? this.findByType(eventType) : [],\n // foundByHandler = handler ? this.findByHandler(handler) : [];\n\n if (element && eventType && handler) {\n found = foundByElements.filter( event => event.eventType === eventType && event.handler === handler );\n } else if (element && eventType) {\n found = foundByElements.filter( event => event.eventType === eventType);\n } else {\n found = foundByElements;\n }\n\n return found;\n }\n\n /**\n * Removes all listeners\n */\n removeAll() {\n this.allListeners.map( (current) => {\n current.element.removeEventListener(current.eventType, current.handler);\n });\n\n this.allListeners = [];\n }\n}\n","/**\n * Codex Editor Renderer Module\n *\n * @module Renderer\n * @author CodeX Team\n *\n * @version 2.0.0\n */\nexport default class Renderer extends Module {\n /**\n * @constructor\n * @param {EditorConfig} config\n */\n constructor({config}) {\n super({config});\n }\n\n /**\n * @typedef {Object} RendererItems\n * @property {String} type - tool name\n * @property {Object} data - tool data\n */\n\n /**\n * @example\n *\n * items: [\n * {\n * type : 'paragraph',\n * data : {\n * text : 'Hello from Codex!'\n * }\n * },\n * {\n * type : 'paragraph',\n * data : {\n * text : 'Leave feedback if you like it!'\n * }\n * },\n * ]\n *\n */\n\n /**\n * Make plugin blocks from array of plugin`s data\n * @param {RendererItems[]} items\n */\n render(items) {\n let chainData = [];\n\n for (let i = 0; i < items.length; i++) {\n chainData.push({\n function: () => this.insertBlock(items[i])\n });\n }\n\n return _.sequence(chainData);\n }\n\n /**\n * Get plugin instance\n * Add plugin instance to BlockManager\n * Insert block to working zone\n *\n * @param {Object} item\n * @returns {Promise.}\n * @private\n */\n insertBlock(item) {\n let tool = item.type,\n data = item.data,\n settings = item.settings;\n\n if (tool in this.Editor.Tools.available) {\n this.Editor.BlockManager.insert(tool, data, settings);\n } else {\n /**\n * @todo show warning notification message\n *\n * `${tool} blocks was skipped.`\n */\n\n _.log(`Tool «${tool}» is not found. Check 'tools' property at your initial CodeX Editor config.`, 'warn');\n }\n\n return Promise.resolve();\n }\n}\n","/**\n * CodeX Sanitizer\n *\n * @module Sanitizer\n * Clears HTML from taint tags\n *\n * @version 2.0.0\n *\n * @example\n * Module can be used within two ways:\n * 1) When you have an instance\n * - this.Editor.Sanitizer.clean(yourTaintString);\n * 2) As static method\n * - CodexEditor.Sanitizer.clean(yourTaintString, yourCustomConfiguration);\n *\n * {@link SanitizerConfig}\n */\n\n\n/**\n * @typedef {Object} SanitizerConfig\n * @property {Object} tags - define tags restrictions\n *\n * @example\n *\n * tags : {\n * p: true,\n * a: {\n * href: true,\n * rel: \"nofollow\",\n * target: \"_blank\"\n * }\n * }\n */\nexport default class Sanitizer extends Module {\n /**\n * Initializes Sanitizer module\n * Sets default configuration if custom not exists\n *\n * @property {SanitizerConfig} this.defaultConfig\n * @property {HTMLJanitor} this._sanitizerInstance - Sanitizer library\n *\n * @param {SanitizerConfig} config\n */\n constructor({config}) {\n super({config});\n\n // default config\n this.defaultConfig = null;\n this._sanitizerInstance = null;\n\n /** Custom configuration */\n this.sanitizerConfig = config.settings ? config.settings.sanitizer : {};\n\n /** HTML Janitor library */\n this.sanitizerInstance = require('html-janitor');\n }\n\n /**\n * If developer uses editor's API, then he can customize sanitize restrictions.\n * Or, sanitizing config can be defined globally in editors initialization. That config will be used everywhere\n * At least, if there is no config overrides, that API uses Default configuration\n *\n * @uses https://www.npmjs.com/package/html-janitor\n *\n * @param {HTMLJanitor} library - sanitizer extension\n */\n set sanitizerInstance(library) {\n this._sanitizerInstance = new library(this.defaultConfig);\n }\n\n /**\n * Sets sanitizer configuration. Uses default config if user didn't pass the restriction\n * @param {SanitizerConfig} config\n */\n set sanitizerConfig(config) {\n if (_.isEmpty(config)) {\n this.defaultConfig = {\n tags: {\n p: {},\n a: {\n href: true,\n target: '_blank',\n rel: 'nofollow'\n }\n }\n };\n } else {\n this.defaultConfig = config;\n }\n }\n\n /**\n * Cleans string from unwanted tags\n * @param {String} taintString - HTML string\n * @param {Object} customConfig - custom sanitizer configuration. Method uses default if param is empty\n * @return {String} clean HTML\n */\n clean(taintString, customConfig = {}) {\n if (_.isEmpty(customConfig)) {\n return this._sanitizerInstance.clean(taintString);\n } else {\n return Sanitizer.clean(taintString, customConfig);\n }\n }\n\n /**\n * Cleans string from unwanted tags\n * @static\n *\n * Method allows to use default config\n *\n * @param {String} taintString - taint string\n * @param {SanitizerConfig} customConfig - allowed tags\n *\n * @return {String} clean HTML\n */\n static clean(taintString, customConfig) {\n let newInstance = Sanitizer(customConfig);\n\n return newInstance.clean(taintString);\n }\n}\n","/**\n * Codex Editor Saver\n *\n * @module Saver\n * @author Codex Team\n * @version 2.0.0\n */\n\n/**\n * @typedef {Object} SavedData\n * @property {Date} time - saving proccess time\n * @property {Object} items - extracted data\n * @property {String} version - CodexEditor version\n */\n\n/**\n * @classdesc This method reduces all Blocks asyncronically and calls Block's save method to extract data\n *\n * @typedef {Saver} Saver\n * @property {Element} html - Editor HTML content\n * @property {String} json - Editor JSON output\n */\nexport default class Saver extends Module {\n /**\n * @constructor\n * @param config\n */\n constructor({config}) {\n super({config});\n\n this.output = null;\n this.blocksData = [];\n }\n\n /**\n * Composes new chain of Promises to fire them alternatelly\n * @return {SavedData}\n */\n save() {\n let blocks = this.Editor.BlockManager.blocks,\n chainData = [];\n\n blocks.forEach((block) => {\n chainData.push(block.data);\n });\n\n return Promise.all(chainData)\n .then((allExtractedData) => this.makeOutput(allExtractedData))\n .then((outputData) => {\n return outputData;\n });\n }\n\n /**\n * Creates output object with saved data, time and version of editor\n * @param {Object} allExtractedData\n * @return {SavedData}\n */\n makeOutput(allExtractedData) {\n let items = [],\n totalTime = 0;\n\n console.groupCollapsed('[CodexEditor saving]:');\n\n allExtractedData.forEach((extraction) => {\n /** Group process info */\n console.log(`«${extraction.tool}» saving info`, extraction);\n totalTime += extraction.time;\n items.push({\n type: extraction.tool,\n data: extraction.data\n });\n });\n\n console.log('Total', totalTime);\n console.groupEnd();\n\n return {\n time : +new Date(),\n items : items,\n version : VERSION,\n };\n }\n}\n\n// module.exports = (function (saver) {\n//\n// let editor = codex.editor;\n//\n// /**\n// * @public\n// * Save blocks\n// */\n// saver.save = function () {\n//\n// /** Save html content of redactor to memory */\n// editor.state.html = editor.nodes.redactor.innerHTML;\n//\n// /** Clean jsonOutput state */\n// editor.state.jsonOutput = [];\n//\n// return saveBlocks(editor.nodes.redactor.childNodes);\n//\n// };\n//\n// /**\n// * @private\n// * Save each block data\n// *\n// * @param blocks\n// * @returns {Promise.}\n// */\n// let saveBlocks = function (blocks) {\n//\n// let data = [];\n//\n// for(let index = 0; index < blocks.length; index++) {\n//\n// data.push(getBlockData(blocks[index]));\n//\n// }\n//\n// return Promise.all(data)\n// .then(makeOutput)\n// .catch(editor.core.log);\n//\n// };\n//\n// /** Save and validate block data */\n// let getBlockData = function (block) {\n//\n// return saveBlockData(block)\n// .then(validateBlockData)\n// .catch(editor.core.log);\n//\n// };\n//\n// /**\n// * @private\n// * Call block`s plugin save method and return saved data\n// *\n// * @param block\n// * @returns {Object}\n// */\n// let saveBlockData = function (block) {\n//\n// let pluginName = block.dataset.tool;\n//\n// /** Check for plugin existence */\n// if (!editor.tools[pluginName]) {\n//\n// editor.core.log(`Plugin «${pluginName}» not found`, 'error');\n// return {data: null, pluginName: null};\n//\n// }\n//\n// /** Check for plugin having save method */\n// if (typeof editor.tools[pluginName].save !== 'function') {\n//\n// editor.core.log(`Plugin «${pluginName}» must have save method`, 'error');\n// return {data: null, pluginName: null};\n//\n// }\n//\n// /** Result saver */\n// let blockContent = block.childNodes[0],\n// pluginsContent = blockContent.childNodes[0],\n// position = pluginsContent.dataset.inputPosition;\n//\n// /** If plugin wasn't available then return data from cache */\n// if ( editor.tools[pluginName].available === false ) {\n//\n// return Promise.resolve({data: codex.editor.state.blocks.items[position].data, pluginName});\n//\n// }\n//\n// return Promise.resolve(pluginsContent)\n// .then(editor.tools[pluginName].save)\n// .then(data => Object({data, pluginName}));\n//\n// };\n//\n// /**\n// * Call plugin`s validate method. Return false if validation failed\n// *\n// * @param data\n// * @param pluginName\n// * @returns {Object|Boolean}\n// */\n// let validateBlockData = function ({data, pluginName}) {\n//\n// if (!data || !pluginName) {\n//\n// return false;\n//\n// }\n//\n// if (editor.tools[pluginName].validate) {\n//\n// let result = editor.tools[pluginName].validate(data);\n//\n// /**\n// * Do not allow invalid data\n// */\n// if (!result) {\n//\n// return false;\n//\n// }\n//\n// }\n//\n// return {data, pluginName};\n//\n//\n// };\n//\n// /**\n// * Compile article output\n// *\n// * @param savedData\n// * @returns {{time: number, version, items: (*|Array)}}\n// */\n// let makeOutput = function (savedData) {\n//\n// savedData = savedData.filter(blockData => blockData);\n//\n// let items = savedData.map(blockData => Object({type: blockData.pluginName, data: blockData.data}));\n//\n// editor.state.jsonOutput = items;\n//\n// return {\n// id: editor.state.blocks.id || null,\n// time: +new Date(),\n// version: editor.version,\n// items\n// };\n//\n// };\n//\n// return saver;\n//\n// })({});\n","/**\n * Block Settings\n *\n * ____ Settings Panel ____\n * | ...................... |\n * | . Tool Settings . |\n * | ...................... |\n * | . Default Settings . |\n * | ...................... |\n * |________________________|\n */\nexport default class BlockSettings extends Module {\n /**\n * @constructor\n */\n constructor({config}) {\n super({config});\n\n this.nodes = {\n wrapper: null,\n toolSettings: null,\n defaultSettings: null\n };\n }\n\n /**\n * Module Events\n * @return {{opened: string, closed: string}}\n */\n get events() {\n return {\n opened: 'block-settings-opened',\n closed: 'block-settings-closed',\n };\n }\n\n /**\n * Block Settings CSS\n * @return {{wrapper, wrapperOpened, toolSettings, defaultSettings, button}}\n */\n static get CSS() {\n return {\n // Settings Panel\n wrapper: 'ce-settings',\n wrapperOpened: 'ce-settings--opened',\n toolSettings: 'ce-settings__plugin-zone',\n defaultSettings: 'ce-settings__default-zone',\n\n button: 'ce-settings__button'\n };\n }\n\n /**\n * Panel with block settings with 2 sections:\n * - Tool's Settings\n * - Default Settings [Move, Remove, etc]\n *\n * @return {Element}\n */\n make() {\n this.nodes.wrapper = $.make('div', BlockSettings.CSS.wrapper);\n\n this.nodes.toolSettings = $.make('div', BlockSettings.CSS.toolSettings);\n this.nodes.defaultSettings = $.make('div', BlockSettings.CSS.defaultSettings);\n\n $.append(this.nodes.wrapper, [this.nodes.toolSettings, this.nodes.defaultSettings]);\n }\n\n /**\n * Add Tool's settings\n */\n addToolSettings() {\n if (typeof this.Editor.BlockManager.currentBlock.tool.renderSettings === 'function') {\n $.append(this.nodes.toolSettings, this.Editor.BlockManager.currentBlock.tool.renderSettings());\n }\n }\n\n /**\n * Add default settings\n */\n addDefaultSettings() {\n $.append(this.nodes.defaultSettings, this.Editor.BlockManager.currentBlock.renderTunes());\n }\n\n /**\n * Is Block Settings opened or not\n * @returns {boolean}\n */\n get opened() {\n return this.nodes.wrapper.classList.contains(BlockSettings.CSS.wrapperOpened);\n }\n\n /**\n * Open Block Settings pane\n */\n open() {\n this.nodes.wrapper.classList.add(BlockSettings.CSS.wrapperOpened);\n\n /**\n * Fill Tool's settings\n */\n this.addToolSettings();\n\n /**\n * Add default settings that presents for all Blocks\n */\n this.addDefaultSettings();\n\n /** Tell to subscribers that block settings is opened */\n this.Editor.Events.emit(this.events.opened);\n }\n\n /**\n * Close Block Settings pane\n */\n close() {\n this.nodes.wrapper.classList.remove(BlockSettings.CSS.wrapperOpened);\n\n /** Clear settings */\n this.nodes.toolSettings.innerHTML = '';\n this.nodes.defaultSettings.innerHTML = '';\n\n /** Tell to subscribers that block settings is closed */\n this.Editor.Events.emit(this.events.closed);\n }\n}\n","import BoldInlineTool from '../inline-tools/inline-tool-bold';\nimport ItalicInlineTool from '../inline-tools/inline-tool-italic';\nimport LinkInlineTool from '../inline-tools/inline-tool-link';\nimport Selection from '../selection';\nexport default class InlineToolbar extends Module {\n /**\n * @constructor\n */\n constructor({ config }) {\n super({ config });\n /**\n * CSS styles\n */\n this.CSS = {\n inlineToolbar: 'ce-inline-toolbar',\n inlineToolbarShowed: 'ce-inline-toolbar--showed',\n buttonsWrapper: 'ce-inline-toolbar__buttons',\n actionsWrapper: 'ce-inline-toolbar__actions',\n };\n /**\n * Inline Toolbar elements\n */\n this.nodes = {\n wrapper: null,\n buttons: null,\n /**\n * Zone below the buttons where Tools can create additional actions by 'renderActions()' method\n * For example, input for the 'link' tool or textarea for the 'comment' tool\n */\n actions: null,\n };\n /**\n * Margin above/below the Toolbar\n */\n this.toolbarVerticalMargin = 20;\n }\n /**\n * Inline Toolbar Tools\n * @todo Merge internal tools with external\n */\n get tools() {\n if (!this.toolsInstances) {\n this.toolsInstances = [\n new BoldInlineTool(this.Editor.API.methods),\n new ItalicInlineTool(this.Editor.API.methods),\n new LinkInlineTool(this.Editor.API.methods),\n ...this.Editor.Tools.inline.map((Tool) => new Tool(this.Editor.API.methods)),\n ];\n }\n return this.toolsInstances;\n }\n /**\n * Making DOM\n */\n make() {\n this.nodes.wrapper = $.make('div', this.CSS.inlineToolbar);\n this.nodes.buttons = $.make('div', this.CSS.buttonsWrapper);\n this.nodes.actions = $.make('div', this.CSS.actionsWrapper);\n /**\n * Append Inline Toolbar to the Editor\n */\n $.append(this.nodes.wrapper, [this.nodes.buttons, this.nodes.actions]);\n $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\n /**\n * Append Inline Toolbar Tools\n */\n this.addTools();\n }\n /**\n *\n *\n * Moving / appearance\n * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n *\n */\n /**\n * Shows Inline Toolbar by keyup/mouseup\n * @param {KeyboardEvent|MouseEvent} event\n */\n handleShowingEvent(event) {\n if (!this.allowedToShow(event)) {\n this.close();\n return;\n }\n this.move();\n this.open();\n /** Check Tools state for selected fragment */\n this.checkToolsState();\n }\n /**\n * Move Toolbar to the selected text\n */\n move() {\n const selectionRect = Selection.rect;\n const wrapperOffset = this.Editor.UI.nodes.wrapper.getBoundingClientRect();\n const newCoords = {\n x: selectionRect.x - wrapperOffset.left,\n y: selectionRect.y\n + selectionRect.height\n // + window.scrollY\n - wrapperOffset.top\n + this.toolbarVerticalMargin,\n };\n /**\n * If we know selections width, place InlineToolbar to center\n */\n if (selectionRect.width) {\n newCoords.x += Math.floor(selectionRect.width / 2);\n }\n this.nodes.wrapper.style.left = Math.floor(newCoords.x) + 'px';\n this.nodes.wrapper.style.top = Math.floor(newCoords.y) + 'px';\n }\n /**\n * Shows Inline Toolbar\n */\n open() {\n this.nodes.wrapper.classList.add(this.CSS.inlineToolbarShowed);\n this.tools.forEach((tool) => {\n if (typeof tool.clear === 'function') {\n tool.clear();\n }\n });\n }\n /**\n * Hides Inline Toolbar\n */\n close() {\n this.nodes.wrapper.classList.remove(this.CSS.inlineToolbarShowed);\n this.tools.forEach((tool) => {\n if (typeof tool.clear === 'function') {\n tool.clear();\n }\n });\n }\n /**\n * Need to show Inline Toolbar or not\n * @param {KeyboardEvent|MouseEvent} event\n */\n allowedToShow(event) {\n /**\n * Tags conflicts with window.selection function.\n * Ex. IMG tag returns null (Firefox) or Redactors wrapper (Chrome)\n */\n const tagsConflictsWithSelection = ['IMG', 'INPUT'];\n if (event && tagsConflictsWithSelection.includes(event.target.tagName)) {\n return false;\n }\n const currentSelection = Selection.get(), selectedText = Selection.text;\n // old browsers\n if (!currentSelection || !currentSelection.anchorNode) {\n return false;\n }\n // empty selection\n if (currentSelection.isCollapsed || selectedText.length < 1) {\n return false;\n }\n // is enabled by current Block's Tool\n const currentBlock = this.Editor.BlockManager.getBlock(currentSelection.anchorNode);\n if (!currentBlock) {\n return false;\n }\n const toolConfig = this.config.toolsConfig[currentBlock.name];\n return toolConfig && toolConfig[this.Editor.Tools.apiSettings.IS_ENABLED_INLINE_TOOLBAR];\n }\n /**\n *\n *\n * Working with Tools\n * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n *\n */\n /**\n * Fill Inline Toolbar with Tools\n */\n addTools() {\n this.tools.forEach((tool) => {\n this.addTool(tool);\n });\n }\n /**\n * Add tool button and activate clicks\n * @param {InlineTool} tool - Tool's instance\n */\n addTool(tool) {\n const button = tool.render();\n if (!button) {\n _.log('Render method must return an instance of Node', 'warn', tool);\n return;\n }\n this.nodes.buttons.appendChild(button);\n if (typeof tool.renderActions === 'function') {\n const actions = tool.renderActions();\n this.nodes.actions.appendChild(actions);\n }\n this.Editor.Listeners.on(button, 'click', () => {\n this.toolClicked(tool);\n });\n }\n /**\n * Inline Tool button clicks\n * @param {InlineTool} tool - Tool's instance\n */\n toolClicked(tool) {\n const range = Selection.range;\n tool.surround(range);\n this.checkToolsState();\n }\n /**\n * Check Tools` state by selection\n */\n checkToolsState() {\n this.tools.forEach((tool) => {\n tool.checkState(Selection.get());\n });\n }\n}\n","/**\n * @class Toolbox\n * @classdesc Holder for Tools\n *\n * @typedef {Toolbox} Toolbox\n * @property {Boolean} opened - opening state\n * @property {Object} nodes - Toolbox nodes\n * @property {Object} CSS - CSS class names\n *\n */\nexport default class Toolbox extends Module {\n /**\n * @constructor\n */\n constructor({config}) {\n super({config});\n\n this.nodes = {\n toolbox: null,\n buttons: []\n };\n\n /**\n * Opening state\n * @type {boolean}\n */\n this.opened = false;\n }\n\n /**\n * CSS styles\n * @return {{toolbox: string, toolboxButton: string, toolboxOpened: string}}\n */\n static get CSS() {\n return {\n toolbox: 'ce-toolbox',\n toolboxButton: 'ce-toolbox__button',\n toolboxOpened: 'ce-toolbox--opened',\n };\n }\n\n /**\n * Makes the Toolbox\n */\n make() {\n this.nodes.toolbox = $.make('div', Toolbox.CSS.toolbox);\n $.append(this.Editor.Toolbar.nodes.content, this.nodes.toolbox);\n\n this.addTools();\n }\n\n /**\n * Iterates available tools and appends them to the Toolbox\n */\n addTools() {\n let tools = this.Editor.Tools.toolsAvailable;\n\n for (let toolName in tools) {\n this.addTool(toolName, tools[toolName]);\n }\n }\n\n /**\n * Append Tool to the Toolbox\n *\n * @param {string} toolName - tool name\n * @param {Tool} tool - tool class\n */\n addTool(toolName, tool) {\n const api = this.Editor.Tools.apiSettings;\n\n if (tool[api.IS_DISPLAYED_IN_TOOLBOX] && !tool[api.TOOLBAR_ICON_CLASS]) {\n _.log('Toolbar icon class name is missed. Tool %o skipped', 'warn', toolName);\n return;\n }\n\n /**\n * @todo Add checkup for the render method\n */\n // if (typeof tool.render !== 'function') {\n //\n // _.log('render method missed. Tool %o skipped', 'warn', tool);\n // return;\n //\n // }\n\n /**\n * Skip tools that pass 'displayInToolbox=false'\n */\n if (!tool[api.IS_DISPLAYED_IN_TOOLBOX]) {\n return;\n }\n\n let button = $.make('li', [Toolbox.CSS.toolboxButton, tool[api.TOOLBAR_ICON_CLASS]], {\n title: toolName\n });\n\n /**\n * Save tool's name in the button data-name\n */\n button.dataset.name = toolName;\n\n $.append(this.nodes.toolbox, button);\n\n this.nodes.toolbox.appendChild(button);\n this.nodes.buttons.push(button);\n\n /**\n * @todo add event with module Listeners\n */\n // this.Editor.Listeners.add();\n button.addEventListener('click', event => {\n this.buttonClicked(event);\n }, false);\n }\n\n /**\n * Toolbox button click listener\n * 1) if block is empty -> replace\n * 2) if block is not empty -> add new block below\n *\n * @param {MouseEvent} event\n */\n buttonClicked(event) {\n let toolButton = event.target,\n toolName = toolButton.dataset.name,\n tool = this.Editor.Tools.toolClasses[toolName];\n\n /**\n * @type {Block}\n */\n let currentBlock = this.Editor.BlockManager.currentBlock;\n\n /**\n * We do replace if:\n * - block is empty\n * - block is not irreplaceable\n * @type {Array}\n */\n if (!tool[this.Editor.Tools.apiSettings.IS_IRREPLACEBLE_TOOL] && currentBlock.isEmpty) {\n this.Editor.BlockManager.replace(toolName);\n } else {\n this.Editor.BlockManager.insert(toolName);\n }\n\n /**\n * @todo set caret to the new block\n */\n\n // window.setTimeout(function () {\n\n /** Set caret to current block */\n // editor.caret.setToBlock(currentInputIndex);\n\n // }, 10);\n\n /**\n * Move toolbar when node is changed\n */\n this.Editor.Toolbar.move();\n }\n\n /**\n * Open Toolbox with Tools\n */\n open() {\n this.nodes.toolbox.classList.add(Toolbox.CSS.toolboxOpened);\n this.opened = true;\n }\n\n /**\n * Close Toolbox\n */\n close() {\n this.nodes.toolbox.classList.remove(Toolbox.CSS.toolboxOpened);\n this.opened = false;\n }\n\n /**\n * Close Toolbox\n */\n toggle() {\n if (!this.opened) {\n this.open();\n } else {\n this.close();\n }\n }\n}\n","/**\n *\n * «Toolbar» is the node that moves up/down over current block\n *\n * ______________________________________ Toolbar ____________________________________________\n * | |\n * | ..................... Content .................... ......... Block Actions .......... |\n * | . . . . |\n * | . . . [Open Settings] . |\n * | . [Plus Button] [Toolbox: {Tool1}, {Tool2}] . . . |\n * | . . . [Settings Panel] . |\n * | .................................................. .................................. |\n * | |\n * |___________________________________________________________________________________________|\n *\n *\n * Toolbox — its an Element contains tools buttons. Can be shown by Plus Button.\n *\n * _______________ Toolbox _______________\n * | |\n * | [Header] [Image] [List] [Quote] ... |\n * |_______________________________________|\n *\n *\n * Settings Panel — is an Element with block settings:\n *\n * ____ Settings Panel ____\n * | ...................... |\n * | . Tool Settings . |\n * | ...................... |\n * | . Default Settings . |\n * | ...................... |\n * |________________________|\n *\n *\n * @class\n * @classdesc Toolbar module\n *\n * @typedef {Toolbar} Toolbar\n * @property {Object} nodes\n * @property {Element} nodes.wrapper - Toolbar main element\n * @property {Element} nodes.content - Zone with Plus button and toolbox.\n * @property {Element} nodes.actions - Zone with Block Settings and Remove Button\n * @property {Element} nodes.blockActionsButtons - Zone with Block Buttons: [Settings]\n * @property {Element} nodes.plusButton - Button that opens or closes Toolbox\n * @property {Element} nodes.toolbox - Container for tools\n * @property {Element} nodes.settingsToggler - open/close Settings Panel button\n * @property {Element} nodes.settings - Settings Panel\n * @property {Element} nodes.pluginSettings - Plugin Settings section of Settings Panel\n * @property {Element} nodes.defaultSettings - Default Settings section of Settings Panel\n */\nexport default class Toolbar extends Module {\n /**\n * @constructor\n */\n constructor({config}) {\n super({config});\n\n this.nodes = {\n wrapper : null,\n content : null,\n actions : null,\n\n // Content Zone\n plusButton : null,\n\n // Actions Zone\n blockActionsButtons: null,\n settingsToggler : null,\n };\n }\n\n /**\n * CSS styles\n * @return {Object}\n * @constructor\n */\n static get CSS() {\n return {\n toolbar: 'ce-toolbar',\n content: 'ce-toolbar__content',\n actions: 'ce-toolbar__actions',\n\n toolbarOpened: 'ce-toolbar--opened',\n\n // Content Zone\n plusButton: 'ce-toolbar__plus',\n plusButtonHidden: 'ce-toolbar__plus--hidden',\n\n // Actions Zone\n blockActionsButtons: 'ce-toolbar__actions-buttons',\n settingsToggler: 'ce-toolbar__settings-btn',\n };\n }\n\n /**\n * Makes toolbar\n */\n make() {\n this.nodes.wrapper = $.make('div', Toolbar.CSS.toolbar);\n\n /**\n * Make Content Zone and Actions Zone\n */\n ['content', 'actions'].forEach( el => {\n this.nodes[el] = $.make('div', Toolbar.CSS[el]);\n $.append(this.nodes.wrapper, this.nodes[el]);\n });\n\n\n /**\n * Fill Content Zone:\n * - Plus Button\n * - Toolbox\n */\n this.nodes.plusButton = $.make('div', Toolbar.CSS.plusButton);\n $.append(this.nodes.plusButton, $.svg('plus', 14, 14));\n $.append(this.nodes.content, this.nodes.plusButton);\n this.nodes.plusButton.addEventListener('click', event => this.plusButtonClicked(event), false);\n\n\n /**\n * Make a Toolbox\n */\n this.Editor.Toolbox.make();\n\n /**\n * Fill Actions Zone:\n * - Settings Toggler\n * - Remove Block Button\n * - Settings Panel\n */\n this.nodes.blockActionsButtons = $.make('div', Toolbar.CSS.blockActionsButtons);\n this.nodes.settingsToggler = $.make('span', Toolbar.CSS.settingsToggler);\n const settingsIcon = $.svg('dots', 18, 4);\n\n $.append(this.nodes.settingsToggler, settingsIcon);\n $.append(this.nodes.blockActionsButtons, this.nodes.settingsToggler);\n $.append(this.nodes.actions, this.nodes.blockActionsButtons);\n\n /**\n * Make and append Settings Panel\n */\n this.Editor.BlockSettings.make();\n $.append(this.nodes.actions, this.Editor.BlockSettings.nodes.wrapper);\n\n /**\n * Append toolbar to the Editor\n */\n $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\n\n /**\n * Bind events on the Toolbar elements\n */\n this.bindEvents();\n }\n\n /**\n * Move Toolbar to the Current Block\n * @param {Boolean} forceClose - force close Toolbar Settings and Toolbar\n */\n move(forceClose = true) {\n if (forceClose) {\n /** Close Toolbox when we move toolbar */\n this.Editor.Toolbox.close();\n this.Editor.BlockSettings.close();\n }\n\n let currentNode = this.Editor.BlockManager.currentNode;\n\n /**\n * If no one Block selected as a Current\n */\n if (!currentNode) {\n return;\n }\n\n /**\n * @todo Compute dynamically on prepare\n * @type {number}\n */\n const defaultToolbarHeight = 49;\n const defaultOffset = 34;\n\n var newYCoordinate = currentNode.offsetTop - (defaultToolbarHeight / 2) + defaultOffset;\n\n this.nodes.wrapper.style.transform = `translate3D(0, ${Math.floor(newYCoordinate)}px, 0)`;\n }\n\n /**\n * Open Toolbar with Plus Button\n */\n open() {\n this.nodes.wrapper.classList.add(Toolbar.CSS.toolbarOpened);\n }\n\n /**\n * Close the Toolbar\n */\n close() {\n this.nodes.wrapper.classList.remove(Toolbar.CSS.toolbarOpened);\n }\n\n /**\n * Plus Button public methods\n * @return {{hide: function(): void, show: function(): void}}\n */\n get plusButton() {\n return {\n hide: () => this.nodes.plusButton.classList.add(Toolbar.CSS.plusButtonHidden),\n show: () => this.nodes.plusButton.classList.remove(Toolbar.CSS.plusButtonHidden)\n };\n }\n\n /**\n * Handler for Plus Button\n * @param {MouseEvent} event\n */\n plusButtonClicked() {\n this.Editor.Toolbox.toggle();\n }\n\n /**\n * Bind events on the Toolbar Elements:\n * - Block Settings\n */\n bindEvents() {\n /**\n * Settings toggler\n */\n this.Editor.Listeners.on(this.nodes.settingsToggler, 'click', (event) => {\n this.settingsTogglerClicked(event);\n });\n }\n\n /**\n * Clicks on the Block Settings toggler\n */\n settingsTogglerClicked() {\n if (this.Editor.BlockSettings.opened) {\n this.Editor.BlockSettings.close();\n } else {\n this.Editor.BlockSettings.open();\n }\n }\n}\n","/**\n * @module Codex Editor Tools Submodule\n *\n * Creates Instances from Plugins and binds external config to the instances\n */\n\n/**\n * Each Tool must contain the following important objects:\n *\n * @typedef {Object} ToolConfig {@link docs/tools.md}\n * @property {String} iconClassname - this a icon in toolbar\n * @property {Boolean} displayInToolbox - will be displayed in toolbox. Default value is TRUE\n * @property {Boolean} enableLineBreaks - inserts new block or break lines. Default value is FALSE\n * @property {Boolean|String[]} inlineToolbar - Pass `true` to enable the Inline Toolbar with all Tools, all pass an array with specified Tools list |\n * @property render @todo add description\n * @property save @todo add description\n * @property settings @todo add description\n * @property validate - method that validates output data before saving\n */\n\n/**\n * @typedef {Function} Tool {@link docs/tools.md}\n * @property {Boolean} displayInToolbox - By default, tools won't be added in the Toolbox. Pass true to add.\n * @property {String} iconClassName - CSS class name for the Toolbox button\n * @property {Boolean} irreplaceable - Toolbox behaviour: replace or add new block below\n * @property render\n * @property save\n * @property settings\n * @property validate\n *\n * @todo update according to current API\n * @todo describe Tool in the {@link docs/tools.md}\n */\n\n/**\n * Class properties:\n *\n * @typedef {Tools} Tools\n * @property {Tools[]} toolsAvailable - available Tools\n * @property {Tools[]} toolsUnavailable - unavailable Tools\n * @property {Object} toolsClasses - all classes\n * @property {EditorConfig} config - Editor config\n */\nexport default class Tools extends Module {\n /**\n * Returns available Tools\n * @return {Tool[]}\n */\n get available() {\n return this.toolsAvailable;\n }\n\n /**\n * Returns unavailable Tools\n * @return {Tool[]}\n */\n get unavailable() {\n return this.toolsUnavailable;\n }\n\n /**\n * Return Tools for the Inline Toolbar\n * @return {Array} - array of Inline Tool's classes\n */\n get inline() {\n return Object.values(this.available).filter( tool => {\n if (!tool[this.apiSettings.IS_INLINE]) {\n return false;\n }\n\n /**\n * Some Tools validation\n */\n const inlineToolRequiredMethods = ['render', 'surround', 'checkState'];\n const notImplementedMethods = inlineToolRequiredMethods.filter( method => !new tool()[method] );\n\n if (notImplementedMethods.length) {\n _.log(`Incorrect Inline Tool: ${tool.name}. Some of required methods is not implemented %o`, 'warn', notImplementedMethods);\n return false;\n }\n\n return true;\n });\n }\n\n /**\n * Constant for available Tools Settings\n * @return {object}\n */\n get apiSettings() {\n return {\n IS_INLINE: 'isInline',\n TOOLBAR_ICON_CLASS: 'iconClassName',\n IS_DISPLAYED_IN_TOOLBOX: 'displayInToolbox',\n IS_ENABLED_LINE_BREAKS: 'enableLineBreaks',\n IS_IRREPLACEBLE_TOOL: 'irreplaceable',\n IS_ENABLED_INLINE_TOOLBAR: 'inlineToolbar',\n };\n }\n\n /**\n * Static getter for default Tool config fields\n * @return {ToolConfig}\n */\n get defaultConfig() {\n return {\n [this.apiSettings.TOOLBAR_ICON_CLASS] : false,\n [this.apiSettings.IS_DISPLAYED_IN_TOOLBOX] : false,\n [this.apiSettings.IS_ENABLED_LINE_BREAKS] : false,\n [this.apiSettings.IS_IRREPLACEBLE_TOOL] : false,\n [this.apiSettings.IS_ENABLED_INLINE_TOOLBAR]: false,\n };\n }\n\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor({config}) {\n super({config});\n\n /**\n * Map {name: Class, ...} where:\n * name — block type name in JSON. Got from EditorConfig.tools keys\n * @type {Object}\n */\n this.toolClasses = {};\n\n /**\n * Available tools list\n * {name: Class, ...}\n * @type {Object}\n */\n this.toolsAvailable = {};\n\n /**\n * Tools that rejected a prepare method\n * {name: Class, ... }\n * @type {Object}\n */\n this.toolsUnavailable = {};\n }\n\n /**\n * Creates instances via passed or default configuration\n * @return {Promise}\n */\n prepare() {\n if (!this.config.hasOwnProperty('tools')) {\n return Promise.reject(\"Can't start without tools\");\n }\n\n for(let toolName in this.config.tools) {\n this.toolClasses[toolName] = this.config.tools[toolName];\n }\n\n /**\n * getting classes that has prepare method\n */\n let sequenceData = this.getListOfPrepareFunctions();\n\n /**\n * if sequence data contains nothing then resolve current chain and run other module prepare\n */\n if (sequenceData.length === 0) {\n return Promise.resolve();\n }\n\n /**\n * to see how it works {@link Util#sequence}\n */\n return _.sequence(sequenceData, (data) => {\n this.success(data);\n }, (data) => {\n this.fallback(data);\n });\n }\n\n /**\n * Binds prepare function of plugins with user or default config\n * @return {Array} list of functions that needs to be fired sequentially\n */\n getListOfPrepareFunctions() {\n let toolPreparationList = [];\n\n for(let toolName in this.toolClasses) {\n let toolClass = this.toolClasses[toolName];\n\n if (typeof toolClass.prepare === 'function') {\n toolPreparationList.push({\n function : toolClass.prepare,\n data : {\n toolName\n }\n });\n } else {\n /**\n * If Tool hasn't a prepare method, mark it as available\n */\n this.toolsAvailable[toolName] = toolClass;\n }\n }\n\n return toolPreparationList;\n }\n\n /**\n * @param {ChainData.data} data - append tool to available list\n */\n success(data) {\n this.toolsAvailable[data.toolName] = this.toolClasses[data.toolName];\n }\n\n /**\n * @param {ChainData.data} data - append tool to unavailable list\n */\n fallback(data) {\n this.toolsUnavailable[data.toolName] = this.toolClasses[data.toolName];\n }\n\n /**\n * Return tool`a instance\n *\n * @param {String} tool — tool name\n * @param {Object} data — initial data\n *\n * @todo throw exceptions if tool doesnt exist\n *\n */\n construct(tool, data) {\n let plugin = this.toolClasses[tool],\n config = this.config.toolsConfig[tool];\n\n let instance = new plugin(data, config || {});\n\n return instance;\n }\n\n /**\n * Check if passed Tool is an instance of Initial Block Tool\n * @param {Tool} tool - Tool to check\n * @return {Boolean}\n */\n isInitial(tool) {\n return tool instanceof this.available[this.config.initialBlock];\n }\n}\n","/**\n * Module UI\n *\n * @type {UI}\n */\n\n/**\n * Prebuilded sprite of SVG icons\n */\nimport sprite from '../../../build/sprite.svg';\nimport Selection from '../selection';\n\n/**\n * @class\n *\n * @classdesc Makes CodeX Editor UI:\n * \n * \n * \n * \n * \n *\n * @typedef {UI} UI\n * @property {EditorConfig} config - editor configuration {@link CodexEditor#configuration}\n * @property {Object} Editor - available editor modules {@link CodexEditor#moduleInstances}\n * @property {Object} nodes -\n * @property {Element} nodes.holder - element where we need to append redactor\n * @property {Element} nodes.wrapper - \n * @property {Element} nodes.redactor - \n */\nexport default class UI extends Module {\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor({config}) {\n super({config});\n\n this.nodes = {\n holder: null,\n wrapper: null,\n redactor: null\n };\n }\n\n /**\n * Making main interface\n */\n prepare() {\n return this.make()\n /**\n * Append SVG sprite\n */\n .then(() => this.appendSVGSprite())\n /**\n * Make toolbar\n */\n .then(() => this.Editor.Toolbar.make())\n /**\n * Make the Inline toolbar\n */\n .then(() => this.Editor.InlineToolbar.make())\n /**\n * Load and append CSS\n */\n .then(() => this.loadStyles())\n /**\n * Bind events for the UI elements\n */\n .then(() => this.bindEvents())\n\n /** Make container for inline toolbar */\n // .then(makeInlineToolbar_)\n\n /** Add inline toolbar tools */\n // .then(addInlineToolbarTools_)\n\n /** Draw wrapper for notifications */\n // .then(makeNotificationHolder_)\n\n /** Add eventlisteners to redactor elements */\n // .then(bindEvents_)\n\n .catch(e => {\n console.error(e);\n\n // editor.core.log(\"Can't draw editor interface\");\n });\n }\n\n /**\n * CodeX Editor UI CSS class names\n * @return {{editorWrapper: string, editorZone: string, block: string}}\n */\n get CSS() {\n return {\n editorWrapper : 'codex-editor',\n editorZone : 'codex-editor__redactor',\n };\n }\n\n /**\n * Makes CodeX Editor interface\n * @return {Promise}\n */\n make() {\n return new Promise( (resolve, reject) => {\n /**\n * Element where we need to append CodeX Editor\n * @type {Element}\n */\n this.nodes.holder = document.getElementById(this.config.holderId);\n\n if (!this.nodes.holder) {\n reject(Error(\"Holder wasn't found by ID: #\" + this.config.holderId));\n return;\n }\n\n /**\n * Create and save main UI elements\n */\n this.nodes.wrapper = $.make('div', this.CSS.editorWrapper);\n this.nodes.redactor = $.make('div', this.CSS.editorZone);\n\n this.nodes.wrapper.appendChild(this.nodes.redactor);\n this.nodes.holder.appendChild(this.nodes.wrapper);\n\n resolve();\n });\n }\n\n /**\n * Appends CSS\n */\n loadStyles() {\n /**\n * Load CSS\n */\n let styles = require('../../styles/main.css');\n\n /**\n * Make tag\n */\n let tag = $.make('style', null, {\n textContent: styles.toString()\n });\n\n /**\n * Append styles\n */\n $.append(document.head, tag);\n }\n\n /**\n * Bind events on the CodeX Editor interface\n */\n bindEvents() {\n this.Editor.Listeners.on(this.nodes.redactor, 'click', event => this.redactorClicked(event), false );\n this.Editor.Listeners.on(document, 'keydown', event => this.documentKeydown(event), true );\n this.Editor.Listeners.on(document, 'click', event => this.documentClicked(event), false );\n }\n\n /**\n * All keydowns on document\n * @param event\n */\n documentKeydown(event) {\n switch (event.keyCode) {\n case _.keyCodes.ENTER:\n this.enterPressed(event);\n break;\n\n default:\n this.defaultBehaviour(event);\n break;\n }\n }\n\n /**\n * Ignore all other document's keydown events\n * @param {KeyboardEvent} event\n */\n defaultBehaviour(event) {\n const keyDownOnEditor = event.target.closest(`.${this.CSS.editorWrapper}`);\n\n /**\n * Ignore keydowns on document\n * clear pointer and close toolbar\n */\n if (!keyDownOnEditor) {\n /**\n * Remove all highlights and remove caret\n */\n this.Editor.BlockManager.dropPointer();\n\n /**\n * Close Toolbar\n */\n this.Editor.Toolbar.close();\n }\n }\n\n /**\n * Enter pressed on document\n * @param event\n */\n enterPressed(event) {\n let hasPointerToBlock = this.Editor.BlockManager.currentBlockIndex >= 0;\n\n /**\n * If Selection is out of Editor and document has some selection\n */\n if (!Selection.isAtEditor && Selection.anchorNode) {\n return;\n }\n\n /**\n * If there is no selection (caret is not placed) and BlockManager points some to Block\n */\n if (hasPointerToBlock && !Selection.anchorNode) {\n /**\n * Insert initial typed Block\n */\n this.Editor.BlockManager.insert();\n this.Editor.BlockManager.highlightCurrentNode();\n\n /**\n * Move toolbar and show plus button because new Block is empty\n */\n this.Editor.Toolbar.move();\n this.Editor.Toolbar.plusButton.show();\n }\n }\n\n /**\n * All clicks on document\n * @param {MouseEvent} event - Click\n */\n documentClicked(event) {\n /**\n * Close Inline Toolbar when nothing selected\n * Do not fire check on clicks at the Inline Toolbar buttons\n */\n const clickedOnInlineToolbarButton = event.target.closest(`.${this.Editor.InlineToolbar.CSS.inlineToolbar}`);\n const clickedInsideofEditor = event.target.closest(`.${this.CSS.editorWrapper}`);\n\n /** Clear highlightings and pointer on BlockManager */\n if (!clickedInsideofEditor) {\n this.Editor.BlockManager.dropPointer();\n this.Editor.Toolbar.close();\n }\n\n if (!clickedOnInlineToolbarButton) {\n this.Editor.InlineToolbar.handleShowingEvent(event);\n }\n }\n\n /**\n * All clicks on the redactor zone\n *\n * @param {MouseEvent} event\n *\n * @description\n * 1. Save clicked Block as a current {@link BlockManager#currentNode}\n * it uses for the following:\n * - add CSS modifier for the selected Block\n * - on Enter press, we make a new Block under that\n *\n * 2. Move and show the Toolbar\n *\n * 3. Set a Caret\n *\n * 4. By clicks on the Editor's bottom zone:\n * - if last Block is empty, set a Caret to this\n * - otherwise, add a new empty Block and set a Caret to that\n *\n * 5. Hide the Inline Toolbar\n *\n * @see selectClickedBlock\n *\n */\n redactorClicked(event) {\n let clickedNode = event.target;\n\n /**\n * Select clicked Block as Current\n */\n try {\n /**\n * Renew Current Block\n */\n this.Editor.BlockManager.setCurrentBlockByChildNode(clickedNode);\n\n /**\n * Highlight Current Node\n */\n this.Editor.BlockManager.highlightCurrentNode();\n } catch (e) {\n /**\n * If clicked outside first-level Blocks, set Caret to the last empty Block\n */\n this.Editor.Caret.setToTheLastBlock();\n }\n\n /**\n * Move toolbar and open\n */\n this.Editor.Toolbar.move();\n this.Editor.Toolbar.open();\n\n /**\n * Hide the Plus Button\n * */\n this.Editor.Toolbar.plusButton.hide();\n\n /**\n * Show the Plus Button if:\n * - Block is an initial-block (Text)\n * - Block is empty\n */\n let isInitialBlock = this.Editor.Tools.isInitial(this.Editor.BlockManager.currentBlock.tool),\n isEmptyBlock = this.Editor.BlockManager.currentBlock.isEmpty;\n\n if (isInitialBlock && isEmptyBlock) {\n this.Editor.Toolbar.plusButton.show();\n }\n }\n\n /**\n * Append prebuilded sprite with SVG icons\n */\n appendSVGSprite() {\n let spriteHolder = $.make('div');\n\n spriteHolder.innerHTML = sprite;\n\n $.append(this.nodes.wrapper, spriteHolder);\n }\n}\n\n// /**\n// * Codex Editor UI module\n// *\n// * @author Codex Team\n// * @version 1.2.0\n// */\n//\n// module.exports = (function (ui) {\n//\n// let editor = codex.editor;\n//\n// /**\n// * Basic editor classnames\n// */\n// ui.prepare = function () {\n//\n\n//\n// };\n//\n// /** Draw notifications holder */\n// var makeNotificationHolder_ = function () {\n//\n// /** Append block with notifications to the document */\n// editor.nodes.notifications = editor.notifications.createHolder();\n//\n// };\n//\n//\n// var addInlineToolbarTools_ = function () {\n//\n// var tools = {\n//\n// bold: {\n// icon : 'ce-icon-bold',\n// command : 'bold'\n// },\n//\n// italic: {\n// icon : 'ce-icon-italic',\n// command : 'italic'\n// },\n//\n// link: {\n// icon : 'ce-icon-link',\n// command : 'createLink'\n// }\n// };\n//\n// var toolButton,\n// tool;\n//\n// for(var name in tools) {\n//\n// tool = tools[name];\n//\n// toolButton = editor.draw.toolbarButtonInline(name, tool.icon);\n//\n// editor.nodes.inlineToolbar.buttons.appendChild(toolButton);\n// /**\n// * Add callbacks to this buttons\n// */\n// editor.ui.setInlineToolbarButtonBehaviour(toolButton, tool.command);\n//\n// }\n//\n// };\n//\n// /**\n// * @private\n// * Bind editor UI events\n// */\n// var bindEvents_ = function () {\n//\n// editor.core.log('ui.bindEvents fired', 'info');\n//\n// // window.addEventListener('error', function (errorMsg, url, lineNumber) {\n// // editor.notifications.errorThrown(errorMsg, event);\n// // }, false );\n//\n// /** All keydowns on Document */\n// editor.listeners.add(document, 'keydown', editor.callback.globalKeydown, false);\n//\n// /** All keydowns on Redactor zone */\n// editor.listeners.add(editor.nodes.redactor, 'keydown', editor.callback.redactorKeyDown, false);\n//\n// /** All keydowns on Document */\n// editor.listeners.add(document, 'keyup', editor.callback.globalKeyup, false );\n//\n// /**\n// * Mouse click to radactor\n// */\n// editor.listeners.add(editor.nodes.redactor, 'click', editor.callback.redactorClicked, false );\n//\n// /**\n// * Clicks to the Plus button\n// */\n// editor.listeners.add(editor.nodes.plusButton, 'click', editor.callback.plusButtonClicked, false);\n//\n// /**\n// * Clicks to SETTINGS button in toolbar\n// */\n// editor.listeners.add(editor.nodes.showSettingsButton, 'click', editor.callback.showSettingsButtonClicked, false );\n//\n// /** Bind click listeners on toolbar buttons */\n// for (var button in editor.nodes.toolbarButtons) {\n//\n// editor.listeners.add(editor.nodes.toolbarButtons[button], 'click', editor.callback.toolbarButtonClicked, false);\n//\n// }\n//\n// };\n//\n// ui.addBlockHandlers = function (block) {\n//\n// if (!block) return;\n//\n// /**\n// * Block keydowns\n// */\n// editor.listeners.add(block, 'keydown', editor.callback.blockKeydown, false);\n//\n// /**\n// * Pasting content from another source\n// * We have two type of sanitization\n// * First - uses deep-first search algorithm to get sub nodes,\n// * sanitizes whole Block_content and replaces cleared nodes\n// * This method is deprecated\n// * Method is used in editor.callback.blockPaste(event)\n// *\n// * Secont - uses Mutation observer.\n// * Observer \"observe\" DOM changes and send changings to callback.\n// * Callback gets changed node, not whole Block_content.\n// * Inserted or changed node, which we've gotten have been cleared and replaced with diry node\n// *\n// * Method is used in editor.callback.blockPasteViaSanitize(event)\n// *\n// * @uses html-janitor\n// * @example editor.callback.blockPasteViaSanitize(event), the second method.\n// *\n// */\n// editor.listeners.add(block, 'paste', editor.paste.blockPasteCallback, false);\n//\n// /**\n// * Show inline toolbar for selected text\n// */\n// editor.listeners.add(block, 'mouseup', editor.toolbar.inline.show, false);\n// editor.listeners.add(block, 'keyup', editor.toolbar.inline.show, false);\n//\n// };\n//\n// /** getting all contenteditable elements */\n// ui.saveInputs = function () {\n//\n// var redactor = editor.nodes.redactor;\n//\n// editor.state.inputs = [];\n//\n// /** Save all inputs in global variable state */\n// var inputs = redactor.querySelectorAll('[contenteditable], input, textarea');\n//\n// Array.prototype.map.call(inputs, function (current) {\n//\n// if (!current.type || current.type == 'text' || current.type == 'textarea') {\n//\n// editor.state.inputs.push(current);\n//\n// }\n//\n// });\n//\n// };\n//\n// /**\n// * Adds first initial block on empty redactor\n// */\n// ui.addInitialBlock = function () {\n//\n// var initialBlockType = editor.settings.initialBlockPlugin,\n// initialBlock;\n//\n// if ( !editor.tools[initialBlockType] ) {\n//\n// editor.core.log('Plugin %o was not implemented and can\\'t be used as initial block', 'warn', initialBlockType);\n// return;\n//\n// }\n//\n// initialBlock = editor.tools[initialBlockType].render();\n//\n// initialBlock.setAttribute('data-placeholder', editor.settings.placeholder);\n//\n// editor.content.insertBlock({\n// type : initialBlockType,\n// block : initialBlock\n// });\n//\n// editor.content.workingNodeChanged(initialBlock);\n//\n// };\n//\n// ui.setInlineToolbarButtonBehaviour = function (button, type) {\n//\n// editor.listeners.add(button, 'mousedown', function (event) {\n//\n// editor.toolbar.inline.toolClicked(event, type);\n//\n// }, false);\n//\n// };\n//\n// return ui;\n//\n// })({});\n","/**\n * Element.closest()\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/Element/closest\n */\nif (!Element.prototype.matches)\n Element.prototype.matches = Element.prototype.msMatchesSelector ||\n Element.prototype.webkitMatchesSelector;\n\nif (!Element.prototype.closest)\n Element.prototype.closest = function (s) {\n var el = this;\n\n if (!document.documentElement.contains(el)) return null;\n do {\n if (el.matches(s)) return el;\n el = el.parentElement || el.parentNode;\n } while (el !== null);\n return null;\n };\n","/**\n * Working with selection\n * @typedef {Selection} Selection\n */\nexport default class Selection {\n /**\n * @constructor\n */\n constructor() {\n this.instance = null;\n this.selection = null;\n\n /**\n * This property can store Selection's range for restoring later\n * @type {Range|null}\n */\n this.savedSelectionRange = null;\n }\n\n /**\n * Editor styles\n * @return {{editorWrapper: string, editorZone: string}}\n * @constructor\n */\n static get CSS() {\n return {\n editorWrapper : 'codex-editor',\n editorZone : 'codex-editor__redactor',\n };\n }\n\n /**\n * Returns window Selection\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Window/getSelection}\n * @return {Selection}\n */\n static get() {\n return window.getSelection();\n }\n\n /**\n * Returns selected anchor\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorNode}\n * @return {Node|null}\n */\n static get anchorNode() {\n const selection = window.getSelection();\n\n return selection ? selection.anchorNode : null;\n }\n\n /**\n * Returns selection offset according to the anchor node\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorOffset}\n * @return {Number|null}\n */\n static get anchorOffset() {\n const selection = window.getSelection();\n\n return selection ? selection.anchorOffset : null;\n }\n\n /**\n * Is current selection range collapsed\n * @return {boolean|null}\n */\n static get isCollapsed() {\n const selection = window.getSelection();\n\n return selection ? selection.isCollapsed : null;\n }\n\n /**\n * Check current selection if it is at Editor's zone\n * @return {boolean}\n */\n static get isAtEditor() {\n let selection = Selection.get(),\n selectedNode,\n editorZone = false;\n\n /**\n * Something selected on document\n */\n selectedNode = selection.anchorNode || selection.focusNode;\n\n if (selectedNode && selectedNode.nodeType === Node.TEXT_NODE) {\n selectedNode = selectedNode.parentNode;\n }\n\n if (selectedNode) {\n editorZone = selectedNode.closest(`.${Selection.CSS.editorZone}`);\n }\n\n /**\n * Selection is not out of Editor because Editor's wrapper was found\n */\n return editorZone && editorZone.nodeType === Node.ELEMENT_NODE;\n }\n\n /**\n * Return first range\n * @return {Range|null}\n */\n static get range() {\n const selection = window.getSelection();\n\n return selection && selection.rangeCount ? selection.getRangeAt(0) : null;\n }\n\n /**\n * Calculates position and size of selected text\n * @return {{x, y, width, height, top?, left?, bottom?, right?}}\n */\n static get rect() {\n let sel = document.selection, range;\n let rect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0\n };\n\n if (sel && sel.type !== 'Control') {\n range = sel.createRange();\n rect.x = range.boundingLeft;\n rect.y = range.boundingTop;\n rect.width = range.boundingWidth;\n rect.height = range.boundingHeight;\n\n return rect;\n }\n\n if (!window.getSelection) {\n _.log('Method window.getSelection is not supported', 'warn');\n return rect;\n }\n\n sel = window.getSelection();\n\n if (!sel.rangeCount) {\n _.log('Method Selection.rangeCount() is not supported', 'warn');\n return rect;\n }\n\n range = sel.getRangeAt(0).cloneRange();\n\n if (range.getBoundingClientRect) {\n rect = range.getBoundingClientRect();\n }\n // Fall back to inserting a temporary element\n if (rect.x === 0 && rect.y === 0) {\n let span = document.createElement('span');\n\n if (span.getBoundingClientRect) {\n // Ensure span has dimensions and position by\n // adding a zero-width space character\n span.appendChild( document.createTextNode('\\u200b') );\n range.insertNode(span);\n rect = span.getBoundingClientRect();\n\n let spanParent = span.parentNode;\n\n spanParent.removeChild(span);\n\n // Glue any broken text nodes back together\n spanParent.normalize();\n }\n }\n\n return rect;\n }\n\n /**\n * Returns selected text as String\n * @returns {string}\n */\n static get text() {\n return window.getSelection ? window.getSelection().toString() : '';\n };\n\n /**\n * Save Selection's range\n */\n save() {\n this.savedSelectionRange = Selection.range;\n }\n\n /**\n * Restore saved Selection's range\n */\n restore() {\n if (!this.savedSelectionRange) {\n return;\n }\n\n const sel = window.getSelection();\n\n sel.removeAllRanges();\n sel.addRange(this.savedSelectionRange);\n }\n\n /**\n * Clears saved selection\n */\n clearSaved() {\n this.savedSelectionRange = null;\n }\n\n /**\n * Looks ahead to find passed tag from current selection\n *\n * @param {String} tagName - tag to found\n * @param {String} [className] - tag's class name\n * @param {Number} [searchDepth] - count of tags that can be included. For better performance.\n * @return {HTMLElement|null}\n */\n findParentTag(tagName, className, searchDepth = 10) {\n let selection = window.getSelection(),\n parentTag = null;\n\n /**\n * If selection is missing or no anchorNode or focusNode were found then return null\n */\n if (!selection || !selection.anchorNode || !selection.focusNode) {\n return null;\n }\n\n /**\n * Define Nodes for start and end of selection\n */\n let boundNodes = [\n /** the Node in which the selection begins */\n selection.anchorNode,\n /** the Node in which the selection ends */\n selection.focusNode\n ];\n\n /**\n * For each selection parent Nodes we try to find target tag [with target class name]\n * It would be saved in parentTag variable\n */\n boundNodes.forEach(parent => {\n /** Reset tags limit */\n let searchDepthIterable = searchDepth;\n\n while (searchDepthIterable > 0 && parent.parentNode) {\n /**\n * Check tag's name\n */\n if (parent.tagName === tagName) {\n /**\n * Optional additional check for class-name matching\n */\n if (className && parent.classList && !parent.classList.contains(className)) {\n continue;\n }\n\n /**\n * If we have found required tag with class then save the result and go out from cycle\n */\n parentTag = parent;\n break;\n }\n\n /**\n * Target tag was not found. Go up to the parent and check it\n */\n parent = parent.parentNode;\n searchDepthIterable--;\n }\n });\n\n /**\n * Return found tag or null\n */\n return parentTag;\n }\n\n /**\n * Expands selection range to the passed parent node\n *\n * @param {HTMLElement} node\n */\n expandToTag(node) {\n let selection = window.getSelection();\n\n selection.removeAllRanges();\n let range = document.createRange();\n\n range.selectNodeContents(node);\n selection.addRange(range);\n }\n}\n","/**\n * Codex Editor Util\n */\nexport default class Util {\n /**\n * Custom logger\n *\n * @param {string} msg - message\n * @param {string} type - logging type 'log'|'warn'|'error'|'info'\n * @param {*} args - argument to log with a message\n */\n static log(msg, type, args) {\n type = type || 'log';\n\n if (!args) {\n args = msg || 'undefined';\n msg = '[codex-editor]: %o';\n } else {\n msg = '[codex-editor]: ' + msg;\n }\n\n try{\n if ( 'console' in window && window.console[ type ] ) {\n if ( args ) window.console[ type ]( msg, args );\n else window.console[ type ]( msg );\n }\n } catch(e) {\n // do nothing\n }\n }\n\n /**\n * Returns basic keycodes as constants\n * @return {{}}\n */\n static get keyCodes() {\n return {\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 };\n }\n\n /**\n * @typedef {Object} ChainData\n * @property {Object} data - data that will be passed to the success or fallback\n * @property {Function} function - function's that must be called asynchronically\n */\n\n /**\n * Fires a promise sequence asyncronically\n *\n * @param {Object[]} chains - list or ChainData's\n * @param {Function} success - success callback\n * @param {Function} fallback - callback that fires in case of errors\n *\n * @return {Promise}\n */\n static sequence(chains, success = () => {}, fallback = () => {}) {\n return new Promise(function (resolve) {\n /**\n * pluck each element from queue\n * First, send resolved Promise as previous value\n * Each plugins \"prepare\" method returns a Promise, that's why\n * reduce current element will not be able to continue while can't get\n * a resolved Promise\n */\n chains.reduce(function (previousValue, currentValue, iteration) {\n return previousValue\n .then(() => waitNextBlock(currentValue, success, fallback))\n .then(() => {\n // finished\n if (iteration === chains.length - 1) {\n resolve();\n }\n });\n }, Promise.resolve());\n });\n\n /**\n * Decorator\n *\n * @param {ChainData} chainData\n *\n * @param {Function} successCallback\n * @param {Function} fallbackCallback\n *\n * @return {Promise}\n */\n function waitNextBlock(chainData, successCallback, fallbackCallback) {\n return new Promise(function (resolve) {\n chainData.function()\n .then(() => {\n successCallback(chainData.data || {});\n })\n .then(resolve)\n .catch(function () {\n fallbackCallback(chainData.data || {});\n\n // anyway, go ahead even it falls\n resolve();\n });\n });\n }\n }\n\n /**\n * Make array from array-like collection\n *\n * @param {*} collection\n *\n * @return {Array}\n */\n static array(collection) {\n return Array.prototype.slice.call(collection);\n }\n\n /**\n * Checks if object is empty\n *\n * @param {Object} object\n * @return {boolean}\n */\n static isEmpty(object) {\n return Object.keys(object).length === 0 && object.constructor === Object;\n }\n\n /**\n * Check if passed object is a Promise\n * @param {*} object - object to check\n * @return {Boolean}\n */\n static isPromise(object) {\n return Promise.resolve(object) === object;\n }\n\n /**\n * Check if passed element is contenteditable\n * @param element\n * @return {boolean}\n */\n static isContentEditable(element) {\n return element.contentEditable === 'true';\n }\n\n /**\n * Delays method execution\n *\n * @param method\n * @param timeout\n */\n static delay(method, timeout) {\n return function () {\n let context = this,\n args = arguments;\n\n window.setTimeout(() => method.apply(context, args), timeout);\n };\n }\n};\n","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \":root {\\n /**\\n * Selection color\\n */\\n --selectionColor: rgba(61,166,239,0.63);\\n\\n /**\\n * Toolbar buttons\\n */\\n --bg-light: #eff2f5;\\n\\n /**\\n * All gray texts: placeholders, settings\\n */\\n --grayText: #707684;\\n\\n /** Blue icons */\\n --color-active-icon: #388AE5;\\n\\n /**\\n * Block content width\\n */\\n --content-width: 650px;\\n\\n /**\\n * Toolbar buttons height and width\\n */\\n --toolbar-buttons-size: 34px;\\n\\n /**\\n * Toolbar Plus Button and Toolbox buttons height and width\\n */\\n --toolbox-buttons-size: 20px;\\n\\n /**\\n * Confirm deletion bg\\n */\\n --color-confirm: #E24A4A;\\n}\\n/**\\n* Editor wrapper\\n*/\\n.codex-editor {\\n position: relative;\\n box-sizing: border-box;\\n}\\n.codex-editor .hide {\\n display: none;\\n }\\n.codex-editor__redactor {\\n padding-bottom: 300px;\\n }\\n.codex-editor svg {\\n fill: currentColor;\\n vertical-align: middle;\\n max-height: 100%;\\n }\\n/**\\n * Set color for native selection\\n */\\n::-moz-selection{\\n background-color: rgba(61,166,239,0.63);\\n background-color: var(--selectionColor);\\n}\\n::selection{\\n background-color: rgba(61,166,239,0.63);\\n background-color: var(--selectionColor);\\n}\\n/**\\n * Add placeholder to content editable elements with data attribute\\n * data-placeholder=\\\"Hello world!\\\"\\n */\\n[contentEditable=true][data-placeholder]:empty:not(:focus):before{\\n content: attr(data-placeholder);\\n color: #707684;\\n color: var(--grayText);\\n}\\n.ce-toolbar {\\n position: absolute;\\n left: 0;\\n right: 0;\\n top: 0;\\n /*opacity: 0;*/\\n /*visibility: hidden;*/\\n transition: opacity 100ms ease;\\n will-change: opacity, transform;\\n display: none;\\n}\\n.ce-toolbar--opened {\\n display: block;\\n /*opacity: 1;*/\\n /*visibility: visible;*/\\n }\\n.ce-toolbar__content {\\n max-width: 650px;\\n max-width: var(--content-width);\\n margin: 0 auto;\\n position: relative;\\n }\\n.ce-toolbar__plus {\\n color: #707684;\\n color: var(--grayText);\\n cursor: pointer;\\n display: inline-block;\\n width: 20px;\\n width: var(--toolbox-buttons-size);\\n height: 20px;\\n height: var(--toolbox-buttons-size);\\n line-height: 20px;\\n line-height: var(--toolbox-buttons-size)\\n }\\n.ce-toolbar__plus:not(:last-of-type){\\n margin-right: 3px;\\n }\\n.ce-toolbar__plus:hover {\\n color: #388AE5;\\n color: var(--color-active-icon);\\n }\\n.ce-toolbar__plus {\\n\\n position: absolute;\\n top: -1px;\\n left: calc(calc(20px + 10px) * -1);\\n left: calc(calc(var(--toolbox-buttons-size) + 10px) * -1);\\n }\\n.ce-toolbar__plus--hidden {\\n display: none;\\n }\\n/**\\n * Block actions Zone\\n * -------------------------\\n */\\n.ce-toolbar__actions {\\n position: absolute;\\n right: 0;\\n top: 0;\\n padding-right: 16px;\\n }\\n.ce-toolbar__actions-buttons {\\n text-align: right;\\n }\\n.ce-toolbar__settings-btn {\\n display: inline-block;\\n width: 24px;\\n height: 24px;\\n color: #707684;\\n color: var(--grayText);\\n cursor: pointer;\\n }\\n.ce-toolbox {\\n position: absolute;\\n visibility: hidden;\\n transition: opacity 100ms ease;\\n will-change: opacity;\\n}\\n.ce-toolbox--opened {\\n opacity: 1;\\n visibility: visible;\\n }\\n.ce-toolbox__button {\\n color: #707684;\\n color: var(--grayText);\\n cursor: pointer;\\n display: inline-block;\\n width: 20px;\\n width: var(--toolbox-buttons-size);\\n height: 20px;\\n height: var(--toolbox-buttons-size);\\n line-height: 20px;\\n line-height: var(--toolbox-buttons-size);\\n }\\n.ce-toolbox__button:not(:last-of-type){\\n margin-right: 3px;\\n }\\n.ce-toolbox__button:hover {\\n color: #388AE5;\\n color: var(--color-active-icon);\\n }\\n.ce-inline-toolbar {\\n position: absolute;\\n background-color: #FFFFFF;\\n box-shadow: 0 8px 23px -6px rgba(21,40,54,0.31), 22px -14px 34px -18px rgba(33,48,73,0.26);\\n border-radius: 4px;\\n z-index: 2\\n}\\n.ce-inline-toolbar::before {\\n content: '';\\n width: 15px;\\n height: 15px;\\n position: absolute;\\n top: -7px;\\n left: 50%;\\n margin-left: -7px;\\n transform: rotate(-45deg);\\n background-color: #fff;\\n z-index: -1;\\n }\\n.ce-inline-toolbar {\\n padding: 6px;\\n transform: translateX(-50%);\\n display: none;\\n box-shadow: 0 6px 12px -6px rgba(131, 147, 173, 0.46),\\n 5px -12px 34px -13px rgba(97, 105, 134, 0.6),\\n 0 26px 52px 3px rgba(147, 165, 186, 0.24);\\n}\\n.ce-inline-toolbar--showed {\\n display: block;\\n }\\n.ce-inline-tool {\\n display: inline-block;\\n width: 34px;\\n height: 34px;\\n line-height: 34px;\\n text-align: center;\\n border-radius: 3px;\\n cursor: pointer;\\n border: 0;\\n outline: none;\\n background-color: transparent;\\n vertical-align: bottom;\\n color: #707684;\\n color: var(--grayText)\\n}\\n.ce-inline-tool:not(:last-of-type){\\n margin-right: 5px;\\n }\\n.ce-inline-tool:hover {\\n background-color: #eff2f5;\\n background-color: var(--bg-light);\\n }\\n.ce-inline-tool {\\n line-height: normal;\\n}\\n.ce-inline-tool--active {\\n color: #388AE5;\\n color: var(--color-active-icon);\\n }\\n.ce-inline-tool--link .icon {\\n margin-top: -2px;\\n }\\n.ce-inline-tool--link .icon--unlink {\\n display: none;\\n }\\n.ce-inline-tool--unlink .icon--link {\\n display: none;\\n }\\n.ce-inline-tool--unlink .icon--unlink {\\n display: inline-block;\\n }\\n.ce-inline-tool-input {\\n background-color: #eff2f5;\\n background-color: var(--bg-light);\\n outline: none;\\n border: 0;\\n border-radius: 3px;\\n margin: 6px 0 0;\\n font-size: 13px;\\n padding: 8px;\\n width: 100%;\\n box-sizing: border-box;\\n display: none\\n }\\n.ce-inline-tool-input::-webkit-input-placeholder {\\n color: #707684;\\n color: var(--grayText);\\n }\\n.ce-inline-tool-input:-ms-input-placeholder {\\n color: #707684;\\n color: var(--grayText);\\n }\\n.ce-inline-tool-input::placeholder {\\n color: #707684;\\n color: var(--grayText);\\n }\\n.ce-inline-tool-input--showed {\\n display: block;\\n }\\n.ce-settings {\\n position: absolute;\\n background-color: #FFFFFF;\\n box-shadow: 0 8px 23px -6px rgba(21,40,54,0.31), 22px -14px 34px -18px rgba(33,48,73,0.26);\\n border-radius: 4px;\\n z-index: 2\\n}\\n.ce-settings::before {\\n content: '';\\n width: 15px;\\n height: 15px;\\n position: absolute;\\n top: -7px;\\n left: 50%;\\n margin-left: -7px;\\n transform: rotate(-45deg);\\n background-color: #fff;\\n z-index: -1;\\n }\\n.ce-settings {\\n right: 5px;\\n top: 35px;\\n min-width: 124px\\n}\\n.ce-settings::before{\\n left: auto;\\n right: 12px;\\n }\\n.ce-settings {\\n\\n display: none;\\n}\\n.ce-settings--opened {\\n display: block;\\n }\\n.ce-settings__plugin-zone:not(:empty){\\n padding: 6px 6px 0;\\n }\\n.ce-settings__default-zone:not(:empty){\\n padding: 6px;\\n }\\n.ce-settings__button {\\n display: inline-block;\\n width: 34px;\\n height: 34px;\\n line-height: 34px;\\n text-align: center;\\n border-radius: 3px;\\n cursor: pointer;\\n border: 0;\\n outline: none;\\n background-color: transparent;\\n vertical-align: bottom;\\n color: #707684;\\n color: var(--grayText)\\n }\\n.ce-settings__button:not(:last-of-type){\\n margin-right: 5px;\\n }\\n.ce-settings__button:hover {\\n background-color: #eff2f5;\\n background-color: var(--bg-light);\\n }\\n.ce-settings__button--active {\\n color: #388AE5;\\n color: var(--color-active-icon);\\n }\\n.ce-settings__button--disabled {\\n cursor: not-allowed !important;\\n opacity: .3;\\n }\\n.ce-settings__button--selected {\\n color: #388AE5;\\n color: var(--color-active-icon);\\n }\\n.ce-settings__button--delete {\\n transition: background-color 300ms ease;\\n will-change: background-color;\\n }\\n.ce-settings__button--delete .icon {\\n transition: transform 200ms ease-out;\\n will-change: transform;\\n }\\n.ce-settings__button--confirm {\\n background-color: #E24A4A;\\n background-color: var(--color-confirm);\\n color: #fff\\n }\\n.ce-settings__button--confirm:hover {\\n background-color: rgb(213, 74, 74) !important;\\n background-color: rgb(213, 74, 74) !important;\\n }\\n.ce-settings__button--confirm .icon {\\n transform: rotate(90deg);\\n }\\n.ce-block:first-of-type {\\n margin-top: 0;\\n }\\n.ce-block--selected {\\n background-image: linear-gradient(17deg, rgba(243, 248, 255, 0.03) 63.45%, rgba(207, 214, 229, 0.27) 98%);\\n border-radius: 3px;\\n }\\n.ce-block__content {\\n max-width: 650px;\\n max-width: var(--content-width);\\n margin: 0 auto;\\n }\\n.wobble {\\n animation-name: wobble;\\n animation-duration: 400ms;\\n}\\n/**\\n * @author Nick Pettit - https://github.com/nickpettit/glide\\n */\\n@keyframes wobble {\\n from {\\n transform: translate3d(0, 0, 0);\\n }\\n\\n 15% {\\n transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -5deg);\\n }\\n\\n 30% {\\n transform: translate3d(2%, 0, 0) rotate3d(0, 0, 1, 3deg);\\n }\\n\\n 45% {\\n transform: translate3d(-3%, 0, 0) rotate3d(0, 0, 1, -3deg);\\n }\\n\\n 60% {\\n transform: translate3d(2%, 0, 0) rotate3d(0, 0, 1, 2deg);\\n }\\n\\n 75% {\\n transform: translate3d(-1%, 0, 0) rotate3d(0, 0, 1, -1deg);\\n }\\n\\n to {\\n transform: translate3d(0, 0, 0);\\n }\\n}\\n\", \"\"]);\n\n// exports\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://CodexEditor/webpack/universalModuleDefinition","webpack://CodexEditor/webpack/bootstrap","webpack://CodexEditor/./build/sprite.svg","webpack://CodexEditor/./node_modules/css-loader/lib/css-base.js","webpack://CodexEditor/./node_modules/html-janitor/src/html-janitor.js","webpack://CodexEditor/./src/codex.js","webpack://CodexEditor/./src/components/__module.ts","webpack://CodexEditor/./src/components/block-tunes/block-tune-delete.ts","webpack://CodexEditor/./src/components/block-tunes/block-tune-move-down.ts","webpack://CodexEditor/./src/components/block-tunes/block-tune-move-up.ts","webpack://CodexEditor/./src/components/block.js","webpack://CodexEditor/./src/components/dom.js","webpack://CodexEditor/./src/components/inline-tools/inline-tool-bold.ts","webpack://CodexEditor/./src/components/inline-tools/inline-tool-italic.ts","webpack://CodexEditor/./src/components/inline-tools/inline-tool-link.ts","webpack://CodexEditor/./src/components/modules sync ^\\.\\/.*$","webpack://CodexEditor/./src/components/modules/_anchors.js","webpack://CodexEditor/./src/components/modules/_callbacks.js","webpack://CodexEditor/./src/components/modules/_caret.js","webpack://CodexEditor/./src/components/modules/_content.js","webpack://CodexEditor/./src/components/modules/_destroyer.js","webpack://CodexEditor/./src/components/modules/_notifications.js","webpack://CodexEditor/./src/components/modules/_parser.js","webpack://CodexEditor/./src/components/modules/_paste.js","webpack://CodexEditor/./src/components/modules/_transport.js","webpack://CodexEditor/./src/components/modules/api-blocks.ts","webpack://CodexEditor/./src/components/modules/api-events.ts","webpack://CodexEditor/./src/components/modules/api-listener.ts","webpack://CodexEditor/./src/components/modules/api-sanitizer.ts","webpack://CodexEditor/./src/components/modules/api-saver.ts","webpack://CodexEditor/./src/components/modules/api-selection.ts","webpack://CodexEditor/./src/components/modules/api-toolbar.ts","webpack://CodexEditor/./src/components/modules/api.ts","webpack://CodexEditor/./src/components/modules/block-events.ts","webpack://CodexEditor/./src/components/modules/blockManager.js","webpack://CodexEditor/./src/components/modules/caret.js","webpack://CodexEditor/./src/components/modules/events.js","webpack://CodexEditor/./src/components/modules/listeners.js","webpack://CodexEditor/./src/components/modules/renderer.js","webpack://CodexEditor/./src/components/modules/sanitizer.js","webpack://CodexEditor/./src/components/modules/saver.js","webpack://CodexEditor/./src/components/modules/toolbar-blockSettings.js","webpack://CodexEditor/./src/components/modules/toolbar-inline.ts","webpack://CodexEditor/./src/components/modules/toolbar-toolbox.js","webpack://CodexEditor/./src/components/modules/toolbar.js","webpack://CodexEditor/./src/components/modules/toolbar/inline.js","webpack://CodexEditor/./src/components/modules/toolbar/settings.js","webpack://CodexEditor/./src/components/modules/toolbar/toolbar.js","webpack://CodexEditor/./src/components/modules/toolbar/toolbox.js","webpack://CodexEditor/./src/components/modules/tools.js","webpack://CodexEditor/./src/components/modules/ui.js","webpack://CodexEditor/./src/components/polyfills.js","webpack://CodexEditor/./src/components/selection.js","webpack://CodexEditor/./src/components/utils.js","webpack://CodexEditor/./src/styles/main.css"],"names":["modules","editorModules","map","module","CodexEditor","config","moduleInstances","Promise","resolve","then","configuration","init","start","methods","API","method","console","log","catch","error","constructModules","configureModules","forEach","Module","displayName","e","name","state","getModulesDiff","diff","moduleName","prepareDecorator","prepare","Tools","UI","BlockManager","Renderer","render","data","items","initialBlock","type","holderId","placeholder","sanitizer","p","b","a","hideToolbar","tools","toolsConfig","_","isEmpty","length","new","target","TypeError","Editor","DeleteTune","api","CSS","wrapper","button","buttonDelete","buttonConfirm","nodes","resetConfirmation","setConfirmation","$","make","appendChild","svg","listener","on","event","handleClick","needConfirmation","events","off","blocks","delete","classList","add","MoveDownTune","animation","moveDownButton","currentBlockIndex","getCurrentBlockIndex","getBlocksCount","window","setTimeout","remove","nextBlockElement","getBlockByIndex","holder","nextBlockCoords","getBoundingClientRect","scrollOffset","Math","abs","innerHeight","offsetHeight","top","scrollY","scrollTo","swap","MoveUpTune","moveUpButton","currentBlockElement","previousBlockElement","currentBlockCoords","previousBlockCoords","scrollUpOffset","scrollBy","Block","toolName","toolInstance","settings","apiMethods","tool","compose","inputIndex","tunes","makeTunes","contentNode","content","pluginsContent","methodName","params","Function","call","merge","extractedBlock","save","measuringStart","performance","now","measuringEnd","finishedExtraction","time","isValid","validate","tunesList","tune","tunesElement","document","createDocumentFragment","append","querySelector","childNodes","collection","querySelectorAll","array","inputs","min","max","contentless","emptyText","emptyMedia","hasMedia","mediaTags","join","selected","Dom","tag","tagName","includes","classNames","attributes","el","createElement","Array","isArray","attrName","createTextNode","width","height","icon","createElementNS","setAttribute","innerHTML","parent","elements","el1","el2","temp","parentNode","insertBefore","removeChild","selector","node","atLast","child","sibling","nodeType","Node","ELEMENT_NODE","nodeChild","isSingleTag","getDeepestNode","nativeInputs","nodeText","isElement","isNativeInput","value","textContent","replace","trim","treeWalker","leafs","isNodeEmpty","push","firstChild","shift","isLeaf","nextSibling","every","leaf","BoldInlineTool","commandName","buttonActive","buttonModifier","range","execCommand","selection","isActive","queryCommandState","toggle","ItalicInlineTool","LinkInlineTool","commandLink","commandUnlink","ENTER_KEY","buttonUnlink","input","inputShowed","inputOpened","inlineToolbar","toolbar","Selection","addEventListener","keyCode","enterPressed","parentAnchor","findParentTag","expandToTag","unlink","closeActions","checkState","close","toggleActions","anchorTag","openActions","hrefAttr","getAttribute","needFocus","focus","clearSavedSelection","clearSaved","restore","preventDefault","validateURL","prepareLink","insertLink","stopPropagation","stopImmediatePropagation","str","test","link","addProtocol","isInternal","isAnchor","substring","isProtocolRelative","exports","anchors","editor","codex","currentNode","settingsOpened","currentBlock","dataset","anchor","anchorChanged","newAnchor","rusToTranslit","ui","className","BLOCK_WITH_ANCHOR","keyDownOnAnchorInput","core","keys","ENTER","blur","keyUpOnAnchorInput","LEFT","DOWN","string","ru","en","i","split","toLowerCase","callbacks","globalKeydown","enterKeyPressed_","redactorKeyDown","TAB","tabKeyPressedOnRedactorsZone_","enterKeyPressedOnRedactorsZone_","ESC","escapeKeyPressedOnRedactorsZone_","defaultKeyPressedOnRedactorsZone_","globalKeyup","UP","RIGHT","arrowKeyPressed_","isBlockEmpty","opened","open","toolbox","editorAreaHightlighted","caret","enterPressedOnBlock_","NEW_BLOCK_TYPE","initialBlockPlugin","insertBlock","block","move","contentEditable","saveCurrentInputIndex","currentInputIndex","getCurrentInputIndex","workingNode","isEnterPressedOnToolbar","current","enableLineBreaks","toolClicked","shiftKey","currentSelection","getSelection","currentSelectedNode","anchorNode","caretAtTheEndOfText","position","atTheEnd","isTextNodeHasParentBetweenContenteditable","callback","enterPressedOnBlock","nodeTypes","TEXT","splitBlock","showPlusButton","islastNode","isLastNode","saveInputs","workingNodeChanged","inline","actionsOpened","clearMark","redactorClicked","detectWhenClickedOnFirstLevelBlockArea_","selectedText","getSelectionText","firstLevelBlock","indexOfLastInput","getFirstLevelBlock","setToBlock","setToNextBlock","inputIsEmpty","currentNodeType","isInitialType","hidePlusButton","markBlock","flag","rangeCount","isDomNode","body","toolbarButtonClicked","plusButtonClicked","contains","blockKeydown","blockRightOrDownArrowPressed_","BACKSPACE","backspacePressed_","blockLeftOrUpArrowPressed_","focusedNode","focusedNodeHolder","editableElementIndex","caretInLastChild","lastChild","deepestTextnode","getDeepestTextNodeFromPosition","anchorOffset","caretInFirstChild","caretAtTheBeginning","setToPreviousBlock","selectionLength","firstLevelBlocksCount","getRange","endOffset","startOffset","atStart","mergeBlocks","redactor","addInitialBlock","showSettingsButtonClicked","currentToolType","hideRemoveActions","offset","focusedNodeIndex","set","index","childs","nodeToSet","createRange","setStart","setEnd","removeAllRanges","addRange","nextInput","emptyTextElement","targetInput","previousInput","lastChildNode","lengthOfLastChildNode","pluginsRender","isFirstNode","isOffsetZero","insertNode","lastNode","DOCUMENT_FRAGMENT","getRangeAt","deleteContents","setStartAfter","collapse","stretched","highlighted","_currentNode","_currentIndex","pluginHTML","isStretched","blockContent","toolId","newBlock","composeBlock_","insertAdjacentElement","destroyer","removeNodes","notifications","destroyPlugins","destroy","destroyScripts","scripts","getElementsByTagName","id","indexOf","scriptPrefix","listeners","removeAll","plugins","queue","addToQueue","splice","createHolder","draw","errorThrown","errorMsg","notification","message","constructorSettings","cancel","confirm","inputField","confirmHandler","cancelHandler","create","okBtn","cancelBtn","okMsg","cancelMsg","send","clear","parser","insertPastedContent","blockType","text","isFirstLevelBlock","TAG","BLOCK_CLASSNAME","paste","patterns","renderOnPastePatterns","pattern","pasted","clipBoardData","clipboardData","getData","result","analize","plugin","execArray","regex","exec","match","pasteToNewBlock_","blockPasteCallback","needsToHandlePasteEvent","htmlData","plainData","paragraphs","cleanData","wrappedData","clean","wrapTextWithParagraphs","emulateUserAgentBehaviour","insertPastedParagraphs","editableParent","getEditableParent","paragraph","newNode","childElementCount","cloneNode","transport","currentRequest","arguments","fileSelected","clearInput","files","formData","FormData","multiple","ajax","url","beforeSend","success","progress","selectAndUpload","args","accept","click","abort","BlocksAPI","fromIndex","toIndex","Toolbar","blockIndex","removeBlock","insert","Caret","navigatePrevious","EventsAPI","eventName","Events","emit","ListenerAPI","element","eventType","handler","useCapture","Listeners","SanitizerAPI","taintString","Sanitizer","SaverAPI","Saver","SelectionAPI","ToolbarAPI","saver","BlockEvents","beforeKeydownProcessing","keyCodes","backspace","enter","arrowRightAndDown","arrowLeftAndUp","defaultHandler","clearHighlightings","InlineToolbar","handleShowingEvent","apiSettings","IS_ENABLED_LINE_BREAKS","newCurrent","isInitial","plusButton","show","BM","isFirstBlock","canMergeBlocks","isAtStart","targetBlock","blockToMerge","mergeable","createShadow","restoreCaret","normalize","navigateNext","_blocks","Blocks","Proxy","get","construct","bindEvents","keydown","mouseUp","keyup","composeBlock","blockToMergeIndex","blockToMergeInfo","mergeWith","extractedFragment","extractFragmentFromCaretPosition","blockInserted","closest","childNode","parentFirstLevelBlock","Error","needAddInitialBlock","dropPointer","isLastBlock","workingArea","first","second","secondBlock","deleteCount","previousBlock","nextBlock","isNaN","children","instance","Number","atEnd","delay","lastBlock","insertAtEnd","selectRange","blockElem","cloneRange","selectNodeContents","endContainer","extractContents","from","direction","siblings","force","isAtEnd","shadowCaret","sel","newRange","selectNode","isCollapsed","firstNode","firstLetterPosition","search","leftSiblings","getHigherLevelSiblings","nothingAtLeft","nothingAtRight","rightTrimmedText","subscribers","reduce","previousData","currentHandler","newData","allListeners","assignedEventData","alreadyExist","findOne","existingListeners","findAll","removeEventListener","listenersOnElement","listenersWithType","listenersWithHandler","foundListeners","found","foundByElements","findByElement","filter","chainData","function","sequence","item","available","defaultConfig","_sanitizerInstance","sanitizerConfig","sanitizerInstance","require","customConfig","library","tags","href","rel","newInstance","output","blocksData","all","allExtractedData","makeOutput","outputData","totalTime","groupCollapsed","extraction","groupEnd","Date","version","VERSION","BlockSettings","toolSettings","defaultSettings","renderSettings","renderTunes","wrapperOpened","addToolSettings","addDefaultSettings","closed","inlineToolbarShowed","buttonsWrapper","actionsWrapper","buttons","actions","toolbarVerticalMargin","addTools","allowedToShow","checkToolsState","selectionRect","rect","wrapperOffset","newCoords","x","left","y","floor","style","tagsConflictsWithSelection","getBlock","toolConfig","IS_ENABLED_INLINE_TOOLBAR","addTool","renderActions","surround","toolsInstances","Tool","Toolbox","toolsAvailable","IS_DISPLAYED_IN_TOOLBOX","TOOLBAR_ICON_CLASS","toolboxButton","title","buttonClicked","toolButton","toolClasses","IS_IRREPLACEBLE_TOOL","toolboxOpened","blockActionsButtons","settingsToggler","settingsIcon","forceClose","defaultToolbarHeight","defaultOffset","newYCoordinate","offsetTop","transform","toolbarOpened","settingsTogglerClicked","hide","plusButtonHidden","buttonsOpened","wrappersOffset","storedSelection","showInlineToolbar","showButtons","getWrappersOffset","coords","getSelectionCoords","newCoordinateX","newCoordinateY","closeButtons","closeAction","createLinkAction","defaultToolAction","hightlight","getOffset","_x","_y","offsetLeft","clientLeft","clientTop","offsetParent","boundingLeft","boundingTop","getClientRects","toString","showActions","action","inlineToolbarAnchorInputKeydown_","editable","restoreSelection","setAnchor","clearRange","isLinkActive","saveSelection","inputForLink","dataType","containerEl","preSelectionRange","startContainer","end","savedSel","charIndex","nodeStack","foundStart","stop","nextCharIndex","pop","setButtonHighlighted","removeButtonsHighLight","setting","toolType","settingsBlock","pluginSettings","blockSettings","makeRemoveBlockButton","removeBlockWrapper","settingButton","actionWrapper","confirmAction","cancelAction","removeButtonClicked","confirmRemovingRequest","cancelRemovingRequest","showRemoveActions","showSettingsButton","toolbarButtons","openedOnBlock","currentTool","Object","barButtons","nextToolIndex","toolToSelect","visibleTool","displayInToolbox","UNREPLACEBLE_TOOLS","newBlockContent","appendCallback","blockData","switchBlock","toolsUnavailable","values","IS_INLINE","inlineToolRequiredMethods","notImplementedMethods","hasOwnProperty","reject","sequenceData","getListOfPrepareFunctions","fallback","toolPreparationList","toolClass","appendSVGSprite","loadStyles","getElementById","editorWrapper","editorZone","styles","head","documentKeydown","documentClicked","defaultBehaviour","keyDownOnEditor","hasPointerToBlock","isAtEditor","highlightCurrentNode","clickedOnInlineToolbarButton","clickedInsideofEditor","clickedNode","setCurrentBlockByChildNode","setToTheLastBlock","isInitialBlock","isEmptyBlock","spriteHolder","sprite","Element","prototype","matches","msMatchesSelector","webkitMatchesSelector","s","documentElement","parentElement","savedSelectionRange","searchDepth","parentTag","focusNode","boundNodes","searchDepthIterable","selectedNode","TEXT_NODE","boundingWidth","boundingHeight","span","spanParent","Util","msg","chains","previousValue","currentValue","iteration","waitNextBlock","successCallback","fallbackCallback","slice","object","constructor","timeout","context","apply","SHIFT","CTRL","ALT","SPACE","DELETE","META"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;AClFA,whI;;;;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,mCAAmC,gBAAgB;AACnD,IAAI;AACJ;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAgB,iBAAiB;AACjC;AACA;AACA;AACA;AACA,YAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oDAAoD,cAAc;;AAElE;AACA;;;;;;;;;;;;AC3EA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA,GAAG,QAIH;AACA,CAAC;;AAED;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB;AACA;;AAEA;AACA;;AAEA;AACA,wBAAwB,iCAAiC,EAAE;AAC3D,6BAA6B,uEAAuE,EAAE;;AAEtG;AACA;AACA;;AA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AL,CAAYiC,IAAZ,CAAiBC,KAAjB,GAAyB,CAAEC,YAAF,CAAzB;AACD,OAHD,MAGO;AACL,YAAI,CAAC,KAAKnC,MAAL,CAAYiC,IAAZ,CAAiBC,KAAlB,IAA2B,KAAKlC,MAAL,CAAYiC,IAAZ,CAAiBC,KAAjB,CAAuBc,MAAvB,KAAkC,CAAjE,EAAoE;AAClE,eAAKhD,MAAL,CAAYiC,IAAZ,CAAiBC,KAAjB,GAAyB,CAAEC,YAAF,CAAzB;AACD;AACF;;AAED;;;AAGA,UAAI,CAACnC,OAAOmC,YAAZ,EAA0B;AACxB,aAAK,KAAKnC,MAAL,CAAYmC,YAAjB,IAAiC,KAAKnC,MAAL,CAAY4C,KAA7C;AAAoD;AAApD;AACD,OAFD,MAEO;AACL,aAAK5C,MAAL,CAAYmC,YAAZ,GAA2BnC,OAAOmC,YAAlC;AACD;AACF;;AAED;;;;;wBAIoB;AAClB,aAAO,KAAKnC,MAAZ;AACD;;;;;;;kBAlHkBD,W;AA6MpB;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;AClZA;;;;;;;;;IASqBmB,M;AACjB;;;;AAIA,0BAAwB;AAAA,YAAVlB,MAAU,QAAVA,MAAU;;AAAA;;AACpB,YAAIiD,IAAIC,MAAJ,KAAehC,MAAnB,EAA2B;AACvB,kBAAM,IAAIiC,SAAJ,CAAc,yDAAd,CAAN;AACH;AACD,aAAKnD,MAAL,GAAcA,MAAd;AACH;AACD;;;;;;;;0BAIUoD,M,EAAQ;AACd,iBAAKA,MAAL,GAAcA,MAAd;AACH;;;;;;;kBAjBgBlC,M;;;;;;;;;;;;;;;;;;;;;;;ICTAmC,U;AACjB;;;;;AAKA,8BAAqB;AAAA;;AAAA,YAAPC,GAAO,QAAPA,GAAO;;AAAA;;AACjB;;;;AAIA,aAAKC,GAAL,GAAW;AACPC,qBAAS,KADF;AAEPC,oBAAQ,qBAFD;AAGPC,0BAAc,6BAHP;AAIPC,2BAAe;AAJR,SAAX;AAMA;;;AAGA,aAAKC,KAAL,GAAa;AACTH,oBAAQ;AADC,SAAb;AAGA,aAAKH,GAAL,GAAWA,GAAX;AACA,aAAKO,iBAAL,GAAyB,YAAM;AAC3B,kBAAKC,eAAL,CAAqB,KAArB;AACH,SAFD;AAGH;AACD;;;;;;;;iCAIS;AAAA;;AACL,iBAAKF,KAAL,CAAWH,MAAX,GAAoBM,EAAEC,IAAF,CAAO,KAAP,EAAc,CAAC,KAAKT,GAAL,CAASE,MAAV,EAAkB,KAAKF,GAAL,CAASG,YAA3B,CAAd,EAAwD,EAAxD,CAApB;AACA,iBAAKE,KAAL,CAAWH,MAAX,CAAkBQ,WAAlB,CAA8BF,EAAEG,GAAF,CAAM,OAAN,EAAe,EAAf,EAAmB,EAAnB,CAA9B;AACA,iBAAKZ,GAAL,CAASa,QAAT,CAAkBC,EAAlB,CAAqB,KAAKR,KAAL,CAAWH,MAAhC,EAAwC,OAAxC,EAAiD,UAACY,KAAD;AAAA,uBAAW,OAAKC,WAAL,CAAiBD,KAAjB,CAAX;AAAA,aAAjD,EAAqF,KAArF;AACA,mBAAO,KAAKT,KAAL,CAAWH,MAAlB;AACH;AACD;;;;;;;oCAIYY,K,EAAO;AACf;;;;AAIA,gBAAI,CAAC,KAAKE,gBAAV,EAA4B;AACxB,qBAAKT,eAAL,CAAqB,IAArB;AACA;;;;;AAKA,qBAAKR,GAAL,CAASkB,MAAT,CAAgBJ,EAAhB,CAAmB,uBAAnB,EAA4C,KAAKP,iBAAjD;AACH,aARD,MASK;AACD;;;AAGA,qBAAKP,GAAL,CAASkB,MAAT,CAAgBC,GAAhB,CAAoB,uBAApB,EAA6C,KAAKZ,iBAAlD;AACA,qBAAKP,GAAL,CAASoB,MAAT,CAAgBC,MAAhB;AACH;AACJ;AACD;;;;;;wCAGgBrD,K,EAAO;AACnB,iBAAKiD,gBAAL,GAAwBjD,KAAxB;AACA,iBAAKsC,KAAL,CAAWH,MAAX,CAAkBmB,SAAlB,CAA4BC,GAA5B,CAAgC,KAAKtB,GAAL,CAASI,aAAzC;AACH;;;;;;;kBAtEgBN,U;;;;;;;;;;;;;;;;;;;;;;;;ICAAyB,Y;AACjB;;;;;AAKA,gCAAqB;AAAA,YAAPxB,GAAO,QAAPA,GAAO;;AAAA;;AACjB;;;;AAIA,aAAKC,GAAL,GAAW;AACPE,oBAAQ,qBADD;AAEPD,qBAAS,mBAFF;AAGPuB,uBAAW;AAHJ,SAAX;AAKA,aAAKzB,GAAL,GAAWA,GAAX;AACH;AACD;;;;;;;iCAGS;AAAA;;AACL,gBAAM0B,iBAAiBjB,EAAEC,IAAF,CAAO,KAAP,EAAc,CAAC,KAAKT,GAAL,CAASE,MAAV,EAAkB,KAAKF,GAAL,CAASC,OAA3B,CAAd,EAAmD,EAAnD,CAAvB;AACAwB,2BAAef,WAAf,CAA2BF,EAAEG,GAAF,CAAM,YAAN,EAAoB,EAApB,EAAwB,EAAxB,CAA3B;AACA,iBAAKZ,GAAL,CAASa,QAAT,CAAkBC,EAAlB,CAAqBY,cAArB,EAAqC,OAArC,EAA8C,UAACX,KAAD;AAAA,uBAAW,MAAKC,WAAL,CAAiBD,KAAjB,EAAwBW,cAAxB,CAAX;AAAA,aAA9C,EAAkG,KAAlG;AACA,mBAAOA,cAAP;AACH;AACD;;;;;;;;oCAKYX,K,EAAOZ,M,EAAQ;AAAA;;AACvB,gBAAMwB,oBAAoB,KAAK3B,GAAL,CAASoB,MAAT,CAAgBQ,oBAAhB,EAA1B;AACA;AACA,gBAAID,sBAAsB,KAAK3B,GAAL,CAASoB,MAAT,CAAgBS,cAAhB,KAAmC,CAA7D,EAAgE;AAC5D1B,uBAAOmB,SAAP,CAAiBC,GAAjB,CAAqB,KAAKtB,GAAL,CAASwB,SAA9B;AACAK,uBAAOC,UAAP,CAAkB,YAAM;AACpB5B,2BAAOmB,SAAP,CAAiBU,MAAjB,CAAwB,OAAK/B,GAAL,CAASwB,SAAjC;AACH,iBAFD,EAEG,GAFH;AAGA;AACH;AACD,gBAAMQ,mBAAmB,KAAKjC,GAAL,CAASoB,MAAT,CAAgBc,eAAhB,CAAgCP,oBAAoB,CAApD,EAAuDQ,MAAhF;AAAA,gBAAwFC,kBAAkBH,iBAAiBI,qBAAjB,EAA1G;AACA,gBAAIC,eAAeC,KAAKC,GAAL,CAASV,OAAOW,WAAP,GAAqBR,iBAAiBS,YAA/C,CAAnB;AACA;;;;AAIA,gBAAIN,gBAAgBO,GAAhB,GAAsBb,OAAOW,WAAjC,EAA8C;AAC1CH,+BAAeR,OAAOc,OAAP,GAAiBX,iBAAiBS,YAAjD;AACH;AACDZ,mBAAOe,QAAP,CAAgB,CAAhB,EAAmBP,YAAnB;AACA;AACA,iBAAKtC,GAAL,CAASoB,MAAT,CAAgB0B,IAAhB,CAAqBnB,iBAArB,EAAwCA,oBAAoB,CAA5D;AACH;;;;;;;kBAtDgBH,Y;;;;;;;;;;;;;;;;;;;;;;;;ICAAuB,U;AACjB;;;;;AAKA,8BAAqB;AAAA,YAAP/C,GAAO,QAAPA,GAAO;;AAAA;;AACjB;;;;AAIA,aAAKC,GAAL,GAAW;AACPE,oBAAQ,qBADD;AAEPD,qBAAS,iBAFF;AAGPuB,uBAAW;AAHJ,SAAX;AAKA,aAAKzB,GAAL,GAAWA,GAAX;AACH;AACD;;;;;;;;iCAIS;AAAA;;AACL,gBAAMgD,eAAevC,EAAEC,IAAF,CAAO,KAAP,EAAc,CAAC,KAAKT,GAAL,CAASE,MAAV,EAAkB,KAAKF,GAAL,CAASC,OAA3B,CAAd,EAAmD,EAAnD,CAArB;AACA8C,yBAAarC,WAAb,CAAyBF,EAAEG,GAAF,CAAM,UAAN,EAAkB,EAAlB,EAAsB,EAAtB,CAAzB;AACA,iBAAKZ,GAAL,CAASa,QAAT,CAAkBC,EAAlB,CAAqBkC,YAArB,EAAmC,OAAnC,EAA4C,UAACjC,KAAD;AAAA,uBAAW,MAAKC,WAAL,CAAiBD,KAAjB,EAAwBiC,YAAxB,CAAX;AAAA,aAA5C,EAA8F,KAA9F;AACA,mBAAOA,YAAP;AACH;AACD;;;;;;;;oCAKYjC,K,EAAOZ,M,EAAQ;AAAA;;AACvB,gBAAMwB,oBAAoB,KAAK3B,GAAL,CAASoB,MAAT,CAAgBQ,oBAAhB,EAA1B;AACA,gBAAID,sBAAsB,CAA1B,EAA6B;AACzBxB,uBAAOmB,SAAP,CAAiBC,GAAjB,CAAqB,KAAKtB,GAAL,CAASwB,SAA9B;AACAK,uBAAOC,UAAP,CAAkB,YAAM;AACpB5B,2BAAOmB,SAAP,CAAiBU,MAAjB,CAAwB,OAAK/B,GAAL,CAASwB,SAAjC;AACH,iBAFD,EAEG,GAFH;AAGA;AACH;AACD,gBAAMwB,sBAAsB,KAAKjD,GAAL,CAASoB,MAAT,CAAgBc,eAAhB,CAAgCP,iBAAhC,EAAmDQ,MAA/E;AAAA,gBAAuFe,uBAAuB,KAAKlD,GAAL,CAASoB,MAAT,CAAgBc,eAAhB,CAAgCP,oBAAoB,CAApD,EAAuDQ,MAArK;AACA;;;;;;;;AAQA,gBAAMgB,qBAAqBF,oBAAoBZ,qBAApB,EAA3B;AAAA,gBAAwEe,sBAAsBF,qBAAqBb,qBAArB,EAA9F;AACA,gBAAIgB,uBAAJ;AACA,gBAAID,oBAAoBT,GAApB,GAA0B,CAA9B,EAAiC;AAC7BU,iCAAiBd,KAAKC,GAAL,CAASW,mBAAmBR,GAA5B,IAAmCJ,KAAKC,GAAL,CAASY,oBAAoBT,GAA7B,CAApD;AACH,aAFD,MAGK;AACDU,iCAAiBvB,OAAOW,WAAP,GAAqBF,KAAKC,GAAL,CAASW,mBAAmBR,GAA5B,CAArB,GAAwDJ,KAAKC,GAAL,CAASY,oBAAoBT,GAA7B,CAAzE;AACH;AACDb,mBAAOwB,QAAP,CAAgB,CAAhB,EAAmB,CAAC,CAAD,GAAKD,cAAxB;AACA;AACA,iBAAKrD,GAAL,CAASoB,MAAT,CAAgB0B,IAAhB,CAAqBnB,iBAArB,EAAwCA,oBAAoB,CAA5D;AACH;;;;;;;kBA9DgBoB,U;;;;;;;;;;;;;;;;;;;;qjBCArB;;;;;;;;;AASA;;;AACA;;;;AACA;;;;AACA;;;;;;;;AAEA;;;;;;;;IAQqBQ,K;AACnB;;;;;;;AAOA,iBAAYC,QAAZ,EAAsBC,YAAtB,EAAoCC,QAApC,EAA8CC,UAA9C,EAA0D;AAAA;;AACxD,SAAK5F,IAAL,GAAYyF,QAAZ;AACA,SAAKI,IAAL,GAAYH,YAAZ;AACA,SAAKC,QAAL,GAAgBA,QAAhB;AACA,SAAK1D,GAAL,GAAW2D,UAAX;AACA,SAAKxB,MAAL,GAAc,KAAK0B,OAAL,EAAd;AACA,SAAKC,UAAL,GAAkB,CAAlB;;AAEA;;;AAGA,SAAKC,KAAL,GAAa,KAAKC,SAAL,EAAb;AACD;;AAED;;;;;;;;;;AAYA;;;;8BAIU;AACR,UAAI9D,UAAUO,EAAEC,IAAF,CAAO,KAAP,EAAc6C,MAAMtD,GAAN,CAAUC,OAAxB,CAAd;AAAA,UACE+D,cAAcxD,EAAEC,IAAF,CAAO,KAAP,EAAc6C,MAAMtD,GAAN,CAAUiE,OAAxB,CADhB;AAAA,UAEEC,iBAAkB,KAAKP,IAAL,CAAUlF,MAAV,EAFpB;;AAIAuF,kBAAYtD,WAAZ,CAAwBwD,cAAxB;AACAjE,cAAQS,WAAR,CAAoBsD,WAApB;AACA,aAAO/D,OAAP;AACD;;AAED;;;;;;;;;;;yBAQKkE,U,EAAYC,M,EAAQ;AACvB;;;AAGA,UAAI,KAAKT,IAAL,CAAUQ,UAAV,KAAyB,KAAKR,IAAL,CAAUQ,UAAV,aAAiCE,QAA9D,EAAwE;AACtE,aAAKV,IAAL,CAAUQ,UAAV,EAAsBG,IAAtB,CAA2B,KAAKX,IAAhC,EAAsCS,MAAtC;AACD;AACF;;AAED;;;;;;;;;AAmDA;;;;8BAIU1F,I,EAAM;AAAA;;AACd,aAAO/B,QAAQC,OAAR,GACJC,IADI,CACC,YAAM;AACV,cAAK8G,IAAL,CAAUY,KAAV,CAAgB7F,IAAhB;AACD,OAHI,CAAP;AAID;AACD;;;;;;;;2BAKO;AAAA;;AACL,UAAI8F,iBAAiB,KAAKb,IAAL,CAAUc,IAAV,CAAe,KAAKP,cAApB,CAArB;;AAEA;AACA,UAAIQ,iBAAiB7C,OAAO8C,WAAP,CAAmBC,GAAnB,EAArB;AAAA,UACEC,qBADF;;AAGA,aAAOlI,QAAQC,OAAR,CAAgB4H,cAAhB,EACJ3H,IADI,CACC,UAACiI,kBAAD,EAAwB;AAC5B;AACAD,uBAAehD,OAAO8C,WAAP,CAAmBC,GAAnB,EAAf;;AAEA,eAAO;AACLjB,gBAAM,OAAK7F,IADN;AAELY,gBAAMoG,kBAFD;AAGLC,gBAAOF,eAAeH;AAHjB,SAAP;AAKD,OAVI,EAWJpH,KAXI,CAWE,UAAUC,KAAV,EAAiB;AACtBgC,UAAElC,GAAF,0BAA6B,KAAKsG,IAAL,CAAU7F,IAAvC,gCAAsEP,KAAtE,EAA+E,KAA/E,EAAsF,KAAtF;AACD,OAbI,CAAP;AAcD;;AAED;;;;;;;;;;;;iCASamB,I,EAAM;AACjB,UAAIsG,UAAU,IAAd;;AAEA,UAAI,KAAKrB,IAAL,CAAUsB,QAAV,YAA8BZ,QAAlC,EAA4C;AAC1CW,kBAAU,KAAKrB,IAAL,CAAUsB,QAAV,CAAmBvG,IAAnB,CAAV;AACD;;AAED,UAAI,CAACsG,OAAL,EAAc;AACZ,eAAO,KAAP;AACD;;AAED,aAAOtG,IAAP;AACD;;AAED;;;;;;;;gCAKY;AAAA;;AACV,UAAIwG,YAAY,CAACpC,yBAAD,EAAahD,yBAAb,EAAyByB,2BAAzB,CAAhB;;AAEA;AACA,aAAO2D,UAAU5I,GAAV,CAAe,UAAC6I,IAAD,EAAU;AAC9B,eAAO,IAAIA,IAAJ,CAAS;AACdpF,eAAK,OAAKA,GADI;AAEd0D,oBAAU,OAAKA;AAFD,SAAT,CAAP;AAID,OALM,CAAP;AAMD;;AAED;;;;;;;kCAIc;AACZ,UAAI2B,eAAeC,SAASC,sBAAT,EAAnB;;AAEA,WAAKxB,KAAL,CAAWpG,OAAX,CAAoB,gBAAQ;AAC1B8C,UAAE+E,MAAF,CAASH,YAAT,EAAuBD,KAAK1G,MAAL,EAAvB;AACD,OAFD;;AAIA,aAAO2G,YAAP;AACD;;AAED;;;;;;;wBA3IqB;AACnB,UAAIlB,iBAAiB,KAAKhC,MAAL,CAAYsD,aAAZ,OAA8BlC,MAAMtD,GAAN,CAAUiE,OAAxC,CAArB;;AAEA,UAAIC,kBAAkBA,eAAeuB,UAAf,CAA0BhG,MAAhD,EAAwD;AACtD,eAAOyE,eAAeuB,UAAf,CAA0B,CAA1B,CAAP;AACD;;AAED,aAAO,IAAP;AACD;;AAED;;;;;;;wBAIW;AACT,aAAO,KAAKhB,IAAL,EAAP;AACD;;;wBAEY;AACX,UAAMiB,aAAa,KAAKxD,MAAL,CAAYyD,gBAAZ,CAA6B,oCAA7B,CAAnB;;AAEA,aAAOpG,EAAEqG,KAAF,CAAQF,UAAR,CAAP;AACD;;;wBAEe;AACd,UAAMG,SAAS,KAAKA,MAApB;;AAEA,WAAKhC,UAAL,GAAkBvB,KAAKwD,GAAL,CAASD,OAAOpG,MAAP,GAAgB,CAAzB,EAA4B,KAAKoE,UAAL,GAAkB,CAA9C,CAAlB;;AAEA,aAAOgC,OAAO,KAAKhC,UAAZ,CAAP;AACD;;;wBAEmB;AAClB,WAAKA,UAAL,GAAkBvB,KAAKyD,GAAL,CAAS,CAAT,EAAY,KAAKlC,UAAL,GAAkB,CAA9B,CAAlB;;AAEA,aAAO,KAAKgC,MAAL,CAAY,KAAKhC,UAAjB,CAAP;AACD;;AAED;;;;;;;;wBAKgB;AACd,aAAO,OAAO,KAAKF,IAAL,CAAUY,KAAjB,KAA2B,UAAlC;AACD;;;wBAkGa;AACZ;;;;AAIA,UAAI,KAAKZ,IAAL,CAAUqC,WAAd,EAA2B;AACzB,eAAO,KAAP;AACD;;AAED,UAAIC,YAAYzF,EAAEhB,OAAF,CAAU,KAAK0E,cAAf,CAAhB;AAAA,UACEgC,aAAa,CAAC,KAAKC,QADrB;;AAGA,aAAOF,aAAaC,UAApB;AACD;;AAED;;;;;;;wBAIe;AACb;;;;AAIA,UAAME,YAAY,CAChB,KADgB,EAEhB,QAFgB,EAGhB,OAHgB,EAIhB,OAJgB,EAKhB,QALgB,EAMhB,OANgB,EAOhB,UAPgB,EAQhB,eARgB,CAAlB;;AAWA,aAAO,CAAC,CAAC,KAAKlE,MAAL,CAAYsD,aAAZ,CAA0BY,UAAUC,IAAV,CAAe,GAAf,CAA1B,CAAT;AACD;;AAED;;;;;;;sBAIatI,K,EAAO;AAClB;;;AAGA,UAAIA,UAAU,IAAV,IAAkB,CAAC,KAAKyB,OAA5B,EAAqC;AACnC,aAAK0C,MAAL,CAAYb,SAAZ,CAAsBC,GAAtB,CAA0BgC,MAAMtD,GAAN,CAAUsG,QAApC;AACD,OAFD,MAEO;AACL,aAAKpE,MAAL,CAAYb,SAAZ,CAAsBU,MAAtB,CAA6BuB,MAAMtD,GAAN,CAAUsG,QAAvC;AACD;AACF;;;wBA7OgB;AACf,aAAO;AACLrG,iBAAS,UADJ;AAELgE,iBAAS,mBAFJ;AAGLqC,kBAAU;AAHL,OAAP;AAKD;;;;;;;kBAhCkBhD,K;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtBrB;;;IAGqBiD,G;;;;;;;;AACnB;;;;;gCAKmBC,G,EAAK;AACtB,aAAOA,IAAIC,OAAJ,IAAe,CAAC,MAAD,EAAS,MAAT,EAAiB,IAAjB,EAAuB,KAAvB,EAA8B,SAA9B,EAAyC,OAAzC,EAAkD,IAAlD,EAAwD,KAAxD,EAA+D,OAA/D,EAAwE,QAAxE,EAAkF,MAAlF,EAA0F,MAA1F,EAAkG,OAAlG,EAA2G,QAA3G,EAAqH,OAArH,EAA8H,KAA9H,EAAqIC,QAArI,CAA8IF,IAAIC,OAAlJ,CAAtB;AACD;;;;;AAGD;;;;;;;;yBAQYA,O,EAA6C;AAAA,UAApCE,UAAoC,uEAAvB,IAAuB;AAAA,UAAjBC,UAAiB,uEAAJ,EAAI;;AACvD,UAAIC,KAAKxB,SAASyB,aAAT,CAAuBL,OAAvB,CAAT;;AAEA,UAAKM,MAAMC,OAAN,CAAcL,UAAd,CAAL,EAAiC;AAAA;;AAC/B,4BAAGtF,SAAH,EAAaC,GAAb,yCAAoBqF,UAApB;AACD,OAFD,MAEO,IAAIA,UAAJ,EAAiB;AACtBE,WAAGxF,SAAH,CAAaC,GAAb,CAAiBqF,UAAjB;AACD;;AAED,WAAK,IAAIM,QAAT,IAAqBL,UAArB,EAAiC;AAC/BC,WAAGI,QAAH,IAAeL,WAAWK,QAAX,CAAf;AACD;;AAED,aAAOJ,EAAP;AACD;;AAED;;;;;;;;yBAKY5C,O,EAAS;AACnB,aAAOoB,SAAS6B,cAAT,CAAwBjD,OAAxB,CAAP;AACD;;AAED;;;;;;;;;;wBAOWnG,I,EAA+B;AAAA,UAAzBqJ,KAAyB,uEAAjB,EAAiB;AAAA,UAAbC,MAAa,uEAAJ,EAAI;;AACxC,UAAIC,OAAOhC,SAASiC,eAAT,CAAyB,4BAAzB,EAAuD,KAAvD,CAAX;;AAEAD,WAAKhG,SAAL,CAAeC,GAAf,CAAmB,MAAnB,EAA2B,WAAWxD,IAAtC;AACAuJ,WAAKE,YAAL,CAAkB,OAAlB,EAA2BJ,QAAQ,IAAnC;AACAE,WAAKE,YAAL,CAAkB,QAAlB,EAA4BH,SAAS,IAArC;AACAC,WAAKG,SAAL,qEAAiF1J,IAAjF;;AAEA,aAAOuJ,IAAP;AACD;;AAED;;;;;;;;;2BAMcI,M,EAAQC,Q,EAAU;AAC9B,UAAKX,MAAMC,OAAN,CAAcU,QAAd,CAAL,EAA+B;AAC7BA,iBAAShK,OAAT,CAAkB;AAAA,iBAAM+J,OAAO/G,WAAP,CAAmBmG,EAAnB,CAAN;AAAA,SAAlB;AACD,OAFD,MAEO;AACLY,eAAO/G,WAAP,CAAmBgH,QAAnB;AACD;AACF;;AAED;;;;;;;;yBAKYC,G,EAAKC,G,EAAK;AACpB;AACA,UAAMC,OAAOxC,SAASyB,aAAT,CAAuB,KAAvB,CAAb;AAAA,UACEW,SAASE,IAAIG,UADf;;AAGAL,aAAOM,YAAP,CAAoBF,IAApB,EAA0BF,GAA1B;;AAEA;AACAF,aAAOM,YAAP,CAAoBJ,GAApB,EAAyBC,GAAzB;;AAEA;AACAH,aAAOM,YAAP,CAAoBH,GAApB,EAAyBC,IAAzB;;AAEA;AACAJ,aAAOO,WAAP,CAAmBH,IAAnB;AACD;;AAED;;;;;;;;;;;;;2BAUqC;AAAA,UAAzBhB,EAAyB,uEAApBxB,QAAoB;AAAA,UAAV4C,QAAU;;AACnC,aAAOpB,GAAGrB,aAAH,CAAiByC,QAAjB,CAAP;AACD;;AAED;;;;;;;;;;;;8BASwC;AAAA,UAAzBpB,EAAyB,uEAApBxB,QAAoB;AAAA,UAAV4C,QAAU;;AACtC,aAAOpB,GAAGlB,gBAAH,CAAoBsC,QAApB,CAAP;AACD;;AAED;;;;;;;;;;;;;mCAUsBC,I,EAAsB;AAAA,UAAhBC,MAAgB,uEAAP,KAAO;;AAC1C;;;;;;AAMA,UAAIC,QAAQD,SAAS,WAAT,GAAuB,YAAnC;AAAA,UACEE,UAAUF,SAAS,iBAAT,GAA6B,aADzC;;AAGA,UAAID,QAAQA,KAAKI,QAAL,KAAkBC,KAAKC,YAA/B,IAA+CN,KAAKE,KAAL,CAAnD,EAAgE;AAC9D,YAAIK,YAAYP,KAAKE,KAAL,CAAhB;;AAEA;;;AAGA,YAAI7B,IAAImC,WAAJ,CAAgBD,SAAhB,CAAJ,EAAgC;AAC9B;;;;;;;;;AASA,cAAIA,UAAUJ,OAAV,CAAJ,EAAwB;AACtBI,wBAAYA,UAAUJ,OAAV,CAAZ;AACD,WAFD,MAEO,IAAII,UAAUX,UAAV,CAAqBO,OAArB,CAAJ,EAAmC;AACxCI,wBAAYA,UAAUX,UAAV,CAAqBO,OAArB,CAAZ;AACD,WAFM,MAEA;AACL,mBAAOI,UAAUX,UAAjB;AACD;AACF;;AAED,eAAO,KAAKa,cAAL,CAAoBF,SAApB,EAA+BN,MAA/B,CAAP;AACD;;AAED,aAAOD,IAAP;AACD;;AAED;;;;;;;;;8BAMiBA,I,EAAM;AACrB,aAAOA,QAAQ,QAAOA,IAAP,yCAAOA,IAAP,OAAgB,QAAxB,IAAoCA,KAAKI,QAAzC,IAAqDJ,KAAKI,QAAL,KAAkBC,KAAKC,YAAnF;AACD;;AAED;;;;;;;;kCAKqB7I,M,EAAQ;AAC3B,UAAIiJ,eAAe,CACjB,OADiB,EAEjB,UAFiB,CAAnB;;AAKA,aAAOjJ,SAASiJ,aAAalC,QAAb,CAAsB/G,OAAO8G,OAA7B,CAAT,GAAiD,KAAxD;AACD;;AAED;;;;;;;;;;;;gCASmByB,I,EAAM;AACvB,UAAIW,iBAAJ;;AAEA,UAAK,KAAKC,SAAL,CAAeZ,IAAf,KAAwB,KAAKa,aAAL,CAAmBb,IAAnB,CAA7B,EAAwD;AACtDW,mBAAWX,KAAKc,KAAhB;AACD,OAFD,MAEO;AACLH,mBAAWX,KAAKe,WAAL,CAAiBC,OAAjB,CAAyB,QAAzB,EAAmC,EAAnC,CAAX;AACD;;AAED,aAAOL,SAASM,IAAT,GAAgB1J,MAAhB,KAA2B,CAAlC;AACD;;AAED;;;;;;;;2BAKcyI,I,EAAM;AAClB,UAAI,CAACA,IAAL,EAAW;AACT,eAAO,KAAP;AACD;;AAED,aAAOA,KAAKzC,UAAL,CAAgBhG,MAAhB,KAA2B,CAAlC;AACD;;AAED;;;;;;;;;;;;4BASeyI,I,EAAM;AAAA;;AACnB,UAAIkB,aAAa,EAAjB;AAAA,UACEC,QAAQ,EADV;;AAGA,UAAI,CAACnB,IAAL,EAAW;AACT,eAAO,IAAP;AACD;;AAED,UAAI,CAACA,KAAKzC,UAAL,CAAgBhG,MAArB,EAA6B;AAC3B,eAAO,KAAK6J,WAAL,CAAiBpB,IAAjB,CAAP;AACD;;AAEDkB,iBAAWG,IAAX,CAAgBrB,KAAKsB,UAArB;;AAEA,aAAQJ,WAAW3J,MAAX,GAAoB,CAA5B,EAAgC;AAC9ByI,eAAOkB,WAAWK,KAAX,EAAP;;AAEA,YAAI,CAACvB,IAAL,EAAW;;AAEX,YAAK,KAAKwB,MAAL,CAAYxB,IAAZ,CAAL,EAAyB;AACvBmB,gBAAME,IAAN,CAAWrB,IAAX;AACD,SAFD,MAEO;AACLkB,qBAAWG,IAAX,CAAgBrB,KAAKsB,UAArB;AACD;;AAED,eAAQtB,QAAQA,KAAKyB,WAArB,EAAmC;AACjCzB,iBAAOA,KAAKyB,WAAZ;;AAEA,cAAI,CAACzB,IAAL,EAAW;;AAEXkB,qBAAWG,IAAX,CAAgBrB,IAAhB;AACD;;AAED;;;AAGA,YAAIA,QAAQ,CAAC,KAAKoB,WAAL,CAAiBpB,IAAjB,CAAb,EAAqC;AACnC,iBAAO,KAAP;AACD;AACF;;AAED,aAAOmB,MAAMO,KAAN,CAAa;AAAA,eAAQ,MAAKN,WAAL,CAAiBO,IAAjB,CAAR;AAAA,OAAb,CAAP;AACD;;;;;;;kBA7RkBtD,G;AA8RpB;;;;;;;;;;;;;;;;;;;;;;;ACjSD;;;;;;;IAOqBuD,c;AACjB,0BAAY/J,GAAZ,EAAiB;AAAA;;AACb;;;AAGA,SAAKgK,WAAL,GAAmB,MAAnB;AACA;;;AAGA,SAAK/J,GAAL,GAAW;AACPE,cAAQ,gBADD;AAEP8J,oBAAc,wBAFP;AAGPC,sBAAgB;AAHT,KAAX;AAKA;;;AAGA,SAAK5J,KAAL,GAAa;AACTH,cAAQ;AADC,KAAb;AAGA9C,YAAQC,GAAR,CAAY,2BAAZ;AACH;AACD;;;;;;;6BAGS;AACL,WAAKgD,KAAL,CAAWH,MAAX,GAAoBmF,SAASyB,aAAT,CAAuB,QAAvB,CAApB;AACA,WAAKzG,KAAL,CAAWH,MAAX,CAAkBmB,SAAlB,CAA4BC,GAA5B,CAAgC,KAAKtB,GAAL,CAASE,MAAzC,EAAiD,KAAKF,GAAL,CAASiK,cAA1D;AACA,WAAK5J,KAAL,CAAWH,MAAX,CAAkBQ,WAAlB,CAA8BF,EAAEG,GAAF,CAAM,MAAN,EAAc,EAAd,EAAkB,EAAlB,CAA9B;AACA,aAAO,KAAKN,KAAL,CAAWH,MAAlB;AACH;AACD;;;;;;;6BAISgK,K,EAAO;AACZ7E,eAAS8E,WAAT,CAAqB,KAAKJ,WAA1B;AACH;AACD;;;;;;;+BAIWK,S,EAAW;AAClB,UAAMC,WAAWhF,SAASiF,iBAAT,CAA2B,KAAKP,WAAhC,CAAjB;AACA,WAAK1J,KAAL,CAAWH,MAAX,CAAkBmB,SAAlB,CAA4BkJ,MAA5B,CAAmC,KAAKvK,GAAL,CAASgK,YAA5C,EAA0DK,QAA1D;AACA,aAAOA,QAAP;AACH;;;;;;;kBA9CgBP,c;;;;;;;;;;;;;;;;;;;;;;;;ACPrB;;;;;;;IAOqBU,gB;AACjB,4BAAYzK,GAAZ,EAAiB;AAAA;;AACb;;;AAGA,SAAKgK,WAAL,GAAmB,QAAnB;AACA;;;AAGA,SAAK/J,GAAL,GAAW;AACPE,cAAQ,gBADD;AAEP8J,oBAAc,wBAFP;AAGPC,sBAAgB;AAHT,KAAX;AAKA;;;AAGA,SAAK5J,KAAL,GAAa;AACTH,cAAQ;AADC,KAAb;AAGA9C,YAAQC,GAAR,CAAY,6BAAZ;AACH;AACD;;;;;;;6BAGS;AACL,WAAKgD,KAAL,CAAWH,MAAX,GAAoBmF,SAASyB,aAAT,CAAuB,QAAvB,CAApB;AACA,WAAKzG,KAAL,CAAWH,MAAX,CAAkBmB,SAAlB,CAA4BC,GAA5B,CAAgC,KAAKtB,GAAL,CAASE,MAAzC,EAAiD,KAAKF,GAAL,CAASiK,cAA1D;AACA,WAAK5J,KAAL,CAAWH,MAAX,CAAkBQ,WAAlB,CAA8BF,EAAEG,GAAF,CAAM,QAAN,EAAgB,CAAhB,EAAmB,EAAnB,CAA9B;AACA,aAAO,KAAKN,KAAL,CAAWH,MAAlB;AACH;AACD;;;;;;;6BAISgK,K,EAAO;AACZ7E,eAAS8E,WAAT,CAAqB,KAAKJ,WAA1B;AACH;AACD;;;;;;;+BAIWK,S,EAAW;AAClB,UAAMC,WAAWhF,SAASiF,iBAAT,CAA2B,KAAKP,WAAhC,CAAjB;AACA,WAAK1J,KAAL,CAAWH,MAAX,CAAkBmB,SAAlB,CAA4BkJ,MAA5B,CAAmC,KAAKvK,GAAL,CAASgK,YAA5C,EAA0DK,QAA1D;AACA,aAAOA,QAAP;AACH;;;;;;;kBA9CgBG,gB;;;;;;;;;;;;;;;;;;;;;;ACPrB;;;;;;;;AACA;;;;;;;IAOqBC,c;AACjB;;;;AAIA,4BAAY1K,GAAZ,EAAiB;AAAA;;AACb;;;AAGA,aAAK2K,WAAL,GAAmB,YAAnB;AACA,aAAKC,aAAL,GAAqB,QAArB;AACA;;;AAGA,aAAKC,SAAL,GAAiB,EAAjB;AACA;;;AAGA,aAAK5K,GAAL,GAAW;AACPE,oBAAQ,gBADD;AAEP8J,0BAAc,wBAFP;AAGPC,4BAAgB,sBAHT;AAIPY,0BAAc,wBAJP;AAKPC,mBAAO,sBALA;AAMPC,yBAAa;AANN,SAAX;AAQA;;;AAGA,aAAK1K,KAAL,GAAa;AACTH,oBAAQ,IADC;AAET4K,mBAAO;AAFE,SAAb;AAIA;;;AAGA,aAAKE,WAAL,GAAmB,KAAnB;AACA,aAAKC,aAAL,GAAqBlL,IAAImL,OAAzB;AACA,aAAKd,SAAL,GAAiB,IAAIe,mBAAJ,EAAjB;AACH;AACD;;;;;;;iCAGS;AACL,iBAAK9K,KAAL,CAAWH,MAAX,GAAoBmF,SAASyB,aAAT,CAAuB,QAAvB,CAApB;AACA,iBAAKzG,KAAL,CAAWH,MAAX,CAAkBmB,SAAlB,CAA4BC,GAA5B,CAAgC,KAAKtB,GAAL,CAASE,MAAzC,EAAiD,KAAKF,GAAL,CAASiK,cAA1D;AACA,iBAAK5J,KAAL,CAAWH,MAAX,CAAkBQ,WAAlB,CAA8BF,EAAEG,GAAF,CAAM,MAAN,EAAc,EAAd,EAAkB,EAAlB,CAA9B;AACA,iBAAKN,KAAL,CAAWH,MAAX,CAAkBQ,WAAlB,CAA8BF,EAAEG,GAAF,CAAM,QAAN,EAAgB,EAAhB,EAAoB,EAApB,CAA9B;AACA,mBAAO,KAAKN,KAAL,CAAWH,MAAlB;AACH;AACD;;;;;;wCAGgB;AAAA;;AACZ,iBAAKG,KAAL,CAAWyK,KAAX,GAAmBzF,SAASyB,aAAT,CAAuB,OAAvB,CAAnB;AACA,iBAAKzG,KAAL,CAAWyK,KAAX,CAAiB/L,WAAjB,GAA+B,YAA/B;AACA,iBAAKsB,KAAL,CAAWyK,KAAX,CAAiBzJ,SAAjB,CAA2BC,GAA3B,CAA+B,KAAKtB,GAAL,CAAS8K,KAAxC;AACA,iBAAKzK,KAAL,CAAWyK,KAAX,CAAiBM,gBAAjB,CAAkC,SAAlC,EAA6C,UAACtK,KAAD,EAAW;AACpD,oBAAIA,MAAMuK,OAAN,KAAkB,MAAKT,SAA3B,EAAsC;AAClC,0BAAKU,YAAL,CAAkBxK,KAAlB;AACH;AACJ,aAJD;AAKA,mBAAO,KAAKT,KAAL,CAAWyK,KAAlB;AACH;AACD;;;;;;;iCAISZ,K,EAAO;AACZ;;;AAGA,gBAAIA,KAAJ,EAAW;AACP;;;AAGA,qBAAKE,SAAL,CAAe3F,IAAf;AACA,oBAAM8G,eAAe,KAAKnB,SAAL,CAAeoB,aAAf,CAA6B,GAA7B,CAArB;AACA;;;AAGA,oBAAID,YAAJ,EAAkB;AACd,yBAAKnB,SAAL,CAAeqB,WAAf,CAA2BF,YAA3B;AACA,yBAAKG,MAAL;AACA,yBAAKC,YAAL;AACA,yBAAKC,UAAL;AACA,yBAAKX,aAAL,CAAmBY,KAAnB;AACA;AACH;AACJ;AACD,iBAAKC,aAAL;AACH;AACD;;;;;;;mCAIW1B,S,EAAW;AAClB,gBAAM2B,YAAY,KAAK3B,SAAL,CAAeoB,aAAf,CAA6B,GAA7B,CAAlB;AACA,gBAAIO,SAAJ,EAAe;AACX,qBAAK1L,KAAL,CAAWH,MAAX,CAAkBmB,SAAlB,CAA4BC,GAA5B,CAAgC,KAAKtB,GAAL,CAAS6K,YAAzC;AACA,qBAAKxK,KAAL,CAAWH,MAAX,CAAkBmB,SAAlB,CAA4BC,GAA5B,CAAgC,KAAKtB,GAAL,CAASgK,YAAzC;AACA,qBAAKgC,WAAL;AACA;;;AAGA,oBAAMC,WAAWF,UAAUG,YAAV,CAAuB,MAAvB,CAAjB;AACA,qBAAK7L,KAAL,CAAWyK,KAAX,CAAiB9B,KAAjB,GAAyBiD,aAAa,MAAb,GAAsBA,QAAtB,GAAiC,EAA1D;AACA,qBAAK7B,SAAL,CAAe3F,IAAf;AACH,aAVD,MAWK;AACD,qBAAKpE,KAAL,CAAWH,MAAX,CAAkBmB,SAAlB,CAA4BU,MAA5B,CAAmC,KAAK/B,GAAL,CAAS6K,YAA5C;AACA,qBAAKxK,KAAL,CAAWH,MAAX,CAAkBmB,SAAlB,CAA4BU,MAA5B,CAAmC,KAAK/B,GAAL,CAASgK,YAA5C;AACH;AACD,mBAAO,CAAC,CAAC+B,SAAT;AACH;AACD;;;;;;gCAGQ;AACJ,iBAAKJ,YAAL;AACH;;;wCACe;AACZ,gBAAI,CAAC,KAAKX,WAAV,EAAuB;AACnB,qBAAKgB,WAAL,CAAiB,IAAjB;AACH,aAFD,MAGK;AACD,qBAAKL,YAAL,CAAkB,KAAlB;AACH;AACJ;AACD;;;;;;sCAG+B;AAAA,gBAAnBQ,SAAmB,uEAAP,KAAO;;AAC3B,iBAAK9L,KAAL,CAAWyK,KAAX,CAAiBzJ,SAAjB,CAA2BC,GAA3B,CAA+B,KAAKtB,GAAL,CAAS+K,WAAxC;AACA,gBAAIoB,SAAJ,EAAe;AACX,qBAAK9L,KAAL,CAAWyK,KAAX,CAAiBsB,KAAjB;AACH;AACD,iBAAKpB,WAAL,GAAmB,IAAnB;AACH;AACD;;;;;;;;uCAKyC;AAAA,gBAA5BqB,mBAA4B,uEAAN,IAAM;;AACrC,iBAAKhM,KAAL,CAAWyK,KAAX,CAAiBzJ,SAAjB,CAA2BU,MAA3B,CAAkC,KAAK/B,GAAL,CAAS+K,WAA3C;AACA,iBAAK1K,KAAL,CAAWyK,KAAX,CAAiB9B,KAAjB,GAAyB,EAAzB;AACA,gBAAIqD,mBAAJ,EAAyB;AACrB,qBAAKjC,SAAL,CAAekC,UAAf;AACH;AACD,iBAAKtB,WAAL,GAAmB,KAAnB;AACH;AACD;;;;;;;qCAIalK,K,EAAO;AAChB,gBAAIkI,QAAQ,KAAK3I,KAAL,CAAWyK,KAAX,CAAiB9B,KAAjB,IAA0B,EAAtC;AACA,gBAAI,CAACA,MAAMG,IAAN,EAAL,EAAmB;AACf,qBAAKiB,SAAL,CAAemC,OAAf;AACA,qBAAKb,MAAL;AACA5K,sBAAM0L,cAAN;AACA,qBAAKb,YAAL;AACH;AACD,gBAAI,CAAC,KAAKc,WAAL,CAAiBzD,KAAjB,CAAL,EAA8B;AAC1B;;;AAGAzJ,kBAAElC,GAAF,CAAM,uBAAN,EAA+B,MAA/B,EAAuC2L,KAAvC;AACA;AACH;AACDA,oBAAQ,KAAK0D,WAAL,CAAiB1D,KAAjB,CAAR;AACA,iBAAKoB,SAAL,CAAemC,OAAf;AACA,iBAAKI,UAAL,CAAgB3D,KAAhB;AACA;;;AAGAlI,kBAAM0L,cAAN;AACA1L,kBAAM8L,eAAN;AACA9L,kBAAM+L,wBAAN;AACA,iBAAKlB,YAAL;AACA,iBAAKV,aAAL,CAAmBY,KAAnB;AACA,iBAAKD,UAAL;AACH;AACD;;;;;;;;oCAKYkB,G,EAAK;AACb;;;AAGA,mBAAO,CAAC,KAAKC,IAAL,CAAUD,GAAV,CAAR;AACH;AACD;;;;;;;;;oCAMYE,I,EAAM;AACdA,mBAAOA,KAAK7D,IAAL,EAAP;AACA6D,mBAAO,KAAKC,WAAL,CAAiBD,IAAjB,CAAP;AACA,mBAAOA,IAAP;AACH;AACD;;;;;;;oCAIYA,I,EAAM;AACd;;;AAGA,gBAAI,cAAcD,IAAd,CAAmBC,IAAnB,CAAJ,EAA8B;AAC1B,uBAAOA,IAAP;AACH;AACD;;;;;;AAMA,gBAAME,aAAa,aAAaH,IAAb,CAAkBC,IAAlB,CAAnB;AAAA,gBAA4CG,WAAWH,KAAKI,SAAL,CAAe,CAAf,EAAkB,CAAlB,MAAyB,GAAhF;AAAA,gBAAqFC,qBAAqB,eAAeN,IAAf,CAAoBC,IAApB,CAA1G;AACA,gBAAI,CAACE,UAAD,IAAe,CAACC,QAAhB,IAA4B,CAACE,kBAAjC,EAAqD;AACjDL,uBAAO,YAAYA,IAAnB;AACH;AACD,mBAAOA,IAAP;AACH;AACD;;;;;;;mCAIWA,I,EAAM;AACb;;;AAGA,gBAAMjB,YAAY,KAAK3B,SAAL,CAAeoB,aAAf,CAA6B,GAA7B,CAAlB;AACA,gBAAIO,SAAJ,EAAe;AACX,qBAAK3B,SAAL,CAAeqB,WAAf,CAA2BM,SAA3B;AACH;AACD1G,qBAAS8E,WAAT,CAAqB,KAAKO,WAA1B,EAAuC,KAAvC,EAA8CsC,IAA9C;AACH;AACD;;;;;;iCAGS;AACL3H,qBAAS8E,WAAT,CAAqB,KAAKQ,aAA1B;AACH;;;;;;;kBAxPgBF,c;;;;;;;;;;;;;ACRrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yE;;;;;;;;;;;;;;AC5FA;;;;;;;AAOAlO,OAAO+Q,OAAP,GAAiB,UAAUC,OAAV,EAAmB;AAClC,MAAIC,SAASC,MAAMD,MAAnB;;AAEAD,UAAQzC,KAAR,GAAsB,IAAtB;AACAyC,UAAQG,WAAR,GAAsB,IAAtB;;AAEAH,UAAQI,cAAR,GAAyB,UAAUC,YAAV,EAAwB;AAC/CL,YAAQG,WAAR,GAAsBE,YAAtB;AACAL,YAAQzC,KAAR,CAAc9B,KAAd,GAAsBuE,QAAQG,WAAR,CAAoBG,OAApB,CAA4BC,MAA5B,IAAsC,EAA5D;AACD,GAHD;;AAKAP,UAAQQ,aAAR,GAAwB,UAAUlQ,CAAV,EAAa;AACnC,QAAImQ,YAAYnQ,EAAE8B,MAAF,CAASqJ,KAAT,GAAiBuE,QAAQU,aAAR,CAAsBpQ,EAAE8B,MAAF,CAASqJ,KAA/B,CAAjC;;AAEAuE,YAAQG,WAAR,CAAoBG,OAApB,CAA4BC,MAA5B,GAAqCE,SAArC;;AAEA,QAAIA,UAAU7E,IAAV,OAAqB,EAAzB,EAA6B;AAC3BoE,cAAQG,WAAR,CAAoBrM,SAApB,CAA8BC,GAA9B,CAAkCkM,OAAOU,EAAP,CAAUC,SAAV,CAAoBC,iBAAtD;AACD,KAFD,MAEO;AACLb,cAAQG,WAAR,CAAoBrM,SAApB,CAA8BU,MAA9B,CAAqCyL,OAAOU,EAAP,CAAUC,SAAV,CAAoBC,iBAAzD;AACD;AACF,GAVD;;AAYAb,UAAQc,oBAAR,GAA+B,UAAUxQ,CAAV,EAAa;AAC1C,QAAIA,EAAEwN,OAAF,IAAamC,OAAOc,IAAP,CAAYC,IAAZ,CAAiBC,KAAlC,EAAyC;AACvC3Q,QAAE2O,cAAF;AACA3O,QAAE+O,eAAF;;AAEA/O,QAAE8B,MAAF,CAAS8O,IAAT;AACAjB,aAAOtC,OAAP,CAAezH,QAAf,CAAwBoI,KAAxB;AACD;AACF,GARD;;AAUA0B,UAAQmB,kBAAR,GAA6B,UAAU7Q,CAAV,EAAa;AACxC,QAAIA,EAAEwN,OAAF,IAAamC,OAAOc,IAAP,CAAYC,IAAZ,CAAiBI,IAA9B,IAAsC9Q,EAAEwN,OAAF,IAAamC,OAAOc,IAAP,CAAYC,IAAZ,CAAiBK,IAAxE,EAA8E;AAC5E/Q,QAAE+O,eAAF;AACD;AACF,GAJD;;AAMAW,UAAQU,aAAR,GAAwB,UAAUY,MAAV,EAAkB;AACxC,QAAIC,KAAK,CACL,GADK,EACA,GADA,EACK,GADL,EACU,GADV,EACe,GADf,EACoB,GADpB,EACyB,GADzB,EAC8B,GAD9B,EACmC,GADnC,EACwC,GADxC,EAC6C,GAD7C,EAEL,GAFK,EAEA,GAFA,EAEK,GAFL,EAEU,GAFV,EAEe,GAFf,EAEoB,GAFpB,EAEyB,GAFzB,EAE8B,GAF9B,EAEmC,GAFnC,EAEwC,GAFxC,EAE6C,GAF7C,EAGL,GAHK,EAGA,GAHA,EAGK,GAHL,EAGU,GAHV,EAGe,GAHf,EAGoB,GAHpB,EAGyB,GAHzB,EAG8B,GAH9B,EAGmC,GAHnC,EAGwC,GAHxC,EAG6C,GAH7C,CAAT;AAAA,QAKEC,KAAK,CACH,GADG,EACE,GADF,EACO,GADP,EACY,GADZ,EACiB,GADjB,EACsB,GADtB,EAC2B,GAD3B,EACgC,IADhC,EACsC,GADtC,EAC2C,GAD3C,EACgD,GADhD,EAEH,GAFG,EAEE,GAFF,EAEO,GAFP,EAEY,GAFZ,EAEiB,GAFjB,EAEsB,GAFtB,EAE2B,GAF3B,EAEgC,GAFhC,EAEqC,GAFrC,EAE0C,GAF1C,EAE+C,GAF/C,EAGH,GAHG,EAGE,GAHF,EAGO,IAHP,EAGa,IAHb,EAGmB,KAHnB,EAG0B,EAH1B,EAG8B,GAH9B,EAGmC,EAHnC,EAGuC,GAHvC,EAG4C,IAH5C,EAGkD,IAHlD,CALP;;AAWA,SAAK,IAAIC,IAAI,CAAb,EAAgBA,IAAIF,GAAGrP,MAAvB,EAA+BuP,GAA/B,EAAoC;AAClCH,eAASA,OAAOI,KAAP,CAAaH,GAAGE,CAAH,CAAb,EAAoB3I,IAApB,CAAyB0I,GAAGC,CAAH,CAAzB,CAAT;AACAH,eAASA,OAAOI,KAAP,CAAaH,GAAGE,CAAH,EAAME,WAAN,EAAb,EAAkC7I,IAAlC,CAAuC0I,GAAGC,CAAH,EAAME,WAAN,EAAvC,CAAT;AACD;;AAEDL,aAASA,OAAO3F,OAAP,CAAe,iBAAf,EAAkC,GAAlC,CAAT;;AAEA,WAAO2F,MAAP;AACD,GApBD;;AAsBA,SAAOtB,OAAP;AACD,CA9DgB,CA8Df,EA9De,CAAjB,C;;;;;;;;;;;;;;ACPA;;;;;;;;AAQAhR,OAAO+Q,OAAP,GAAkB,UAAU6B,SAAV,EAAqB;AACrC,MAAI3B,SAASC,MAAMD,MAAnB;;AAEA;;;;;AAKA2B,YAAUC,aAAV,GAA0B,UAAUtO,KAAV,EAAiB;AACzC,YAAQA,MAAMuK,OAAd;AACE,WAAKmC,OAAOc,IAAP,CAAYC,IAAZ,CAAiBC,KAAtB;AAA8Ba,yBAAiBvO,KAAjB,EAA6B;AAD7D;AAGD,GAJD;;AAMA;;;;;AAKAqO,YAAUG,eAAV,GAA4B,UAAUxO,KAAV,EAAiB;AAC3C,YAAQA,MAAMuK,OAAd;AACE,WAAKmC,OAAOc,IAAP,CAAYC,IAAZ,CAAiBgB,GAAtB;AAA8BC,sCAA8B1O,KAA9B,EAA0D;AACxF,WAAK0M,OAAOc,IAAP,CAAYC,IAAZ,CAAiBC,KAAtB;AAA8BiB,wCAAgC3O,KAAhC,EAA0D;AACxF,WAAK0M,OAAOc,IAAP,CAAYC,IAAZ,CAAiBmB,GAAtB;AAA8BC,yCAAiC7O,KAAjC,EAA0D;AACxF;AAA8B8O,0CAAkC9O,KAAlC,EAA0D;AAJ1F;AAMD,GAPD;;AASA;;;;;AAKAqO,YAAUU,WAAV,GAAwB,UAAU/O,KAAV,EAAiB;AACvC,YAAQA,MAAMuK,OAAd;AACE,WAAKmC,OAAOc,IAAP,CAAYC,IAAZ,CAAiBuB,EAAtB;AACA,WAAKtC,OAAOc,IAAP,CAAYC,IAAZ,CAAiBI,IAAtB;AACA,WAAKnB,OAAOc,IAAP,CAAYC,IAAZ,CAAiBwB,KAAtB;AACA,WAAKvC,OAAOc,IAAP,CAAYC,IAAZ,CAAiBK,IAAtB;AAA8BoB,yBAAiBlP,KAAjB,EAAyB;AAJzD;AAMD,GAPD;;AASA;;;;;;;;AAQA,MAAI0O,gCAAgC,SAAhCA,6BAAgC,CAAU1O,KAAV,EAAiB;AACnD;;;;AAIAA,UAAM0L,cAAN;;AAGA,QAAI,CAACgB,OAAOc,IAAP,CAAY2B,YAAZ,CAAyBzC,OAAOvJ,OAAP,CAAeyJ,WAAxC,CAAL,EAA2D;AACzD;AACD;;AAED,QAAK,CAACF,OAAOtC,OAAP,CAAegF,MAArB,EAA+B;AAC7B1C,aAAOtC,OAAP,CAAeiF,IAAf;AACD;;AAED,QAAI3C,OAAOtC,OAAP,CAAegF,MAAf,IAAyB,CAAC1C,OAAOtC,OAAP,CAAekF,OAAf,CAAuBF,MAArD,EAA6D;AAC3D1C,aAAOtC,OAAP,CAAekF,OAAf,CAAuBD,IAAvB;AACD,KAFD,MAEO;AACL3C,aAAOtC,OAAP,CAAekF,OAAf,CAAuBvG,IAAvB;AACD;AACF,GArBD;;AAuBE;;;;;AAKF,MAAIwF,mBAAmB,SAAnBA,gBAAmB,GAAY;AACjC,QAAI7B,OAAOvJ,OAAP,CAAeoM,sBAAnB,EAA2C;AACzC;;;;AAIA7C,aAAO8C,KAAP,CAAazM,UAAb,GAA0B,CAAC,CAA3B;;AAEA0M;AACD;AACF,GAVD;;AAYE;;;;;;;;AAQF,MAAIA,uBAAuB,SAAvBA,oBAAuB,GAAY;AACrC,QAAIC,iBAAkBhD,OAAO/J,QAAP,CAAgBgN,kBAAtC;;AAEAjD,WAAOvJ,OAAP,CAAeyM,WAAf,CAA2B;AACzB7R,YAAQ2R,cADiB;AAEzBG,aAAQnD,OAAOnO,KAAP,CAAamR,cAAb,EAA6B/R,MAA7B;AAFiB,KAA3B,EAGG,IAHH;;AAKA+O,WAAOtC,OAAP,CAAe0F,IAAf;AACApD,WAAOtC,OAAP,CAAeiF,IAAf;AACD,GAVD;;AAaE;;;;;;;;AAQF,MAAIV,kCAAkC,SAAlCA,+BAAkC,CAAU3O,KAAV,EAAiB;AACrD,QAAIA,MAAMnB,MAAN,CAAakR,eAAb,IAAgC,MAApC,EAA4C;AAC1C;AACArD,aAAO8C,KAAP,CAAaQ,qBAAb;AACD;;AAED,QAAIC,oBAA0BvD,OAAO8C,KAAP,CAAaU,oBAAb,MAAuC,CAArE;AAAA,QACEC,cAA0BzD,OAAOvJ,OAAP,CAAeyJ,WAD3C;AAAA,QAEE/J,OAA0BsN,YAAYpD,OAAZ,CAAoBlK,IAFhD;AAAA,QAGEuN,0BAA0B1D,OAAOtC,OAAP,CAAegF,MAAf,IACQ1C,OAAOtC,OAAP,CAAeiG,OADvB,IAEQrQ,MAAMnB,MAAN,IAAgB6N,OAAOzP,KAAP,CAAa8H,MAAb,CAAoBkL,iBAApB,CALpD;;AAOA;AACA,QAAIK,mBAAmB5D,OAAOnO,KAAP,CAAasE,IAAb,EAAmByN,gBAA1C;;AAEA;AACA,QAAIZ,iBAAiBhD,OAAO/J,QAAP,CAAgBgN,kBAArC;;AAEA;;;AAGA,QAAKS,uBAAL,EAA+B;AAC7BpQ,YAAM0L,cAAN;;AAEAgB,aAAOtC,OAAP,CAAekF,OAAf,CAAuBiB,WAAvB,CAAmCvQ,KAAnC;;AAEA0M,aAAOtC,OAAP,CAAeW,KAAf;;AAEA;;;AAGA/K,YAAM8L,eAAN;AACA9L,YAAM+L,wBAAN;;AAEA;AACD;;AAED;;;;AAIA,QAAK/L,MAAMwQ,QAAN,IAAkBF,gBAAvB,EAA0C;AACxCtQ,YAAM8L,eAAN;AACA9L,YAAM+L,wBAAN;AACA;AACD;;AAED,QAAI0E,mBAAmB1P,OAAO2P,YAAP,EAAvB;AAAA,QACEC,sBAAsBF,iBAAiBG,UADzC;AAAA,QAEEC,sBAAsBnE,OAAO8C,KAAP,CAAasB,QAAb,CAAsBC,QAAtB,EAFxB;AAAA,QAGEC,4CAA4C,KAH9C;;AAKA;;;AAGA,QAAKhR,MAAMwQ,QAAN,IAAkB,CAACF,gBAAxB,EAA2C;AACzC5D,aAAOuE,QAAP,CAAgBC,mBAAhB,CAAoCxE,OAAOvJ,OAAP,CAAe2J,YAAnD,EAAiE9M,KAAjE;AACAA,YAAM0L,cAAN;AACA;AACD;;AAED;;;;;AAKAsF,gDAA4CL,uBAAuBA,oBAAoB3J,UAApB,CAA+B+I,eAA/B,IAAkD,MAArH;;AAEA;;;AAGA,QACEY,oBAAoBnJ,QAApB,IAAgCkF,OAAOc,IAAP,CAAY2D,SAAZ,CAAsBC,IAAtD,IACM,CAACJ,yCADP,IAEM,CAACH,mBAHT,EAIE;AACA7Q,YAAM0L,cAAN;;AAEAgB,aAAOc,IAAP,CAAYjR,GAAZ,CAAgB,wBAAhB;;AAEAmQ,aAAOvJ,OAAP,CAAekO,UAAf,CAA0BpB,iBAA1B;;AAEA;AACA,UAAI,CAACvD,OAAOzP,KAAP,CAAa8H,MAAb,CAAoBkL,oBAAoB,CAAxC,EAA2C9H,WAA3C,CAAuDE,IAAvD,EAAL,EAAoE;AAClEqE,eAAOtC,OAAP,CAAekH,cAAf;AACD;AACF,KAfD,MAeO;AACL,UAAIC,aAAa7E,OAAOvJ,OAAP,CAAeqO,UAAf,CAA0Bb,mBAA1B,CAAjB;;AAEA,UAAKY,cAAcV,mBAAnB,EAAyC;AACvC7Q,cAAM0L,cAAN;AACA1L,cAAM8L,eAAN;AACA9L,cAAM+L,wBAAN;;AAEAW,eAAOc,IAAP,CAAYjR,GAAZ,CAAgB,kDAAhB;;AAEAmQ,eAAOvJ,OAAP,CAAeyM,WAAf,CAA2B;AACzB7R,gBAAM2R,cADmB;AAEzBG,iBAAOnD,OAAOnO,KAAP,CAAamR,cAAb,EAA6B/R,MAA7B;AAFkB,SAA3B,EAGG,IAHH;;AAKA+O,eAAOtC,OAAP,CAAe0F,IAAf;AACApD,eAAOtC,OAAP,CAAeiF,IAAf;;AAEA;AACA3C,eAAOtC,OAAP,CAAekH,cAAf;AACD;AACF;;AAED;AACA5E,WAAOU,EAAP,CAAUqE,UAAV;AACD,GAhHD;;AAkHE;;;;;;;AAOF,MAAI5C,mCAAmC,SAAnCA,gCAAmC,CAAU7O,KAAV,EAAiB;AACtD;AACA0M,WAAOtC,OAAP,CAAeW,KAAf;;AAEA;AACA2B,WAAOtC,OAAP,CAAekF,OAAf,CAAuBvE,KAAvB;;AAEA/K,UAAM0L,cAAN;AACD,GARD;;AAUE;;;;;;AAMF,MAAIwD,mBAAmB,SAAnBA,gBAAmB,CAAUlP,KAAV,EAAiB;AACtC0M,WAAOvJ,OAAP,CAAeuO,kBAAf;;AAEA;AACAhF,WAAOtC,OAAP,CAAeW,KAAf;AACA2B,WAAOtC,OAAP,CAAe0F,IAAf;AACD,GAND;;AAQE;;;;;;;AAOF,MAAIhB,oCAAoC,SAApCA,iCAAoC,GAAY;AAClDpC,WAAOtC,OAAP,CAAeW,KAAf;;AAEA,QAAI,CAAC2B,OAAOtC,OAAP,CAAeuH,MAAf,CAAsBC,aAA3B,EAA0C;AACxClF,aAAOtC,OAAP,CAAeuH,MAAf,CAAsB5G,KAAtB;AACA2B,aAAOvJ,OAAP,CAAe0O,SAAf;AACD;AACF,GAPD;;AASE;;;;;;;;;;;;;AAaFxD,YAAUyD,eAAV,GAA4B,UAAU9R,KAAV,EAAiB;AAC3C+R;;AAEArF,WAAOvJ,OAAP,CAAeuO,kBAAf,CAAkC1R,MAAMnB,MAAxC;AACA6N,WAAOU,EAAP,CAAUqE,UAAV;;AAEA,QAAIO,eAAetF,OAAOtC,OAAP,CAAeuH,MAAf,CAAsBM,gBAAtB,EAAnB;AAAA,QACEC,eADF;;AAGA;AACA,QAAIF,aAAarT,MAAb,KAAwB,CAA5B,EAA+B;AAC7B+N,aAAOtC,OAAP,CAAeuH,MAAf,CAAsB5G,KAAtB;AACD;;AAED;AACA,QAAI/K,MAAMnB,MAAN,CAAakR,eAAb,IAAgC,MAApC,EAA4C;AAC1CrD,aAAO8C,KAAP,CAAaQ,qBAAb;AACD;;AAED,QAAItD,OAAOvJ,OAAP,CAAeyJ,WAAf,KAA+B,IAAnC,EAAyC;AACvC;;;AAGA,UAAIuF,mBAAmBzF,OAAOzP,KAAP,CAAa8H,MAAb,CAAoBpG,MAApB,GAA6B,CAA7B,GAAiC+N,OAAOzP,KAAP,CAAa8H,MAAb,CAAoBpG,MAApB,GAA6B,CAA9D,GAAkE,CAAzF;;AAEA;AACA,UAAI+N,OAAOzP,KAAP,CAAa8H,MAAb,CAAoBpG,MAAxB,EAAgC;AAC9B;AACAuT,0BAAkBxF,OAAOvJ,OAAP,CAAeiP,kBAAf,CAAkC1F,OAAOzP,KAAP,CAAa8H,MAAb,CAAoBoN,gBAApB,CAAlC,CAAlB;AACD;;AAED;AACA,UAAIzF,OAAOzP,KAAP,CAAa8H,MAAb,CAAoBpG,MAApB,IAA8B+N,OAAOzP,KAAP,CAAa8H,MAAb,CAAoBoN,gBAApB,EAAsChK,WAAtC,KAAsD,EAApF,IAA0F+J,gBAAgBnF,OAAhB,CAAwBlK,IAAxB,IAAgC6J,OAAO/J,QAAP,CAAgBgN,kBAA9I,EAAkK;AAChKjD,eAAO8C,KAAP,CAAa6C,UAAb,CAAwBF,gBAAxB;AACD,OAFD,MAEO;AACL;AACA,YAAIzC,iBAAiBhD,OAAO/J,QAAP,CAAgBgN,kBAArC;;AAEAjD,eAAOvJ,OAAP,CAAeyM,WAAf,CAA2B;AACzB7R,gBAAQ2R,cADiB;AAEzBG,iBAAQnD,OAAOnO,KAAP,CAAamR,cAAb,EAA6B/R,MAA7B;AAFiB,SAA3B;;AAKA;AACA,YAAI+O,OAAOzP,KAAP,CAAa8H,MAAb,CAAoBpG,MAApB,KAA+B,CAAnC,EAAsC;AACpC+N,iBAAO8C,KAAP,CAAa6C,UAAb,CAAwBF,gBAAxB;AACD,SAFD,MAEO;AACL;AACAzF,iBAAO8C,KAAP,CAAa8C,cAAb,CAA4BH,gBAA5B;AACD;AACF;AACF,KAhCD,MAgCO;AACL;AACAzF,aAAOtC,OAAP,CAAezH,QAAf,CAAwBoI,KAAxB;AACA2B,aAAOtC,OAAP,CAAekF,OAAf,CAAuBvE,KAAvB;AACD;;AAED;;;AAGA2B,WAAOtC,OAAP,CAAe0F,IAAf;AACApD,WAAOtC,OAAP,CAAeiF,IAAf;;AAEA,QAAIkD,eAAe,CAAC7F,OAAOvJ,OAAP,CAAeyJ,WAAf,CAA2BzE,WAA3B,CAAuCE,IAAvC,EAApB;AAAA,QACEmK,kBAAkB9F,OAAOvJ,OAAP,CAAeyJ,WAAf,CAA2BG,OAA3B,CAAmClK,IADvD;AAAA,QAEE4P,gBAAgBD,mBAAmB9F,OAAO/J,QAAP,CAAgBgN,kBAFrD;;AAKA;AACAjD,WAAOtC,OAAP,CAAesI,cAAf;;AAEA,QAAI,CAACH,YAAL,EAAmB;AACjB;AACA7F,aAAOvJ,OAAP,CAAewP,SAAf;AACD;;AAED,QAAKF,iBAAiBF,YAAtB,EAAqC;AACnC;AACA7F,aAAOtC,OAAP,CAAekH,cAAf;AACD;AACF,GAhFD;;AAkFA;;;;;;;;;;AAUA,MAAIS,0CAA0C,SAA1CA,uCAA0C,GAAY;AACxD,QAAIzI,YAAavI,OAAO2P,YAAP,EAAjB;AAAA,QACEE,aAAatH,UAAUsH,UADzB;AAAA,QAEEgC,OAAO,KAFT;;AAIA,QAAItJ,UAAUuJ,UAAV,KAAyB,CAA7B,EAAgC;AAC9BnG,aAAOvJ,OAAP,CAAeoM,sBAAf,GAAwC,IAAxC;AACD,KAFD,MAEO;AACL,UAAI,CAAC7C,OAAOc,IAAP,CAAYsF,SAAZ,CAAsBlC,UAAtB,CAAL,EAAwC;AACtCA,qBAAaA,WAAW5J,UAAxB;AACD;;AAED;AACA,UAAI4J,WAAWb,eAAX,IAA8B,MAAlC,EAA0C;AACxC6C,eAAO,IAAP;AACD;;AAED,aAAOhC,WAAWb,eAAX,IAA8B,MAArC,EAA6C;AAC3Ca,qBAAaA,WAAW5J,UAAxB;;AAEA,YAAI4J,WAAWb,eAAX,IAA8B,MAAlC,EAA0C;AACxC6C,iBAAO,IAAP;AACD;;AAED,YAAIhC,cAAcrM,SAASwO,IAA3B,EAAiC;AAC/B;AACD;AACF;;AAED;AACArG,aAAOvJ,OAAP,CAAeoM,sBAAf,GAAwC,CAACqD,IAAzC;AACD;AACF,GAhCD;;AAkCE;;;;;;;;AAQFvE,YAAU2E,oBAAV,GAAiC,UAAUhT,KAAV,EAAiB;AAChD,QAAIZ,SAAS,IAAb;;AAEAsN,WAAOtC,OAAP,CAAeiG,OAAf,GAAyBjR,OAAO2N,OAAP,CAAehP,IAAxC;;AAEA2O,WAAOtC,OAAP,CAAekF,OAAf,CAAuBiB,WAAvB,CAAmCvQ,KAAnC;AACA0M,WAAOtC,OAAP,CAAeW,KAAf;AACD,GAPD;;AASA;;;AAGAsD,YAAU4E,iBAAV,GAA8B,YAAY;AACxC,QAAI,CAACvG,OAAOnN,KAAP,CAAa+P,OAAb,CAAqB/O,SAArB,CAA+B2S,QAA/B,CAAwC,QAAxC,CAAL,EAAwD;AACtDxG,aAAOtC,OAAP,CAAekF,OAAf,CAAuBD,IAAvB;AACD,KAFD,MAEO;AACL3C,aAAOtC,OAAP,CAAekF,OAAf,CAAuBvE,KAAvB;AACD;AACF,GAND;;AAQA;;;;;;;;;;;AAWAsD,YAAU8E,YAAV,GAAyB,UAAUnT,KAAV,EAAiB;AACxC,QAAI6P,QAAQ7P,MAAMnB,MAAlB,CADwC,CACd;;AAE1B,YAAQmB,MAAMuK,OAAd;AACE,WAAKmC,OAAOc,IAAP,CAAYC,IAAZ,CAAiBK,IAAtB;AACA,WAAKpB,OAAOc,IAAP,CAAYC,IAAZ,CAAiBwB,KAAtB;AACEmE,sCAA8BpT,KAA9B;AACA;;AAEF,WAAK0M,OAAOc,IAAP,CAAYC,IAAZ,CAAiB4F,SAAtB;AACEC,0BAAkBzD,KAAlB,EAAyB7P,KAAzB;AACA;;AAEF,WAAK0M,OAAOc,IAAP,CAAYC,IAAZ,CAAiBuB,EAAtB;AACA,WAAKtC,OAAOc,IAAP,CAAYC,IAAZ,CAAiBI,IAAtB;AACE0F,mCAA2BvT,KAA3B;AACA;AAbJ;AAeD,GAlBD;;AAoBA;;;;;;;;;;AAUA,MAAIoT,gCAAgC,SAAhCA,6BAAgC,CAAUpT,KAAV,EAAiB;AACnD,QAAIsJ,YAAcvI,OAAO2P,YAAP,EAAlB;AAAA,QACE3L,SAAc2H,OAAOzP,KAAP,CAAa8H,MAD7B;AAAA,QAEEyO,cAAclK,UAAUsH,UAF1B;AAAA,QAGE6C,iBAHF;;AAKA;AACA,QAAI,CAACD,WAAL,EAAkB;AAChB,aAAO,KAAP;AACD;;AAED;AACA,WAAOA,YAAYzD,eAAZ,IAA+B,MAAtC,EAA8C;AAC5C0D,0BAAoBD,YAAYxM,UAAhC;AACAwM,oBAAoBC,iBAApB;AACD;;AAED;AACA,QAAIC,uBAAuB,CAA3B;;AAEA,WAAOF,eAAezO,OAAO2O,oBAAP,CAAtB,EAAoD;AAClDA;AACD;;AAED;;;;AAIA,QAAI,CAACF,YAAYrL,WAAjB,EAA8B;AAC5BuE,aAAO8C,KAAP,CAAa8C,cAAb,CAA4BoB,oBAA5B;AACA;AACD;;AAED;;;AAGA,QAAIC,mBAAsB,KAA1B;AAAA,QACE9C,sBAAsB,KADxB;;AAGA,QAAI+C,SAAJ,EACEC,eADF;;AAGAD,gBAAYJ,YAAY7O,UAAZ,CAAuB6O,YAAY7O,UAAZ,CAAuBhG,MAAvB,GAAgC,CAAvD,CAAZ;;AAEA,QAAI+N,OAAOc,IAAP,CAAYsF,SAAZ,CAAsBc,SAAtB,CAAJ,EAAsC;AACpCC,wBAAkBnH,OAAOvJ,OAAP,CAAe2Q,8BAAf,CAA8CF,SAA9C,EAAyDA,UAAUjP,UAAV,CAAqBhG,MAA9E,CAAlB;AACD,KAFD,MAEO;AACLkV,wBAAkBD,SAAlB;AACD;;AAEDD,uBAAmBrK,UAAUsH,UAAV,IAAwBiD,eAA3C;AACAhD,0BAAsBgD,gBAAgBlV,MAAhB,IAA0B2K,UAAUyK,YAA1D;;AAEA,QAAK,CAACJ,gBAAD,IAAsB,CAAC9C,mBAA5B,EAAkD;AAChDnE,aAAOc,IAAP,CAAYjR,GAAZ,CAAgB,qDAAhB;AACA,aAAO,KAAP;AACD;;AAEDmQ,WAAO8C,KAAP,CAAa8C,cAAb,CAA4BoB,oBAA5B;AACD,GA3DD;;AA6DE;;;;;;;;;;;AAWF,MAAIH,6BAA6B,SAA7BA,0BAA6B,CAAUvT,KAAV,EAAiB;AAChD,QAAIsJ,YAAcvI,OAAO2P,YAAP,EAAlB;AAAA,QACE3L,SAAc2H,OAAOzP,KAAP,CAAa8H,MAD7B;AAAA,QAEEyO,cAAclK,UAAUsH,UAF1B;AAAA,QAGE6C,iBAHF;;AAKA;AACA,QAAI,CAACD,WAAL,EAAkB;AAChB,aAAO,KAAP;AACD;;AAED;;;AAGA,QAAKlK,UAAUyK,YAAV,KAA2B,CAAhC,EAAmC;AACjC,aAAO,KAAP;AACD;;AAED;AACA,WAAOP,YAAYzD,eAAZ,IAA+B,MAAtC,EAA8C;AAC5C0D,0BAAoBD,YAAYxM,UAAhC;AACAwM,oBAAoBC,iBAApB;AACD;;AAED;AACA,QAAIC,uBAAuB,CAA3B;;AAEA,WAAOF,eAAezO,OAAO2O,oBAAP,CAAtB,EAAoD;AAClDA;AACD;;AAED;;;AAGA,QAAIM,oBAAsB,KAA1B;AAAA,QACEC,sBAAsB,KADxB;;AAGA,QAAIvL,UAAJ,EACEmL,eADF;;AAGA;;;;AAIA,QAAI,CAACL,YAAYrL,WAAjB,EAA8B;AAC5BuE,aAAO8C,KAAP,CAAa0E,kBAAb,CAAgCR,oBAAhC;AACA;AACD;;AAEDhL,iBAAa8K,YAAY7O,UAAZ,CAAuB,CAAvB,CAAb;;AAEA,QAAI+H,OAAOc,IAAP,CAAYsF,SAAZ,CAAsBpK,UAAtB,CAAJ,EAAuC;AACrCmL,wBAAkBnH,OAAOvJ,OAAP,CAAe2Q,8BAAf,CAA8CpL,UAA9C,EAA0D,CAA1D,CAAlB;AACD,KAFD,MAEO;AACLmL,wBAAkBnL,UAAlB;AACD;;AAEDsL,wBAAsB1K,UAAUsH,UAAV,IAAwBiD,eAA9C;AACAI,0BAAsB3K,UAAUyK,YAAV,KAA2B,CAAjD;;AAEA,QAAKC,qBAAqBC,mBAA1B,EAAgD;AAC9CvH,aAAO8C,KAAP,CAAa0E,kBAAb,CAAgCR,oBAAhC;AACD;AACF,GA/DD;;AAiEE;;;;;;;;;;;;AAYF,MAAIJ,oBAAoB,SAApBA,iBAAoB,CAAUzD,KAAV,EAAiB7P,KAAjB,EAAwB;AAC9C,QAAIiQ,oBAAoBvD,OAAO8C,KAAP,CAAaU,oBAAb,EAAxB;AAAA,QACE9G,KADF;AAAA,QAEE+K,eAFF;AAAA,QAGEC,qBAHF;;AAKA,QAAI1H,OAAOc,IAAP,CAAYvF,aAAZ,CAA0BjI,MAAMnB,MAAhC,CAAJ,EAA6C;AAC3C;AACA,UAAImB,MAAMnB,MAAN,CAAaqJ,KAAb,CAAmBG,IAAnB,MAA6B,EAAjC,EAAqC;AACnCwH,cAAM5O,MAAN;AACD,OAFD,MAEO;AACL;AACD;AACF;;AAED,QAAI4O,MAAM1H,WAAN,CAAkBE,IAAlB,EAAJ,EAA8B;AAC5Be,cAAkBsD,OAAOvJ,OAAP,CAAekR,QAAf,EAAlB;AACAF,wBAAkB/K,MAAMkL,SAAN,GAAkBlL,MAAMmL,WAA1C;;AAEA,UAAI7H,OAAO8C,KAAP,CAAasB,QAAb,CAAsB0D,OAAtB,MAAmC,CAACL,eAApC,IAAuDzH,OAAOzP,KAAP,CAAa8H,MAAb,CAAoBkL,oBAAoB,CAAxC,CAA3D,EAAuG;AACrGvD,eAAOvJ,OAAP,CAAesR,WAAf,CAA2BxE,iBAA3B;AACD,OAFD,MAEO;AACL;AACD;AACF;;AAED,QAAI,CAACkE,eAAL,EAAsB;AACpBtE,YAAM5O,MAAN;AACD;;AAGDmT,4BAAwB1H,OAAOnN,KAAP,CAAamV,QAAb,CAAsB/P,UAAtB,CAAiChG,MAAzD;;AAEA;;;AAGA,QAAIyV,0BAA0B,CAA9B,EAAiC;AAC/B;AACA1H,aAAOvJ,OAAP,CAAeyJ,WAAf,GAA6B,IAA7B;;AAEA;AACAF,aAAOU,EAAP,CAAUuH,eAAV;;AAEA;AACAjI,aAAOU,EAAP,CAAUqE,UAAV;;AAEA;AACA1Q,aAAOC,UAAP,CAAkB,YAAY;AAC5B0L,eAAO8C,KAAP,CAAa0E,kBAAb,CAAgC,CAAhC;AACD,OAFD,EAEG,EAFH;AAGD,KAdD,MAcO;AACL,UAAIxH,OAAO8C,KAAP,CAAazM,UAAb,KAA4B,CAAhC,EAAmC;AACjC;AACA2J,eAAO8C,KAAP,CAAa0E,kBAAb,CAAgCxH,OAAO8C,KAAP,CAAazM,UAA7C;AACD,OAHD,MAGO;AACL;AACA2J,eAAO8C,KAAP,CAAa8C,cAAb,CAA4B5F,OAAO8C,KAAP,CAAazM,UAAzC;AACD;AACF;;AAED2J,WAAOtC,OAAP,CAAe0F,IAAf;;AAEA,QAAI,CAACpD,OAAOtC,OAAP,CAAegF,MAApB,EAA4B;AAC1B1C,aAAOtC,OAAP,CAAeiF,IAAf;AACD;;AAED;AACA3C,WAAOU,EAAP,CAAUqE,UAAV;;AAEA;AACAzR,UAAM0L,cAAN;AACD,GAvED;;AAyEE;;;;;;;;AAQF2C,YAAUuG,yBAAV,GAAsC,UAAU5U,KAAV,EAAiB;AACrD;;;;;;AAMA,QAAI6U,kBAAkBnI,OAAOvJ,OAAP,CAAeyJ,WAAf,CAA2BG,OAA3B,CAAmClK,IAAzD;;AAEA6J,WAAOtC,OAAP,CAAezH,QAAf,CAAwB8G,MAAxB,CAA+BoL,eAA/B;;AAEA;AACAnI,WAAOtC,OAAP,CAAekF,OAAf,CAAuBvE,KAAvB;AACA2B,WAAOtC,OAAP,CAAezH,QAAf,CAAwBmS,iBAAxB;AACD,GAdD;;AAgBA,SAAOzG,SAAP;AACD,CA/tBgB,CA+tBd,EA/tBc,CAAjB,C;;;;;;;;;;;;;;ACRA;;;;;;;AAOA5S,OAAO+Q,OAAP,GAAkB,UAAUgD,KAAV,EAAiB;AACjC,MAAI9C,SAASC,MAAMD,MAAnB;;AAEA;;;AAGA8C,QAAMzM,UAAN,GAAmB,IAAnB;;AAEA;;;AAGAyM,QAAMuF,MAAN,GAAe,IAAf;;AAEA;;;AAGAvF,QAAMwF,gBAAN,GAAyB,IAAzB;;AAEA;;;;;;AAMAxF,QAAMyF,GAAN,GAAY,UAAWlP,EAAX,EAAemP,KAAf,EAAsBH,MAAtB,EAA8B;AACxCA,aAASA,UAAUvF,MAAMuF,MAAhB,IAA0B,CAAnC;AACAG,YAASA,SAAU1F,MAAMwF,gBAAhB,IAAoC,CAA7C;;AAEA,QAAIG,SAASpP,GAAGpB,UAAhB;AAAA,QACEyQ,SADF;;AAGA,QAAKD,OAAOxW,MAAP,KAAkB,CAAvB,EAA2B;AACzByW,kBAAYrP,EAAZ;AACD,KAFD,MAEO;AACLqP,kBAAYD,OAAOD,KAAP,CAAZ;AACD;;AAED;AACA,QAAInP,GAAGgK,eAAH,IAAsB,MAA1B,EAAkC;AAChChK,SAAGuF,KAAH;AACA;AACD;;AAED,QAAIoB,OAAOc,IAAP,CAAYsF,SAAZ,CAAsBsC,SAAtB,CAAJ,EAAsC;AACpCA,kBAAY1I,OAAOvJ,OAAP,CAAe2Q,8BAAf,CAA8CsB,SAA9C,EAAyDA,UAAUzQ,UAAV,CAAqBhG,MAA9E,CAAZ;AACD;;AAED,QAAIyK,QAAY7E,SAAS8Q,WAAT,EAAhB;AAAA,QACE/L,YAAYvI,OAAO2P,YAAP,EADd;;AAGA3P,WAAOC,UAAP,CAAkB,YAAY;AAC5BoI,YAAMkM,QAAN,CAAeF,SAAf,EAA0BL,MAA1B;AACA3L,YAAMmM,MAAN,CAAaH,SAAb,EAAwBL,MAAxB;;AAEAzL,gBAAUkM,eAAV;AACAlM,gBAAUmM,QAAV,CAAmBrM,KAAnB;;AAEAsD,aAAO8C,KAAP,CAAaQ,qBAAb;AACD,KARD,EAQG,EARH;AASD,GAnCD;;AAqCA;;;;AAIAR,QAAMQ,qBAAN,GAA8B,YAAY;AACxC;AACA,QAAI1G,YAAcvI,OAAO2P,YAAP,EAAlB;AAAA,QACE3L,SAAc2H,OAAOzP,KAAP,CAAa8H,MAD7B;AAAA,QAEEyO,cAAclK,UAAUsH,UAF1B;AAAA,QAGE6C,iBAHF;;AAKA,QAAI,CAACD,WAAL,EAAkB;AAChB;AACD;;AAED;AACA,WAAOA,YAAYzD,eAAZ,IAA+B,MAAtC,EAA8C;AAC5C0D,0BAAoBD,YAAYxM,UAAhC;AACAwM,oBAAoBC,iBAApB;AACD;;AAED;AACA,QAAIC,uBAAuB,CAA3B;;AAEA,WAAOF,eAAezO,OAAO2O,oBAAP,CAAtB,EAAoD;AAClDA;AACD;;AAEDlE,UAAMzM,UAAN,GAAmB2Q,oBAAnB;AACD,GAzBD;;AA2BA;;;AAGAlE,QAAMU,oBAAN,GAA6B,YAAY;AACvC,WAAOV,MAAMzM,UAAb;AACD,GAFD;;AAIA;;;AAGAyM,QAAM8C,cAAN,GAAuB,UAAU4C,KAAV,EAAiB;AACtC,QAAInQ,SAAS2H,OAAOzP,KAAP,CAAa8H,MAA1B;AAAA,QACE2Q,YAAY3Q,OAAOmQ,QAAQ,CAAf,CADd;;AAGA,QAAI,CAACQ,SAAL,EAAgB;AACdhJ,aAAOc,IAAP,CAAYjR,GAAZ,CAAgB,wBAAhB;AACA;AACD;;AAED;;;;AAIA,QAAI,CAACmZ,UAAU/Q,UAAV,CAAqBhG,MAA1B,EAAkC;AAChC,UAAIgX,mBAAmBpR,SAAS6B,cAAT,CAAwB,EAAxB,CAAvB;;AAEAsP,gBAAU9V,WAAV,CAAsB+V,gBAAtB;AACD;;AAEDjJ,WAAO8C,KAAP,CAAazM,UAAb,GAA0BmS,QAAQ,CAAlC;AACAxI,WAAO8C,KAAP,CAAayF,GAAb,CAAiBS,SAAjB,EAA4B,CAA5B,EAA+B,CAA/B;AACAhJ,WAAOvJ,OAAP,CAAeuO,kBAAf,CAAkCgE,SAAlC;AACD,GAtBD;;AAwBA;;;;AAIAlG,QAAM6C,UAAN,GAAmB,UAAU6C,KAAV,EAAiB;AAClC,QAAInQ,SAAS2H,OAAOzP,KAAP,CAAa8H,MAA1B;AAAA,QACE6Q,cAAc7Q,OAAOmQ,KAAP,CADhB;;AAGA,QAAK,CAACU,WAAN,EAAoB;AAClB;AACD;;AAED;;;;AAIA,QAAI,CAACA,YAAYjR,UAAZ,CAAuBhG,MAA5B,EAAoC;AAClC,UAAIgX,mBAAmBpR,SAAS6B,cAAT,CAAwB,EAAxB,CAAvB;;AAEAwP,kBAAYhW,WAAZ,CAAwB+V,gBAAxB;AACD;;AAEDjJ,WAAO8C,KAAP,CAAazM,UAAb,GAA0BmS,KAA1B;AACAxI,WAAO8C,KAAP,CAAayF,GAAb,CAAiBW,WAAjB,EAA8B,CAA9B,EAAiC,CAAjC;AACAlJ,WAAOvJ,OAAP,CAAeuO,kBAAf,CAAkCkE,WAAlC;AACD,GArBD;;AAuBA;;;AAGApG,QAAM0E,kBAAN,GAA2B,UAAUgB,KAAV,EAAiB;AAC1CA,YAAQA,SAAS,CAAjB;;AAEA,QAAInQ,SAAS2H,OAAOzP,KAAP,CAAa8H,MAA1B;AAAA,QACE8Q,gBAAgB9Q,OAAOmQ,QAAQ,CAAf,CADlB;AAAA,QAEEY,aAFF;AAAA,QAGEC,qBAHF;AAAA,QAIEJ,gBAJF;;AAOA,QAAI,CAACE,aAAL,EAAoB;AAClBnJ,aAAOc,IAAP,CAAYjR,GAAZ,CAAgB,2BAAhB;AACA;AACD;;AAEDuZ,oBAAgBpJ,OAAOvJ,OAAP,CAAe2Q,8BAAf,CAA8C+B,aAA9C,EAA6DA,cAAclR,UAAd,CAAyBhG,MAAtF,CAAhB;AACAoX,4BAAwBD,cAAcnX,MAAtC;;AAEA;;;;AAIA,QAAI,CAACkX,cAAclR,UAAd,CAAyBhG,MAA9B,EAAsC;AACpCgX,yBAAmBpR,SAAS6B,cAAT,CAAwB,EAAxB,CAAnB;AACAyP,oBAAcjW,WAAd,CAA0B+V,gBAA1B;AACD;AACDjJ,WAAO8C,KAAP,CAAazM,UAAb,GAA0BmS,QAAQ,CAAlC;AACAxI,WAAO8C,KAAP,CAAayF,GAAb,CAAiBY,aAAjB,EAAgCA,cAAclR,UAAd,CAAyBhG,MAAzB,GAAkC,CAAlE,EAAqEoX,qBAArE;AACArJ,WAAOvJ,OAAP,CAAeuO,kBAAf,CAAkC3M,OAAOmQ,QAAQ,CAAf,CAAlC;AACD,GA7BD;;AA+BA1F,QAAMsB,QAAN,GAAiB;;AAEf0D,aAAU,mBAAY;AACpB,UAAIlL,YAAkBvI,OAAO2P,YAAP,EAAtB;AAAA,UACEqD,eAAkBzK,UAAUyK,YAD9B;AAAA,UAEEnD,aAAkBtH,UAAUsH,UAF9B;AAAA,UAGEsB,kBAAkBxF,OAAOvJ,OAAP,CAAeiP,kBAAf,CAAkCxB,UAAlC,CAHpB;AAAA,UAIEoF,gBAAkB9D,gBAAgBvN,UAAhB,CAA2B,CAA3B,CAJpB;;AAMA,UAAI,CAAC+H,OAAOc,IAAP,CAAYsF,SAAZ,CAAsBlC,UAAtB,CAAL,EAAwC;AACtCA,qBAAaA,WAAW5J,UAAxB;AACD;;AAED,UAAIiP,cAAerF,eAAeoF,cAAcrR,UAAd,CAAyB,CAAzB,CAAlC;AAAA,UACEuR,eAAenC,iBAAiB,CADlC;;AAGA,aAAOkC,eAAeC,YAAtB;AACD,KAjBc;;AAmBfnF,cAAW,oBAAY;AACrB,UAAIzH,YAAevI,OAAO2P,YAAP,EAAnB;AAAA,UACEqD,eAAezK,UAAUyK,YAD3B;AAAA,UAEEnD,aAAetH,UAAUsH,UAF3B;;AAIA;AACA,aAAO,CAACA,UAAD,IAAe,CAACA,WAAWjS,MAA3B,IAAqCoV,iBAAiBnD,WAAWjS,MAAxE;AACD;AA1Bc,GAAjB;;AA8BA;;;;AAIA6Q,QAAM2G,UAAN,GAAmB,UAAU/O,IAAV,EAAgB;AACjC,QAAIkC,SAAJ;AAAA,QAAeF,KAAf;AAAA,QACEgN,WAAWhP,IADb;;AAGA,QAAIA,KAAKI,QAAL,IAAiBkF,OAAOc,IAAP,CAAY2D,SAAZ,CAAsBkF,iBAA3C,EAA8D;AAC5DD,iBAAWhP,KAAKwM,SAAhB;AACD;;AAEDtK,gBAAYvI,OAAO2P,YAAP,EAAZ;;AAEAtH,YAAQE,UAAUgN,UAAV,CAAqB,CAArB,CAAR;AACAlN,UAAMmN,cAAN;;AAEAnN,UAAM+M,UAAN,CAAiB/O,IAAjB;;AAEAgC,UAAMoN,aAAN,CAAoBJ,QAApB;AACAhN,UAAMqN,QAAN,CAAe,IAAf;;AAEAnN,cAAUkM,eAAV;AACAlM,cAAUmM,QAAV,CAAmBrM,KAAnB;AACD,GApBD;;AAsBA,SAAOoG,KAAP;AACD,CApPgB,CAoPd,EApPc,CAAjB,C;;;;;;;;;;;;;;qjBCPA;;;;;;;;;;;AAWA;;;;;;;;AAEA/T,OAAO+Q,OAAP;AAAA;AAAA;;AACE;;;;AADF,wBAKoB;AAChB,aAAO,SAAP;AACD;;AAED;;;;;;AATF;;AAcE,mBAAY7Q,MAAZ,EAAoB;AAAA;;AAClB,SAAKA,MAAL,GAAcA,MAAd;AACA,SAAKoD,MAAL,GAAc,IAAd;;AAEA,SAAKG,GAAL,GAAW;AACT2Q,aAAO,UADE;AAET1M,eAAS,mBAFA;AAGTuT,iBAAW,qBAHF;AAITC,mBAAa;AAJJ,KAAX;;AAOA,SAAKC,YAAL,GAAoB,IAApB;AACA,SAAKC,aAAL,GAAqB,CAArB;AACD;;AAED;;;;;;AA7BF;AAAA;;;AA0DE;;;;;;;AA1DF,kCAiEgBC,UAjEhB,EAiEiD;AAAA,UAArBC,WAAqB,uEAAP,KAAO;;AAC7C,UAAIlH,QAAYnQ,cAAEC,IAAF,CAAO,KAAP,EAAc,KAAKT,GAAL,CAAS2Q,KAAvB,CAAhB;AAAA,UACEmH,eAAetX,cAAEC,IAAF,CAAO,KAAP,EAAc,KAAKT,GAAL,CAASiE,OAAvB,CADjB;;AAGA6T,mBAAapX,WAAb,CAAyBkX,UAAzB;AACAjH,YAAMjQ,WAAN,CAAkBoX,YAAlB;;AAEA,UAAID,WAAJ,EAAiB;AACfC,qBAAazW,SAAb,CAAuBC,GAAvB,CAA2B,KAAKtB,GAAL,CAASwX,SAApC;AACD;;AAED7G,YAAM9C,OAAN,CAAckK,MAAd,GAAuB,KAAKJ,aAAL,EAAvB;;AAEA,aAAOhH,KAAP;AACD;AA/EH;AAAA;;;AAiFE;;;;;;;;;AAjFF,uCA0FqBzI,IA1FrB,EA0F2B;AACvB,UAAI,CAAC1H,cAAEsI,SAAF,CAAYZ,IAAZ,CAAL,EAAwB;AACtBA,eAAOA,KAAKJ,UAAZ;AACD;;AAED,UAAII,SAAS,KAAKrI,MAAL,CAAYqO,EAAZ,CAAe7N,KAAf,CAAqBmV,QAA9B,IAA0CtN,SAAS7C,SAASwO,IAAhE,EAAsE;AACpE,eAAO,IAAP;AACD,OAFD,MAEO;AACL,eAAM3L,KAAK7G,SAAL,IAAkB,CAAC6G,KAAK7G,SAAL,CAAe2S,QAAf,CAAwB,KAAKhU,GAAL,CAAS2Q,KAAjC,CAAzB,EAAkE;AAChEzI,iBAAOA,KAAKJ,UAAZ;AACD;;AAED,eAAOI,IAAP;AACD;AACF;AAxGH;AAAA;;;AA0GE;;;;;;;;AA1GF,gCAkHcvE,IAlHd,EAkHoB;AAChB,UAAIqU,WAAW,KAAKC,aAAL,CAAmBtU,IAAnB,CAAf;;AAEA,UAAI,KAAK+J,WAAT,EAAsB;AACpB,aAAKA,WAAL,CAAiBwK,qBAAjB,CAAuC,UAAvC,EAAmDF,QAAnD;AACD,OAFD,MAEO;AACL;;;AAGA,aAAKnY,MAAL,CAAYqO,EAAZ,CAAe7N,KAAf,CAAqBmV,QAArB,CAA8B9U,WAA9B,CAA0CsX,QAA1C;AACD;;AAED;;;AAGA,WAAKtK,WAAL,GAAmBsK,QAAnB;;AAEA,aAAOA,SAASnK,OAAT,CAAiBkK,MAAxB;AACD;AApIH;AAAA;AAAA,sBAiCYlY,MAjCZ,EAiCoB;AAChB,WAAKA,MAAL,GAAcA,MAAd;AACD;;AAED;;;;;;AArCF;AAAA;AAAA,wBA0CoB;AAChB,aAAO,KAAK6X,YAAZ;AACD;;AAED;;;;;AA9CF;AAAA,sBAmDkBxP,IAnDlB,EAmDwB;AACpB,UAAI8K,kBAAkB,KAAKE,kBAAL,CAAwBhL,IAAxB,CAAtB;;AAEA,WAAKwP,YAAL,GAAoB1E,eAApB;AACD;AAvDH;;AAAA;AAAA;;AAuIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,U;;;;;;;;;;;;;;;;AC56BA;;;;;;;AAOAzW,OAAO+Q,OAAP,GAAiB,UAAU6K,SAAV,EAAqB;AACpC,MAAI3K,SAASC,MAAMD,MAAnB;;AAEA2K,YAAUC,WAAV,GAAwB,YAAY;AAClC5K,WAAOnN,KAAP,CAAaJ,OAAb,CAAqB8B,MAArB;AACAyL,WAAOnN,KAAP,CAAagY,aAAb,CAA2BtW,MAA3B;AACD,GAHD;;AAKAoW,YAAUG,cAAV,GAA2B,YAAY;AACrC,SAAK,IAAI3U,IAAT,IAAiB6J,OAAOnO,KAAxB,EAA+B;AAC7B,UAAI,OAAOmO,OAAOnO,KAAP,CAAasE,IAAb,EAAmB4U,OAA1B,KAAsC,UAA1C,EAAsD;AACpD/K,eAAOnO,KAAP,CAAasE,IAAb,EAAmB4U,OAAnB;AACD;AACF;AACF,GAND;;AAQAJ,YAAUK,cAAV,GAA2B,YAA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AC;AAHL,OAAP;AAKD;;;;EA5DgC5qB,M;;AA+DnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;kBA5NqB8hB,K;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtBrB;;;;;;;;;;;IAWqB+I,a;;;AACnB;;;AAGA,+BAAsB;AAAA,QAAT/rB,MAAS,QAATA,MAAS;;AAAA;;AAAA,8HACd,EAACA,cAAD,EADc;;AAGpB,UAAK4D,KAAL,GAAa;AACXJ,eAAS,IADE;AAEXwoB,oBAAc,IAFH;AAGXC,uBAAiB;AAHN,KAAb;AAHoB;AAQrB;;AAED;;;;;;;;;;AA2BA;;;;;;;2BAOO;AACL,WAAKroB,KAAL,CAAWJ,OAAX,GAAqBO,EAAEC,IAAF,CAAO,KAAP,EAAc+nB,cAAcxoB,GAAd,CAAkBC,OAAhC,C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AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;kBA5gBqBW,E;;;;;;;;;;;;;;;;AC9BrB;;;;;AAKA,IAAI,CAACi1B,QAAQC,SAAR,CAAkBC,OAAvB,EACEF,QAAQC,SAAR,CAAkBC,OAAlB,GAA4BF,QAAQC,SAAR,CAAkBE,iBAAlB,IACtBH,QAAQC,SAAR,CAAkBG,qBADxB;;AAGF,IAAI,CAACJ,QAAQC,SAAR,CAAkB/Q,OAAvB,EACE8Q,QAAQC,SAAR,CAAkB/Q,OAAlB,GAA4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","file":"codex-editor.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"CodexEditor\"] = factory();\n\telse\n\t\troot[\"CodexEditor\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/codex.js\");\n","module.exports = \"\\n\\n\\r\\n \\r\\n\\n\\n\\r\\n \\r\\n\\n\\n\\r\\n \\r\\n\\n\\n\\r\\n \\r\\n\\n\\n\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n\\n\\n\\r\\n \\r\\n\\n\\n\\r\\n \\r\\n\\n\\n\\r\\n \\r\\n\\n\\n\\r\\n \\r\\n\\n\"","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\nmodule.exports = function(useSourceMap) {\n\tvar list = [];\n\n\t// return the list of modules as css string\n\tlist.toString = function toString() {\n\t\treturn this.map(function (item) {\n\t\t\tvar content = cssWithMappingToString(item, useSourceMap);\n\t\t\tif(item[2]) {\n\t\t\t\treturn \"@media \" + item[2] + \"{\" + content + \"}\";\n\t\t\t} else {\n\t\t\t\treturn content;\n\t\t\t}\n\t\t}).join(\"\");\n\t};\n\n\t// import a list of modules into the list\n\tlist.i = function(modules, mediaQuery) {\n\t\tif(typeof modules === \"string\")\n\t\t\tmodules = [[null, modules, \"\"]];\n\t\tvar alreadyImportedModules = {};\n\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\tvar id = this[i][0];\n\t\t\tif(typeof id === \"number\")\n\t\t\t\talreadyImportedModules[id] = true;\n\t\t}\n\t\tfor(i = 0; i < modules.length; i++) {\n\t\t\tvar item = modules[i];\n\t\t\t// skip already imported module\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\n\t\t\t// when a module is imported multiple times with different media queries.\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\n\t\t\t\tif(mediaQuery && !item[2]) {\n\t\t\t\t\titem[2] = mediaQuery;\n\t\t\t\t} else if(mediaQuery) {\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\n\t\t\t\t}\n\t\t\t\tlist.push(item);\n\t\t\t}\n\t\t}\n\t};\n\treturn list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n\tvar content = item[1] || '';\n\tvar cssMapping = item[3];\n\tif (!cssMapping) {\n\t\treturn content;\n\t}\n\n\tif (useSourceMap && typeof btoa === 'function') {\n\t\tvar sourceMapping = toComment(cssMapping);\n\t\tvar sourceURLs = cssMapping.sources.map(function (source) {\n\t\t\treturn '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'\n\t\t});\n\n\t\treturn [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n\t}\n\n\treturn [content].join('\\n');\n}\n\n// Adapted from convert-source-map (MIT)\nfunction toComment(sourceMap) {\n\t// eslint-disable-next-line no-undef\n\tvar base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n\tvar data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;\n\n\treturn '/*# ' + data + ' */';\n}\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 var sandbox = document.createElement('div');\n sandbox.innerHTML = html;\n\n this._sanitize(sandbox);\n\n return sandbox.innerHTML;\n };\n\n HTMLJanitor.prototype._sanitize = function (parentNode) {\n var treeWalker = createTreeWalker(parentNode);\n var node = treeWalker.firstChild();\n if (!node) { return; }\n\n do {\n // Ignore nodes that have already been sanitized\n if (node._sanitized) {\n continue;\n }\n\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(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(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.
  • ...); 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(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(node);\n\n // Mark node as sanitized so it's ignored in future runs\n node._sanitized = true;\n } while ((node = treeWalker.nextSibling()));\n };\n\n function createTreeWalker(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","/**\r\n * Codex Editor\r\n *\r\n * Short Description (눈_눈;)\r\n * @version 2.0.0\r\n *\r\n * How to start?\r\n * Example:\r\n * new CodexEditor({\r\n * holderId : 'codex-editor',\r\n * initialBlock : 'text',\r\n * placeholder : 'Write your story....',\r\n * tools: {\r\n * quote: Quote,\r\n * anotherTool : AnotherTool\r\n * },\r\n * toolsConfig: {\r\n * quote: {\r\n * iconClassname : 'quote-icon',\r\n * displayInToolbox : true,\r\n * enableLineBreaks : true\r\n * },\r\n * anotherTool: {\r\n * iconClassname : 'tool-icon'\r\n * }\r\n * }\r\n * });\r\n *\r\n * - tools is an object: {\r\n * pluginName: PluginClass,\r\n * .....\r\n * }\r\n * - toolsConfig is an additional configuration that uses Codex Editor API\r\n * iconClassname - CSS classname of toolbox icon\r\n * displayInToolbox - if you want to see your Tool in toolbox hided in \"plus\" button, than set \"True\". By default : \"False\"\r\n * enableLineBreaks - by default enter creates new block that set as initialblock, but if you set this property \"True\", enter will break the lines in current block\r\n *\r\n * @author CodeX-Team \r\n *\r\n */\r\n\r\n/**\r\n * @typedef {CodexEditor} CodexEditor - editor class\r\n */\r\n\r\n/**\r\n * @typedef {Object} EditorConfig\r\n * @property {String} holderId - Element to append Editor\r\n * @property {Array} data - Blocks list in JSON-format\r\n * @property {Object} tools - Map for used Tools in format { name : Class, ... }\r\n * @property {String} initialBlock - This Tool will be added by default\r\n * @property {String} placeholder - First Block placeholder\r\n * @property {Object} sanitizer - @todo fill desc\r\n * @property {Boolean} hideToolbar - @todo fill desc\r\n * @property {Object} toolsConfig - tools configuration {@link tools#ToolConfig}\r\n */\r\n\r\n/**\r\n * Dynamically imported utils\r\n *\r\n * @typedef {Dom} $ - {@link components/dom.js}\r\n * @typedef {Util} _ - {@link components/utils.js}\r\n */\r\n\r\n'use strict';\r\n\r\n/**\r\n * Apply polyfills\r\n */\r\nimport 'components/polyfills';\r\n\r\n/**\r\n * Require Editor modules places in components/modules dir\r\n */\r\n// eslint-disable-next-line\r\nlet modules = editorModules.map( module => require('./components/modules/' + module ));\r\n\r\n/**\r\n * @class\r\n *\r\n * @classdesc CodeX Editor base class\r\n *\r\n * @property this.config - all settings\r\n * @property this.moduleInstances - constructed editor components\r\n *\r\n * @type {CodexEditor}\r\n */\r\nexport default class CodexEditor {\r\n /** Editor version */\r\n static get version() {\r\n return VERSION;\r\n }\r\n\r\n /**\r\n * @param {EditorConfig} config - user configuration\r\n *\r\n */\r\n constructor(config) {\r\n /**\r\n * Configuration object\r\n * @type {EditorConfig}\r\n */\r\n this.config = {};\r\n\r\n /**\r\n * @typedef {Object} EditorComponents\r\n * @property {BlockManager} BlockManager\r\n * @property {Tools} Tools\r\n * @property {Events} Events\r\n * @property {UI} UI\r\n * @property {Toolbar} Toolbar\r\n * @property {Toolbox} Toolbox\r\n * @property {BlockSettings} BlockSettings\r\n * @property {Renderer} Renderer\r\n * @property {InlineToolbar} InlineToolbar\r\n */\r\n this.moduleInstances = {};\r\n\r\n Promise.resolve()\r\n .then(() => {\r\n this.configuration = config;\r\n })\r\n .then(() => this.init())\r\n .then(() => this.start())\r\n .then(() => {\r\n let methods = this.moduleInstances.API.methods;\r\n\r\n /**\r\n * Make API methods available from inside easier\r\n */\r\n for (let method in methods) {\r\n this[method] = methods[method];\r\n }\r\n\r\n // todo Is it necessary?\r\n delete this.moduleInstances;\r\n })\r\n .then(() => {\r\n console.log('CodeX Editor is ready!');\r\n })\r\n .catch(error => {\r\n console.log('CodeX Editor does not ready because of %o', error);\r\n });\r\n }\r\n\r\n /**\r\n * Setting for configuration\r\n * @param {EditorConfig} config\r\n */\r\n set configuration(config) {\r\n /**\r\n * Initlai block type\r\n * Uses in case when there is no items passed\r\n * @type {{type: (*), data: {text: null}}}\r\n */\r\n let initialBlock = {\r\n type : config.initialBlock,\r\n data : {}\r\n };\r\n\r\n this.config.holderId = config.holderId;\r\n this.config.placeholder = config.placeholder || 'write your story...';\r\n this.config.sanitizer = config.sanitizer || {\r\n p: true,\r\n b: true,\r\n a: true\r\n };\r\n\r\n this.config.hideToolbar = config.hideToolbar ? config.hideToolbar : false;\r\n this.config.tools = config.tools || {};\r\n this.config.toolsConfig = config.toolsConfig || {};\r\n this.config.data = config.data || {};\r\n\r\n /**\r\n * Initialize items to pass data to the Renderer\r\n */\r\n if (_.isEmpty(this.config.data)) {\r\n this.config.data = {};\r\n this.config.data.items = [ initialBlock ];\r\n } else {\r\n if (!this.config.data.items || this.config.data.items.length === 0) {\r\n this.config.data.items = [ initialBlock ];\r\n }\r\n }\r\n\r\n /**\r\n * If initial Block's Tool was not passed, use the first Tool in config.tools\r\n */\r\n if (!config.initialBlock) {\r\n for (this.config.initialBlock in this.config.tools) break;\r\n } else {\r\n this.config.initialBlock = config.initialBlock;\r\n }\r\n }\r\n\r\n /**\r\n * Returns private property\r\n * @returns {EditorConfig}\r\n */\r\n get configuration() {\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Initializes modules:\r\n * - make and save instances\r\n * - configure\r\n */\r\n init() {\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 * Make modules instances and save it to the @property this.moduleInstances\r\n */\r\n constructModules() {\r\n modules.forEach( Module => {\r\n try {\r\n /**\r\n * We use class name provided by displayName property\r\n *\r\n * On build, Babel will transform all Classes to the Functions so, name will always be 'Function'\r\n * To prevent this, we use 'babel-plugin-class-display-name' plugin\r\n * @see https://www.npmjs.com/package/babel-plugin-class-display-name\r\n */\r\n this.moduleInstances[Module.displayName] = new Module({\r\n config : this.configuration\r\n });\r\n } catch ( e ) {\r\n console.log('Module %o skipped because %o', Module, 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 configureModules() {\r\n for(let name in this.moduleInstances) {\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 * Return modules without passed name\r\n */\r\n getModulesDiff( name ) {\r\n let diff = {};\r\n\r\n for(let 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 /**\r\n * Start Editor!\r\n *\r\n * Get list of modules that needs to be prepared and return a sequence (Promise)\r\n * @return {Promise}\r\n */\r\n start() {\r\n let prepareDecorator = module => module.prepare();\r\n\r\n return Promise.resolve()\r\n .then(prepareDecorator(this.moduleInstances.Tools))\r\n .then(prepareDecorator(this.moduleInstances.UI))\r\n .then(prepareDecorator(this.moduleInstances.BlockManager))\r\n .then(() => {\r\n return this.moduleInstances.Renderer.render(this.config.data.items);\r\n });\r\n }\r\n};\r\n\r\n// module.exports = (function (editor) {\r\n//\r\n// 'use strict';\r\n//\r\n// editor.version = VERSION;\r\n// editor.scriptPrefix = 'cdx-script-';\r\n//\r\n// var init = function () {\r\n//\r\n// editor.core = require('./modules/core');\r\n// editor.tools = require('./modules/tools');\r\n// editor.ui = require('./modules/ui');\r\n// editor.transport = require('./modules/transport');\r\n// editor.renderer = require('./modules/renderer');\r\n// editor.saver = require('./modules/saver');\r\n// editor.content = require('./modules/content');\r\n// editor.toolbar = require('./modules/toolbar/toolbar');\r\n// editor.callback = require('./modules/callbacks');\r\n// editor.draw = require('./modules/draw');\r\n// editor.caret = require('./modules/caret');\r\n// editor.notifications = require('./modules/notifications');\r\n// editor.parser = require('./modules/parser');\r\n// editor.sanitizer = require('./modules/sanitizer');\r\n// editor.listeners = require('./modules/listeners');\r\n// editor.destroyer = require('./modules/destroyer');\r\n// editor.paste = require('./modules/paste');\r\n//\r\n// };\r\n//\r\n// /**\r\n// * @public\r\n// * holds initial settings\r\n// */\r\n// editor.settings = {\r\n// tools : ['text', 'header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'],\r\n// holderId : 'codex-editor',\r\n//\r\n// // Type of block showing on empty editor\r\n// initialBlockPlugin: 'text'\r\n// };\r\n//\r\n// /**\r\n// * public\r\n// *\r\n// * Static nodes\r\n// */\r\n// editor.nodes = {\r\n// holder : null,\r\n// wrapper : null,\r\n// toolbar : null,\r\n// inlineToolbar : {\r\n// wrapper : null,\r\n// buttons : null,\r\n// actions : null\r\n// },\r\n// toolbox : null,\r\n// notifications : null,\r\n// plusButton : null,\r\n// showSettingsButton: null,\r\n// showTrashButton : null,\r\n// blockSettings : null,\r\n// pluginSettings : null,\r\n// defaultSettings : null,\r\n// toolbarButtons : {}, // { type : DomEl, ... }\r\n// redactor : null\r\n// };\r\n//\r\n// /**\r\n// * @public\r\n// *\r\n// * Output state\r\n// */\r\n// editor.state = {\r\n// jsonOutput : [],\r\n// blocks : [],\r\n// inputs : []\r\n// };\r\n//\r\n// /**\r\n// * @public\r\n// * Editor plugins\r\n// */\r\n// editor.tools = {};\r\n//\r\n// editor.start = function (userSettings) {\r\n//\r\n// init();\r\n//\r\n// editor.core.prepare(userSettings)\r\n//\r\n// // If all ok, make UI, bind events and parse initial-content\r\n// .then(editor.ui.prepare)\r\n// .then(editor.tools.prepare)\r\n// .then(editor.sanitizer.prepare)\r\n// .then(editor.paste.prepare)\r\n// .then(editor.transport.prepare)\r\n// .then(editor.renderer.makeBlocksFromData)\r\n// .then(editor.ui.saveInputs)\r\n// .catch(function (error) {\r\n//\r\n// editor.core.log('Initialization failed with error: %o', 'warn', error);\r\n//\r\n// });\r\n//\r\n// };\r\n//\r\n// return editor;\r\n//\r\n// })({});\r\n","/**\r\n * @abstract\r\n * @class Module\r\n * @classdesc All modules inherits from this class.\r\n *\r\n * @typedef {Module} Module\r\n * @property {Object} config - Editor user settings\r\n * @property {IEditorConfig} Editor - List of Editor modules\r\n */\r\nexport default class Module {\r\n /**\r\n * @constructor\r\n * @param {IModuleConfig}\r\n */\r\n constructor({ config }) {\r\n if (new.target === Module) {\r\n throw new TypeError('Constructors for abstract class Module are not allowed.');\r\n }\r\n this.config = config;\r\n }\r\n /**\r\n * Editor modules setter\r\n * @param {IEditor} Editor\r\n */\r\n set state(Editor) {\r\n this.Editor = Editor;\r\n }\r\n}\r\n","export default class DeleteTune {\r\n /**\r\n * DeleteTune constructor\r\n *\r\n * @param {Object} api\r\n */\r\n constructor({ api }) {\r\n /**\r\n * Styles\r\n * @type {{wrapper: string}}\r\n */\r\n this.CSS = {\r\n wrapper: 'ass',\r\n button: 'ce-settings__button',\r\n buttonDelete: 'ce-settings__button--delete',\r\n buttonConfirm: 'ce-settings__button--confirm',\r\n };\r\n /**\r\n * Tune nodes\r\n */\r\n this.nodes = {\r\n button: null,\r\n };\r\n this.api = api;\r\n this.resetConfirmation = () => {\r\n this.setConfirmation(false);\r\n };\r\n }\r\n /**\r\n * Create \"Delete\" button and add click event listener\r\n * @returns [Element}\r\n */\r\n render() {\r\n this.nodes.button = $.make('div', [this.CSS.button, this.CSS.buttonDelete], {});\r\n this.nodes.button.appendChild($.svg('cross', 12, 12));\r\n this.api.listener.on(this.nodes.button, 'click', (event) => this.handleClick(event), false);\r\n return this.nodes.button;\r\n }\r\n /**\r\n * Delete block conditions passed\r\n * @param {MouseEvent} event\r\n */\r\n handleClick(event) {\r\n /**\r\n * if block is not waiting the confirmation, subscribe on block-settings-closing event to reset\r\n * otherwise delete block\r\n */\r\n if (!this.needConfirmation) {\r\n this.setConfirmation(true);\r\n /**\r\n * Subscribe on event.\r\n * When toolbar block settings is closed but block deletion is not confirmed,\r\n * then reset confirmation state\r\n */\r\n this.api.events.on('block-settings-closed', this.resetConfirmation);\r\n }\r\n else {\r\n /**\r\n * Unsubscribe from block-settings closing event\r\n */\r\n this.api.events.off('block-settings-closed', this.resetConfirmation);\r\n this.api.blocks.delete();\r\n }\r\n }\r\n /**\r\n * change tune state\r\n */\r\n setConfirmation(state) {\r\n this.needConfirmation = state;\r\n this.nodes.button.classList.add(this.CSS.buttonConfirm);\r\n }\r\n}\r\n","export default class MoveDownTune {\r\n /**\r\n * MoveDownTune constructor\r\n *\r\n * @param {Object} api\r\n */\r\n constructor({ api }) {\r\n /**\r\n * Styles\r\n * @type {{wrapper: string}}\r\n */\r\n this.CSS = {\r\n button: 'ce-settings__button',\r\n wrapper: 'ce-tune-move-down',\r\n animation: 'wobble',\r\n };\r\n this.api = api;\r\n }\r\n /**\r\n * Return 'move down' button\r\n */\r\n render() {\r\n const moveDownButton = $.make('div', [this.CSS.button, this.CSS.wrapper], {});\r\n moveDownButton.appendChild($.svg('arrow-down', 14, 14));\r\n this.api.listener.on(moveDownButton, 'click', (event) => this.handleClick(event, moveDownButton), false);\r\n return moveDownButton;\r\n }\r\n /**\r\n * Handle clicks on 'move down' button\r\n * @param {MouseEvent} event\r\n * @param {HTMLElement} button\r\n */\r\n handleClick(event, button) {\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n // If Block is last do nothing\r\n if (currentBlockIndex === this.api.blocks.getBlocksCount() - 1) {\r\n button.classList.add(this.CSS.animation);\r\n window.setTimeout(() => {\r\n button.classList.remove(this.CSS.animation);\r\n }, 500);\r\n return;\r\n }\r\n const nextBlockElement = this.api.blocks.getBlockByIndex(currentBlockIndex + 1).holder, nextBlockCoords = nextBlockElement.getBoundingClientRect();\r\n let scrollOffset = Math.abs(window.innerHeight - nextBlockElement.offsetHeight);\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 window.scrollTo(0, scrollOffset);\r\n /** Change blocks positions */\r\n this.api.blocks.swap(currentBlockIndex, currentBlockIndex + 1);\r\n }\r\n}\r\n","export default class MoveUpTune {\r\n /**\r\n * MoveUpTune constructor\r\n *\r\n * @param {Object} api\r\n */\r\n constructor({ api }) {\r\n /**\r\n * Styles\r\n * @type {{wrapper: string}}\r\n */\r\n this.CSS = {\r\n button: 'ce-settings__button',\r\n wrapper: 'ce-tune-move-up',\r\n animation: 'wobble',\r\n };\r\n this.api = api;\r\n }\r\n /**\r\n * Create \"MoveUp\" button and add click event listener\r\n * @returns [Element}\r\n */\r\n render() {\r\n const moveUpButton = $.make('div', [this.CSS.button, this.CSS.wrapper], {});\r\n moveUpButton.appendChild($.svg('arrow-up', 14, 14));\r\n this.api.listener.on(moveUpButton, 'click', (event) => this.handleClick(event, moveUpButton), false);\r\n return moveUpButton;\r\n }\r\n /**\r\n * Move current block up\r\n * @param {MouseEvent} event\r\n * @param {HTMLElement} button\r\n */\r\n handleClick(event, button) {\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n if (currentBlockIndex === 0) {\r\n button.classList.add(this.CSS.animation);\r\n window.setTimeout(() => {\r\n button.classList.remove(this.CSS.animation);\r\n }, 500);\r\n return;\r\n }\r\n const currentBlockElement = this.api.blocks.getBlockByIndex(currentBlockIndex).holder, previousBlockElement = this.api.blocks.getBlockByIndex(currentBlockIndex - 1).holder;\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(), previousBlockCoords = previousBlockElement.getBoundingClientRect();\r\n let scrollUpOffset;\r\n if (previousBlockCoords.top > 0) {\r\n scrollUpOffset = Math.abs(currentBlockCoords.top) - Math.abs(previousBlockCoords.top);\r\n }\r\n else {\r\n scrollUpOffset = window.innerHeight - Math.abs(currentBlockCoords.top) + Math.abs(previousBlockCoords.top);\r\n }\r\n window.scrollBy(0, -1 * scrollUpOffset);\r\n /** Change blocks positions */\r\n this.api.blocks.swap(currentBlockIndex, currentBlockIndex - 1);\r\n }\r\n}\r\n","/**\n * @class Block\n * @classdesc This class describes editor`s block, including block`s HTMLElement, data and tool\n *\n * @property {Tool} tool — current block tool (Paragraph, for example)\n * @property {Object} CSS — block`s css classes\n *\n */\n\n/** Import default tunes */\nimport MoveUpTune from './block-tunes/block-tune-move-up';\nimport DeleteTune from './block-tunes/block-tune-delete';\nimport MoveDownTune from './block-tunes/block-tune-move-down';\n\n/**\n * @classdesc Abstract Block class that contains Block information, Tool name and Tool class instance\n *\n * @property tool - Tool instance\n * @property html - Returns HTML content of plugin\n * @property holder - Div element that wraps block content with Tool's content. Has `ce-block` CSS class\n * @property pluginsContent - HTML content that returns by Tool's render function\n */\nexport default class Block {\n /**\n * @constructor\n * @param {String} toolName - Tool name that passed on initialization\n * @param {Object} toolInstance — passed Tool`s instance that rendered the Block\n * @param {Object} settings - default settings\n * @param {Object} apiMethods - Editor API\n */\n constructor(toolName, toolInstance, settings, apiMethods) {\n this.name = toolName;\n this.tool = toolInstance;\n this.settings = settings;\n this.api = apiMethods;\n this.holder = this.compose();\n this.inputIndex = 0;\n\n /**\n * @type {IBlockTune[]}\n */\n this.tunes = this.makeTunes();\n }\n\n /**\n * CSS classes for the Block\n * @return {{wrapper: string, content: string}}\n */\n static get CSS() {\n return {\n wrapper: 'ce-block',\n content: 'ce-block__content',\n selected: 'ce-block--selected'\n };\n }\n\n /**\n * Make default Block wrappers and put Tool`s content there\n * @returns {HTMLDivElement}\n */\n compose() {\n let wrapper = $.make('div', Block.CSS.wrapper),\n contentNode = $.make('div', Block.CSS.content),\n pluginsContent = this.tool.render();\n\n contentNode.appendChild(pluginsContent);\n wrapper.appendChild(contentNode);\n return wrapper;\n }\n\n /**\n * Calls Tool's method\n *\n * Method checks tool property {MethodName}. Fires method with passes params If it is instance of Function\n *\n * @param {String} methodName\n * @param {Object} params\n */\n call(methodName, params) {\n /**\n * call Tool's method with the instance context\n */\n if (this.tool[methodName] && this.tool[methodName] instanceof Function) {\n this.tool[methodName].call(this.tool, params);\n }\n }\n\n /**\n * Returns Plugins content\n * @return {Node}\n */\n get pluginsContent() {\n let pluginsContent = this.holder.querySelector(`.${Block.CSS.content}`);\n\n if (pluginsContent && pluginsContent.childNodes.length) {\n return pluginsContent.childNodes[0];\n }\n\n return null;\n }\n\n /**\n * Get Block's JSON data\n * @return {Object}\n */\n get data() {\n return this.save();\n }\n\n get inputs() {\n const collection = this.holder.querySelectorAll('[contenteditable], input, textarea');\n\n return _.array(collection);\n }\n\n get nextInput() {\n const inputs = this.inputs;\n\n this.inputIndex = Math.min(inputs.length - 1, this.inputIndex + 1);\n\n return inputs[this.inputIndex];\n }\n\n get previousInput() {\n this.inputIndex = Math.max(0, this.inputIndex - 1);\n\n return this.inputs[this.inputIndex];\n }\n\n /**\n * is block mergeable\n * We plugin have merge function then we call it mergable\n * @return {boolean}\n */\n get mergeable() {\n return typeof this.tool.merge === 'function';\n }\n\n /**\n * Call plugins merge method\n * @param {Object} data\n */\n mergeWith(data) {\n return Promise.resolve()\n .then(() => {\n this.tool.merge(data);\n });\n }\n /**\n * Extracts data from Block\n * Groups Tool's save processing time\n * @return {Object}\n */\n save() {\n let extractedBlock = this.tool.save(this.pluginsContent);\n\n /** Measuring execution time*/\n let measuringStart = window.performance.now(),\n measuringEnd;\n\n return Promise.resolve(extractedBlock)\n .then((finishedExtraction) => {\n /** measure promise execution */\n measuringEnd = window.performance.now();\n\n return {\n tool: this.name,\n data: finishedExtraction,\n time : measuringEnd - measuringStart\n };\n })\n .catch(function (error) {\n _.log(`Saving proccess for ${this.tool.name} tool failed due to the ${error}`, 'log', 'red');\n });\n }\n\n /**\n * Uses Tool's validation method to check the correctness of output data\n * Tool's validation method is optional\n *\n * @description Method also can return data if it passed the validation\n *\n * @param {Object} data\n * @returns {Boolean|Object} valid\n */\n validateData(data) {\n let isValid = true;\n\n if (this.tool.validate instanceof Function) {\n isValid = this.tool.validate(data);\n }\n\n if (!isValid) {\n return false;\n }\n\n return data;\n }\n\n /**\n * Make an array with default settings\n * Each block has default tune instance that have states\n * @return {IBlockTune[]}\n */\n makeTunes() {\n let tunesList = [MoveUpTune, DeleteTune, MoveDownTune];\n\n // Pluck tunes list and return tune instances with passed Editor API and settings\n return tunesList.map( (tune) => {\n return new tune({\n api: this.api,\n settings: this.settings,\n });\n });\n }\n\n /**\n * Enumerates initialized tunes and returns fragment that can be appended to the toolbars area\n * @return {DocumentFragment}\n */\n renderTunes() {\n let tunesElement = document.createDocumentFragment();\n\n this.tunes.forEach( tune => {\n $.append(tunesElement, tune.render());\n });\n\n return tunesElement;\n }\n\n /**\n * Check block for emptiness\n * @return {Boolean}\n */\n get isEmpty() {\n /**\n * Allow Tool to represent decorative contentless blocks: for example \"* * *\"-tool\n * That Tools are not empty\n */\n if (this.tool.contentless) {\n return false;\n }\n\n let emptyText = $.isEmpty(this.pluginsContent),\n emptyMedia = !this.hasMedia;\n\n return emptyText && emptyMedia;\n }\n\n /**\n * Check if block has a media content such as images, iframes and other\n * @return {Boolean}\n */\n get hasMedia() {\n /**\n * This tags represents media-content\n * @type {string[]}\n */\n const mediaTags = [\n 'img',\n 'iframe',\n 'video',\n 'audio',\n 'source',\n 'input',\n 'textarea',\n 'twitterwidget'\n ];\n\n return !!this.holder.querySelector(mediaTags.join(','));\n }\n\n /**\n * Set selected state\n * @param {Boolean} state - 'true' to select, 'false' to remove selection\n */\n set selected(state) {\n /**\n * We don't need to mark Block as Selected when it is not empty\n */\n if (state === true && !this.isEmpty) {\n this.holder.classList.add(Block.CSS.selected);\n } else {\n this.holder.classList.remove(Block.CSS.selected);\n }\n }\n}\n","/**\r\n * DOM manipulations helper\r\n */\r\nexport default class Dom {\r\n /**\r\n * Check if passed tag has no closed tag\r\n * @param {Element} tag\r\n * @return {Boolean}\r\n */\r\n static isSingleTag(tag) {\r\n return tag.tagName && ['AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR'].includes(tag.tagName);\r\n };\r\n\r\n\r\n /**\r\n * Helper for making Elements with classname and attributes\r\n *\r\n * @param {string} tagName - new Element tag name\r\n * @param {array|string} classNames - list or name of CSS classname(s)\r\n * @param {Object} attributes - any attributes\r\n * @return {Element}\r\n */\r\n static make(tagName, classNames = null, attributes = {}) {\r\n let el = document.createElement(tagName);\r\n\r\n if ( Array.isArray(classNames) ) {\r\n el.classList.add(...classNames);\r\n } else if( classNames ) {\r\n el.classList.add(classNames);\r\n }\r\n\r\n for (let attrName in attributes) {\r\n el[attrName] = attributes[attrName];\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 * @param {String} content - text content\r\n * @return {Text}\r\n */\r\n static text(content) {\r\n return document.createTextNode(content);\r\n }\r\n\r\n /**\r\n * Creates SVG icon linked to the sprite\r\n * @param {string} name - name (id) of icon from sprite\r\n * @param {number} width\r\n * @param {number} height\r\n * @return {SVGElement}\r\n */\r\n static svg(name, width = 14, height = 14) {\r\n let icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\r\n\r\n icon.classList.add('icon', 'icon--' + name);\r\n icon.setAttribute('width', width + 'px');\r\n icon.setAttribute('height', height + 'px');\r\n icon.innerHTML = ``;\r\n\r\n return icon;\r\n }\r\n\r\n /**\r\n * Append one or several elements to the parent\r\n *\r\n * @param {Element} parent - where to append\r\n * @param {Element|Element[]} - element ore elements list\r\n */\r\n static append(parent, elements) {\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 * Swap two elements in parent\r\n * @param {HTMLElement} el1 - from\r\n * @param {HTMLElement} el2 - to\r\n */\r\n static swap(el1, el2) {\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 *\r\n * @returns {Element}\r\n */\r\n static find(el = document, selector) {\r\n return el.querySelector(selector);\r\n }\r\n\r\n /**\r\n * Selector Decorator.\r\n *\r\n * Returns all matches\r\n *\r\n * @param {Element} el - element we searching inside. Default - DOM Document\r\n * @param {String} selector - searching string\r\n * @returns {NodeList}\r\n */\r\n static findAll(el = document, selector) {\r\n return el.querySelectorAll(selector);\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 *\r\n * @param {Node} node - root Node. From this vertex we start Deep-first search {@link https://en.wikipedia.org/wiki/Depth-first_search}\r\n * @param {Boolean} atLast - find last text node\r\n * @return {Node} - it can be text Node or Element Node, so that caret will able to work with it\r\n */\r\n static getDeepestNode(node, atLast = false) {\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 * @type {string}\r\n */\r\n let 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];\r\n\r\n /**\r\n * special case when child is single tag that can't contain any content\r\n */\r\n if (Dom.isSingleTag(nodeChild)) {\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 {Object} node\r\n * @returns {boolean}\r\n */\r\n static isElement(node) {\r\n return node && typeof node === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE;\r\n }\r\n\r\n /**\r\n * Checks target if it is native input\r\n * @param {Element|String|Node} target - HTML element or string\r\n * @return {Boolean}\r\n */\r\n static isNativeInput(target) {\r\n let nativeInputs = [\r\n 'INPUT',\r\n 'TEXTAREA'\r\n ];\r\n\r\n return target ? nativeInputs.includes(target.tagName) : false;\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 *\r\n * @param {Node} node\r\n * @return {Boolean} true if it is empty\r\n */\r\n static isNodeEmpty(node) {\r\n let nodeText;\r\n\r\n if ( this.isElement(node) && this.isNativeInput(node) ) {\r\n nodeText = node.value;\r\n } else {\r\n nodeText = node.textContent.replace('\\u200B', '');\r\n }\r\n\r\n return nodeText.trim().length === 0;\r\n }\r\n\r\n /**\r\n * checks node if it is doesn't have any child nodes\r\n * @param {Node} node\r\n * @return {boolean}\r\n */\r\n static isLeaf(node) {\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 *\r\n * @param {Node} node\r\n * @return {boolean}\r\n */\r\n static isEmpty(node) {\r\n let treeWalker = [],\r\n leafs = [];\r\n\r\n if (!node) {\r\n return true;\r\n }\r\n\r\n if (!node.childNodes.length) {\r\n return this.isNodeEmpty(node);\r\n }\r\n\r\n treeWalker.push(node.firstChild);\r\n\r\n while ( treeWalker.length > 0 ) {\r\n node = treeWalker.shift();\r\n\r\n if (!node) continue;\r\n\r\n if ( this.isLeaf(node) ) {\r\n leafs.push(node);\r\n } else {\r\n treeWalker.push(node.firstChild);\r\n }\r\n\r\n while ( node && node.nextSibling ) {\r\n node = node.nextSibling;\r\n\r\n if (!node) continue;\r\n\r\n treeWalker.push(node);\r\n }\r\n\r\n /**\r\n * If one of childs is not empty, checked Node is not empty too\r\n */\r\n if (node && !this.isNodeEmpty(node)) {\r\n return false;\r\n }\r\n }\r\n\r\n return leafs.every( leaf => this.isNodeEmpty(leaf) );\r\n }\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 {\r\n constructor(api) {\r\n /**\r\n * Native Document's command that uses for Bold\r\n */\r\n this.commandName = 'bold';\r\n /**\r\n * Styles\r\n */\r\n this.CSS = {\r\n button: 'ce-inline-tool',\r\n buttonActive: 'ce-inline-tool--active',\r\n buttonModifier: 'ce-inline-tool--bold',\r\n };\r\n /**\r\n * Elements\r\n */\r\n this.nodes = {\r\n button: null,\r\n };\r\n console.log('Bold Inline Tool is ready');\r\n }\r\n /**\r\n * Create button for Inline Toolbar\r\n */\r\n render() {\r\n this.nodes.button = document.createElement('button');\r\n this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);\r\n this.nodes.button.appendChild($.svg('bold', 13, 15));\r\n return this.nodes.button;\r\n }\r\n /**\r\n * Wrap range with tag\r\n * @param {Range} range\r\n */\r\n surround(range) {\r\n document.execCommand(this.commandName);\r\n }\r\n /**\r\n * Check selection and set activated state to button if there are tag\r\n * @param {Selection} selection\r\n */\r\n checkState(selection) {\r\n const isActive = document.queryCommandState(this.commandName);\r\n this.nodes.button.classList.toggle(this.CSS.buttonActive, isActive);\r\n return isActive;\r\n }\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 {\r\n constructor(api) {\r\n /**\r\n * Native Document's command that uses for Italic\r\n */\r\n this.commandName = 'italic';\r\n /**\r\n * Styles\r\n */\r\n this.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 * Elements\r\n */\r\n this.nodes = {\r\n button: null,\r\n };\r\n console.log('Italic Inline Tool is ready');\r\n }\r\n /**\r\n * Create button for Inline Toolbar\r\n */\r\n render() {\r\n this.nodes.button = document.createElement('button');\r\n this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);\r\n this.nodes.button.appendChild($.svg('italic', 6, 15));\r\n return this.nodes.button;\r\n }\r\n /**\r\n * Wrap range with tag\r\n * @param {Range} range\r\n */\r\n surround(range) {\r\n document.execCommand(this.commandName);\r\n }\r\n /**\r\n * Check selection and set activated state to button if there are tag\r\n * @param {Selection} selection\r\n */\r\n checkState(selection) {\r\n const isActive = document.queryCommandState(this.commandName);\r\n this.nodes.button.classList.toggle(this.CSS.buttonActive, isActive);\r\n return isActive;\r\n }\r\n}\r\n","import Selection from '../selection';\r\n/**\r\n * Link Tool\r\n *\r\n * Inline Toolbar Tool\r\n *\r\n * Wrap selected text with tag\r\n */\r\nexport default class LinkInlineTool {\r\n /**\r\n * @param {object} api - CodeX Editor API\r\n * @param {object} api.toolbar - Inline Toolbar API\r\n */\r\n constructor(api) {\r\n /**\r\n * Native Document's commands for link/unlink\r\n */\r\n this.commandLink = 'createLink';\r\n this.commandUnlink = 'unlink';\r\n /**\r\n * Enter key code\r\n */\r\n this.ENTER_KEY = 13;\r\n /**\r\n * Styles\r\n */\r\n this.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 inputShowed: 'ce-inline-tool-input--showed',\r\n };\r\n /**\r\n * Elements\r\n */\r\n this.nodes = {\r\n button: null,\r\n input: null,\r\n };\r\n /**\r\n * Input opening state\r\n */\r\n this.inputOpened = false;\r\n this.inlineToolbar = api.toolbar;\r\n this.selection = new Selection();\r\n }\r\n /**\r\n * Create button for Inline Toolbar\r\n */\r\n render() {\r\n this.nodes.button = document.createElement('button');\r\n this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);\r\n this.nodes.button.appendChild($.svg('link', 15, 14));\r\n this.nodes.button.appendChild($.svg('unlink', 16, 18));\r\n return this.nodes.button;\r\n }\r\n /**\r\n * Input for the link\r\n */\r\n renderActions() {\r\n this.nodes.input = document.createElement('input');\r\n this.nodes.input.placeholder = 'Add a link';\r\n this.nodes.input.classList.add(this.CSS.input);\r\n this.nodes.input.addEventListener('keydown', (event) => {\r\n if (event.keyCode === this.ENTER_KEY) {\r\n this.enterPressed(event);\r\n }\r\n });\r\n return this.nodes.input;\r\n }\r\n /**\r\n * Handle clicks on the Inline Toolbar icon\r\n * @param {Range} range\r\n */\r\n surround(range) {\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 this.selection.save();\r\n const parentAnchor = this.selection.findParentTag('A');\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.inlineToolbar.close();\r\n return;\r\n }\r\n }\r\n this.toggleActions();\r\n }\r\n /**\r\n * Check selection and set activated state to button if there are tag\r\n * @param {Selection} selection\r\n */\r\n checkState(selection) {\r\n const anchorTag = this.selection.findParentTag('A');\r\n if (anchorTag) {\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 * Fill input value with link href\r\n */\r\n const hrefAttr = anchorTag.getAttribute('href');\r\n this.nodes.input.value = hrefAttr !== 'null' ? hrefAttr : '';\r\n this.selection.save();\r\n }\r\n else {\r\n this.nodes.button.classList.remove(this.CSS.buttonUnlink);\r\n this.nodes.button.classList.remove(this.CSS.buttonActive);\r\n }\r\n return !!anchorTag;\r\n }\r\n /**\r\n * Function called with Inline Toolbar closing\r\n */\r\n clear() {\r\n this.closeActions();\r\n }\r\n toggleActions() {\r\n if (!this.inputOpened) {\r\n this.openActions(true);\r\n }\r\n else {\r\n this.closeActions(false);\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 openActions(needFocus = false) {\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 * Close input\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 closeActions(clearSavedSelection = true) {\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 * Enter pressed on input\r\n * @param {KeyboardEvent} event\r\n */\r\n enterPressed(event) {\r\n let value = this.nodes.input.value || '';\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 if (!this.validateURL(value)) {\r\n /**\r\n * @todo show notification 'Incorrect Link'\r\n */\r\n _.log('Incorrect Link pasted', 'warn', value);\r\n return;\r\n }\r\n value = this.prepareLink(value);\r\n this.selection.restore();\r\n this.insertLink(value);\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.closeActions();\r\n this.inlineToolbar.close();\r\n this.checkState();\r\n }\r\n /**\r\n * Detects if passed string is URL\r\n * @param {string} str\r\n * @return {Boolean}\r\n */\r\n validateURL(str) {\r\n /**\r\n * Don't allow spaces\r\n */\r\n return !/\\s/.test(str);\r\n }\r\n /**\r\n * Process link before injection\r\n * - sanitize\r\n * - add protocol for links like 'google.com'\r\n * @param {string} link - raw user input\r\n */\r\n prepareLink(link) {\r\n link = link.trim();\r\n link = this.addProtocol(link);\r\n return link;\r\n }\r\n /**\r\n * Add 'http' protocol to the links like 'vc.ru', 'google.com'\r\n * @param {String} link\r\n */\r\n addProtocol(link) {\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 * 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), isAnchor = link.substring(0, 1) === '#', isProtocolRelative = /^\\/\\/[^\\/\\s]/.test(link);\r\n if (!isInternal && !isAnchor && !isProtocolRelative) {\r\n link = 'http://' + link;\r\n }\r\n return link;\r\n }\r\n /**\r\n * Inserts tag with \"href\"\r\n * @param {string} link - \"href\" value\r\n */\r\n insertLink(link) {\r\n /**\r\n * Edit all link, not selected part\r\n */\r\n const anchorTag = this.selection.findParentTag('A');\r\n if (anchorTag) {\r\n this.selection.expandToTag(anchorTag);\r\n }\r\n document.execCommand(this.commandLink, false, link);\r\n }\r\n /**\r\n * Removes tag\r\n */\r\n unlink() {\r\n document.execCommand(this.commandUnlink);\r\n }\r\n}\r\n","var map = {\n\t\"./_anchors\": \"./src/components/modules/_anchors.js\",\n\t\"./_anchors.js\": \"./src/components/modules/_anchors.js\",\n\t\"./_callbacks\": \"./src/components/modules/_callbacks.js\",\n\t\"./_callbacks.js\": \"./src/components/modules/_callbacks.js\",\n\t\"./_caret\": \"./src/components/modules/_caret.js\",\n\t\"./_caret.js\": \"./src/components/modules/_caret.js\",\n\t\"./_content\": \"./src/components/modules/_content.js\",\n\t\"./_content.js\": \"./src/components/modules/_content.js\",\n\t\"./_destroyer\": \"./src/components/modules/_destroyer.js\",\n\t\"./_destroyer.js\": \"./src/components/modules/_destroyer.js\",\n\t\"./_notifications\": \"./src/components/modules/_notifications.js\",\n\t\"./_notifications.js\": \"./src/components/modules/_notifications.js\",\n\t\"./_parser\": \"./src/components/modules/_parser.js\",\n\t\"./_parser.js\": \"./src/components/modules/_parser.js\",\n\t\"./_paste\": \"./src/components/modules/_paste.js\",\n\t\"./_paste.js\": \"./src/components/modules/_paste.js\",\n\t\"./_transport\": \"./src/components/modules/_transport.js\",\n\t\"./_transport.js\": \"./src/components/modules/_transport.js\",\n\t\"./api\": \"./src/components/modules/api.ts\",\n\t\"./api-blocks\": \"./src/components/modules/api-blocks.ts\",\n\t\"./api-blocks.ts\": \"./src/components/modules/api-blocks.ts\",\n\t\"./api-events\": \"./src/components/modules/api-events.ts\",\n\t\"./api-events.ts\": \"./src/components/modules/api-events.ts\",\n\t\"./api-listener\": \"./src/components/modules/api-listener.ts\",\n\t\"./api-listener.ts\": \"./src/components/modules/api-listener.ts\",\n\t\"./api-sanitizer\": \"./src/components/modules/api-sanitizer.ts\",\n\t\"./api-sanitizer.ts\": \"./src/components/modules/api-sanitizer.ts\",\n\t\"./api-saver\": \"./src/components/modules/api-saver.ts\",\n\t\"./api-saver.ts\": \"./src/components/modules/api-saver.ts\",\n\t\"./api-selection\": \"./src/components/modules/api-selection.ts\",\n\t\"./api-selection.ts\": \"./src/components/modules/api-selection.ts\",\n\t\"./api-toolbar\": \"./src/components/modules/api-toolbar.ts\",\n\t\"./api-toolbar.ts\": \"./src/components/modules/api-toolbar.ts\",\n\t\"./api.ts\": \"./src/components/modules/api.ts\",\n\t\"./block-events\": \"./src/components/modules/block-events.ts\",\n\t\"./block-events.ts\": \"./src/components/modules/block-events.ts\",\n\t\"./blockManager\": \"./src/components/modules/blockManager.js\",\n\t\"./blockManager.js\": \"./src/components/modules/blockManager.js\",\n\t\"./caret\": \"./src/components/modules/caret.js\",\n\t\"./caret.js\": \"./src/components/modules/caret.js\",\n\t\"./events\": \"./src/components/modules/events.js\",\n\t\"./events.js\": \"./src/components/modules/events.js\",\n\t\"./listeners\": \"./src/components/modules/listeners.js\",\n\t\"./listeners.js\": \"./src/components/modules/listeners.js\",\n\t\"./renderer\": \"./src/components/modules/renderer.js\",\n\t\"./renderer.js\": \"./src/components/modules/renderer.js\",\n\t\"./sanitizer\": \"./src/components/modules/sanitizer.js\",\n\t\"./sanitizer.js\": \"./src/components/modules/sanitizer.js\",\n\t\"./saver\": \"./src/components/modules/saver.js\",\n\t\"./saver.js\": \"./src/components/modules/saver.js\",\n\t\"./toolbar\": \"./src/components/modules/toolbar.js\",\n\t\"./toolbar-blockSettings\": \"./src/components/modules/toolbar-blockSettings.js\",\n\t\"./toolbar-blockSettings.js\": \"./src/components/modules/toolbar-blockSettings.js\",\n\t\"./toolbar-inline\": \"./src/components/modules/toolbar-inline.ts\",\n\t\"./toolbar-inline.ts\": \"./src/components/modules/toolbar-inline.ts\",\n\t\"./toolbar-toolbox\": \"./src/components/modules/toolbar-toolbox.js\",\n\t\"./toolbar-toolbox.js\": \"./src/components/modules/toolbar-toolbox.js\",\n\t\"./toolbar.js\": \"./src/components/modules/toolbar.js\",\n\t\"./toolbar/inline\": \"./src/components/modules/toolbar/inline.js\",\n\t\"./toolbar/inline.js\": \"./src/components/modules/toolbar/inline.js\",\n\t\"./toolbar/settings\": \"./src/components/modules/toolbar/settings.js\",\n\t\"./toolbar/settings.js\": \"./src/components/modules/toolbar/settings.js\",\n\t\"./toolbar/toolbar\": \"./src/components/modules/toolbar/toolbar.js\",\n\t\"./toolbar/toolbar.js\": \"./src/components/modules/toolbar/toolbar.js\",\n\t\"./toolbar/toolbox\": \"./src/components/modules/toolbar/toolbox.js\",\n\t\"./toolbar/toolbox.js\": \"./src/components/modules/toolbar/toolbox.js\",\n\t\"./tools\": \"./src/components/modules/tools.js\",\n\t\"./tools.js\": \"./src/components/modules/tools.js\",\n\t\"./ui\": \"./src/components/modules/ui.js\",\n\t\"./ui.js\": \"./src/components/modules/ui.js\"\n};\n\n\nfunction webpackContext(req) {\n\tvar id = webpackContextResolve(req);\n\treturn __webpack_require__(id);\n}\nfunction webpackContextResolve(req) {\n\tvar id = map[req];\n\tif(!(id + 1)) { // check for number or string\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\treturn id;\n}\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = \"./src/components/modules sync recursive ^\\\\.\\\\/.*$\";","/**\r\n * Codex Editor Anchors module\r\n *\r\n * @author Codex Team\r\n * @version 1.0\r\n */\r\n\r\nmodule.exports = function (anchors) {\r\n let editor = codex.editor;\r\n\r\n anchors.input = null;\r\n anchors.currentNode = null;\r\n\r\n anchors.settingsOpened = function (currentBlock) {\r\n anchors.currentNode = currentBlock;\r\n anchors.input.value = anchors.currentNode.dataset.anchor || '';\r\n };\r\n\r\n anchors.anchorChanged = function (e) {\r\n var newAnchor = e.target.value = anchors.rusToTranslit(e.target.value);\r\n\r\n anchors.currentNode.dataset.anchor = newAnchor;\r\n\r\n if (newAnchor.trim() !== '') {\r\n anchors.currentNode.classList.add(editor.ui.className.BLOCK_WITH_ANCHOR);\r\n } else {\r\n anchors.currentNode.classList.remove(editor.ui.className.BLOCK_WITH_ANCHOR);\r\n }\r\n };\r\n\r\n anchors.keyDownOnAnchorInput = function (e) {\r\n if (e.keyCode == editor.core.keys.ENTER) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n e.target.blur();\r\n editor.toolbar.settings.close();\r\n }\r\n };\r\n\r\n anchors.keyUpOnAnchorInput = function (e) {\r\n if (e.keyCode >= editor.core.keys.LEFT && e.keyCode <= editor.core.keys.DOWN) {\r\n e.stopPropagation();\r\n }\r\n };\r\n\r\n anchors.rusToTranslit = function (string) {\r\n var ru = [\r\n 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й',\r\n 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф',\r\n 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ь', 'Ы', 'Ь', 'Э', 'Ю', 'Я'\r\n ],\r\n en = [\r\n 'A', 'B', 'V', 'G', 'D', 'E', 'E', 'Zh', 'Z', 'I', 'Y',\r\n 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F',\r\n 'H', 'C', 'Ch', 'Sh', 'Sch', '', 'Y', '', 'E', 'Yu', 'Ya'\r\n ];\r\n\r\n for (var i = 0; i < ru.length; i++) {\r\n string = string.split(ru[i]).join(en[i]);\r\n string = string.split(ru[i].toLowerCase()).join(en[i].toLowerCase());\r\n }\r\n\r\n string = string.replace(/[^0-9a-zA-Z_]+/g, '-');\r\n\r\n return string;\r\n };\r\n\r\n return anchors;\r\n}({});","/**\r\n * @module Codex Editor Callbacks module\r\n * @description Module works with editor added Elements\r\n *\r\n * @author Codex Team\r\n * @version 1.4.0\r\n */\r\n\r\nmodule.exports = (function (callbacks) {\r\n let editor = codex.editor;\r\n\r\n /**\r\n * used by UI module\r\n * @description Routes all keydowns on document\r\n * @param {Object} event\r\n */\r\n callbacks.globalKeydown = function (event) {\r\n switch (event.keyCode) {\r\n case editor.core.keys.ENTER : enterKeyPressed_(event); break;\r\n }\r\n };\r\n\r\n /**\r\n * used by UI module\r\n * @description Routes all keydowns on redactors area\r\n * @param {Object} event\r\n */\r\n callbacks.redactorKeyDown = function (event) {\r\n switch (event.keyCode) {\r\n case editor.core.keys.TAB : tabKeyPressedOnRedactorsZone_(event); break;\r\n case editor.core.keys.ENTER : enterKeyPressedOnRedactorsZone_(event); break;\r\n case editor.core.keys.ESC : escapeKeyPressedOnRedactorsZone_(event); break;\r\n default : defaultKeyPressedOnRedactorsZone_(event); break;\r\n }\r\n };\r\n\r\n /**\r\n * used by UI module\r\n * @description Routes all keyup events\r\n * @param {Object} event\r\n */\r\n callbacks.globalKeyup = function (event) {\r\n switch (event.keyCode) {\r\n case editor.core.keys.UP :\r\n case editor.core.keys.LEFT :\r\n case editor.core.keys.RIGHT :\r\n case editor.core.keys.DOWN : arrowKeyPressed_(event); break;\r\n }\r\n };\r\n\r\n /**\r\n * @param {Object} event\r\n * @private\r\n *\r\n * Handles behaviour when tab pressed\r\n * @description if Content is empty show toolbox (if it is closed) or leaf tools\r\n * uses Toolbars toolbox module to handle the situation\r\n */\r\n var tabKeyPressedOnRedactorsZone_ = function (event) {\r\n /**\r\n * Wait for solution. Would like to know the behaviour\r\n * @todo Add spaces\r\n */\r\n event.preventDefault();\r\n\r\n\r\n if (!editor.core.isBlockEmpty(editor.content.currentNode)) {\r\n return;\r\n }\r\n\r\n if ( !editor.toolbar.opened ) {\r\n editor.toolbar.open();\r\n }\r\n\r\n if (editor.toolbar.opened && !editor.toolbar.toolbox.opened) {\r\n editor.toolbar.toolbox.open();\r\n } else {\r\n editor.toolbar.toolbox.leaf();\r\n }\r\n };\r\n\r\n /**\r\n * Handles global EnterKey Press\r\n * @see enterPressedOnBlock_\r\n * @param {Object} event\r\n */\r\n var enterKeyPressed_ = function () {\r\n if (editor.content.editorAreaHightlighted) {\r\n /**\r\n * it means that we lose input index, saved index before is not correct\r\n * therefore we need to set caret when we insert new block\r\n */\r\n editor.caret.inputIndex = -1;\r\n\r\n enterPressedOnBlock_();\r\n }\r\n };\r\n\r\n /**\r\n * Callback for enter key pressing in first-level block area\r\n *\r\n * @param {Event} event\r\n * @private\r\n *\r\n * @description Inserts new block with initial type from settings\r\n */\r\n var enterPressedOnBlock_ = function () {\r\n var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;\r\n\r\n editor.content.insertBlock({\r\n type : NEW_BLOCK_TYPE,\r\n block : editor.tools[NEW_BLOCK_TYPE].render()\r\n }, true );\r\n\r\n editor.toolbar.move();\r\n editor.toolbar.open();\r\n };\r\n\r\n\r\n /**\r\n * ENTER key handler\r\n *\r\n * @param {Object} event\r\n * @private\r\n *\r\n * @description Makes new block with initial type from settings\r\n */\r\n var enterKeyPressedOnRedactorsZone_ = function (event) {\r\n if (event.target.contentEditable == 'true') {\r\n /** Update input index */\r\n editor.caret.saveCurrentInputIndex();\r\n }\r\n\r\n var currentInputIndex = editor.caret.getCurrentInputIndex() || 0,\r\n workingNode = editor.content.currentNode,\r\n tool = workingNode.dataset.tool,\r\n isEnterPressedOnToolbar = editor.toolbar.opened &&\r\n editor.toolbar.current &&\r\n event.target == editor.state.inputs[currentInputIndex];\r\n\r\n /** The list of tools which needs the default browser behaviour */\r\n var enableLineBreaks = editor.tools[tool].enableLineBreaks;\r\n\r\n /** This type of block creates when enter is pressed */\r\n var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;\r\n\r\n /**\r\n * When toolbar is opened, select tool instead of making new paragraph\r\n */\r\n if ( isEnterPressedOnToolbar ) {\r\n event.preventDefault();\r\n\r\n editor.toolbar.toolbox.toolClicked(event);\r\n\r\n editor.toolbar.close();\r\n\r\n /**\r\n * Stop other listeners callback executions\r\n */\r\n event.stopPropagation();\r\n event.stopImmediatePropagation();\r\n\r\n return;\r\n }\r\n\r\n /**\r\n * Allow paragraph lineBreaks with shift enter\r\n * Or if shiftkey pressed and enter and enabledLineBreaks, the let new block creation\r\n */\r\n if ( event.shiftKey || enableLineBreaks ) {\r\n event.stopPropagation();\r\n event.stopImmediatePropagation();\r\n return;\r\n }\r\n\r\n var currentSelection = window.getSelection(),\r\n currentSelectedNode = currentSelection.anchorNode,\r\n caretAtTheEndOfText = editor.caret.position.atTheEnd(),\r\n isTextNodeHasParentBetweenContenteditable = false;\r\n\r\n /**\r\n * Allow making new

    in same block by SHIFT+ENTER and forbids to prevent default browser behaviour\r\n */\r\n if ( event.shiftKey && !enableLineBreaks ) {\r\n editor.callback.enterPressedOnBlock(editor.content.currentBlock, event);\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n /**\r\n * Workaround situation when caret at the Text node that has some wrapper Elements\r\n * Split block cant handle this.\r\n * We need to save default behavior\r\n */\r\n isTextNodeHasParentBetweenContenteditable = currentSelectedNode && currentSelectedNode.parentNode.contentEditable != 'true';\r\n\r\n /**\r\n * Split blocks when input has several nodes and caret placed in textNode\r\n */\r\n if (\r\n currentSelectedNode.nodeType == editor.core.nodeTypes.TEXT &&\r\n !isTextNodeHasParentBetweenContenteditable &&\r\n !caretAtTheEndOfText\r\n ) {\r\n event.preventDefault();\r\n\r\n editor.core.log('Splitting Text node...');\r\n\r\n editor.content.splitBlock(currentInputIndex);\r\n\r\n /** Show plus button when next input after split is empty*/\r\n if (!editor.state.inputs[currentInputIndex + 1].textContent.trim()) {\r\n editor.toolbar.showPlusButton();\r\n }\r\n } else {\r\n var islastNode = editor.content.isLastNode(currentSelectedNode);\r\n\r\n if ( islastNode && caretAtTheEndOfText ) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n event.stopImmediatePropagation();\r\n\r\n editor.core.log('ENTER clicked in last textNode. Create new BLOCK');\r\n\r\n editor.content.insertBlock({\r\n type: NEW_BLOCK_TYPE,\r\n block: editor.tools[NEW_BLOCK_TYPE].render()\r\n }, true);\r\n\r\n editor.toolbar.move();\r\n editor.toolbar.open();\r\n\r\n /** Show plus button with empty block */\r\n editor.toolbar.showPlusButton();\r\n }\r\n }\r\n\r\n /** get all inputs after new appending block */\r\n editor.ui.saveInputs();\r\n };\r\n\r\n /**\r\n * Escape behaviour\r\n * @param event\r\n * @private\r\n *\r\n * @description Closes toolbox and toolbar. Prevents default behaviour\r\n */\r\n var escapeKeyPressedOnRedactorsZone_ = function (event) {\r\n /** Close all toolbar */\r\n editor.toolbar.close();\r\n\r\n /** Close toolbox */\r\n editor.toolbar.toolbox.close();\r\n\r\n event.preventDefault();\r\n };\r\n\r\n /**\r\n * @param {Event} event\r\n * @private\r\n *\r\n * closes and moves toolbar\r\n */\r\n var arrowKeyPressed_ = function (event) {\r\n editor.content.workingNodeChanged();\r\n\r\n /* Closing toolbar */\r\n editor.toolbar.close();\r\n editor.toolbar.move();\r\n };\r\n\r\n /**\r\n * @private\r\n * @param {Event} event\r\n *\r\n * @description Closes all opened bars from toolbar.\r\n * If block is mark, clears highlightning\r\n */\r\n var defaultKeyPressedOnRedactorsZone_ = function () {\r\n editor.toolbar.close();\r\n\r\n if (!editor.toolbar.inline.actionsOpened) {\r\n editor.toolbar.inline.close();\r\n editor.content.clearMark();\r\n }\r\n };\r\n\r\n /**\r\n * Handler when clicked on redactors area\r\n *\r\n * @protected\r\n * @param event\r\n *\r\n * @description Detects clicked area. If it is first-level block area, marks as detected and\r\n * on next enter press will be inserted new block\r\n * Otherwise, save carets position (input index) and put caret to the editable zone.\r\n *\r\n * @see detectWhenClickedOnFirstLevelBlockArea_\r\n *\r\n */\r\n callbacks.redactorClicked = function (event) {\r\n detectWhenClickedOnFirstLevelBlockArea_();\r\n\r\n editor.content.workingNodeChanged(event.target);\r\n editor.ui.saveInputs();\r\n\r\n var selectedText = editor.toolbar.inline.getSelectionText(),\r\n firstLevelBlock;\r\n\r\n /** If selection range took off, then we hide inline toolbar */\r\n if (selectedText.length === 0) {\r\n editor.toolbar.inline.close();\r\n }\r\n\r\n /** Update current input index in memory when caret focused into existed input */\r\n if (event.target.contentEditable == 'true') {\r\n editor.caret.saveCurrentInputIndex();\r\n }\r\n\r\n if (editor.content.currentNode === null) {\r\n /**\r\n * If inputs in redactor does not exits, then we put input index 0 not -1\r\n */\r\n var indexOfLastInput = editor.state.inputs.length > 0 ? editor.state.inputs.length - 1 : 0;\r\n\r\n /** If we have any inputs */\r\n if (editor.state.inputs.length) {\r\n /** getting firstlevel parent of input */\r\n firstLevelBlock = editor.content.getFirstLevelBlock(editor.state.inputs[indexOfLastInput]);\r\n }\r\n\r\n /** If input is empty, then we set caret to the last input */\r\n if (editor.state.inputs.length && editor.state.inputs[indexOfLastInput].textContent === '' && firstLevelBlock.dataset.tool == editor.settings.initialBlockPlugin) {\r\n editor.caret.setToBlock(indexOfLastInput);\r\n } else {\r\n /** Create new input when caret clicked in redactors area */\r\n var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;\r\n\r\n editor.content.insertBlock({\r\n type : NEW_BLOCK_TYPE,\r\n block : editor.tools[NEW_BLOCK_TYPE].render()\r\n });\r\n\r\n /** If there is no inputs except inserted */\r\n if (editor.state.inputs.length === 1) {\r\n editor.caret.setToBlock(indexOfLastInput);\r\n } else {\r\n /** Set caret to this appended input */\r\n editor.caret.setToNextBlock(indexOfLastInput);\r\n }\r\n }\r\n } else {\r\n /** Close all panels */\r\n editor.toolbar.settings.close();\r\n editor.toolbar.toolbox.close();\r\n }\r\n\r\n /**\r\n * Move toolbar and open\r\n */\r\n editor.toolbar.move();\r\n editor.toolbar.open();\r\n\r\n var inputIsEmpty = !editor.content.currentNode.textContent.trim(),\r\n currentNodeType = editor.content.currentNode.dataset.tool,\r\n isInitialType = currentNodeType == editor.settings.initialBlockPlugin;\r\n\r\n\r\n /** Hide plus buttons */\r\n editor.toolbar.hidePlusButton();\r\n\r\n if (!inputIsEmpty) {\r\n /** Mark current block */\r\n editor.content.markBlock();\r\n }\r\n\r\n if ( isInitialType && inputIsEmpty ) {\r\n /** Show plus button */\r\n editor.toolbar.showPlusButton();\r\n }\r\n };\r\n\r\n /**\r\n * This method allows to define, is caret in contenteditable element or not.\r\n *\r\n * @private\r\n *\r\n * @description Otherwise, if we get TEXT node from range container, that will means we have input index.\r\n * In this case we use default browsers behaviour (if plugin allows that) or overwritten action.\r\n * Therefore, to be sure that we've clicked first-level block area, we should have currentNode, which always\r\n * specifies to the first-level block. Other cases we just ignore.\r\n */\r\n var detectWhenClickedOnFirstLevelBlockArea_ = function () {\r\n var selection = window.getSelection(),\r\n anchorNode = selection.anchorNode,\r\n flag = false;\r\n\r\n if (selection.rangeCount === 0) {\r\n editor.content.editorAreaHightlighted = true;\r\n } else {\r\n if (!editor.core.isDomNode(anchorNode)) {\r\n anchorNode = anchorNode.parentNode;\r\n }\r\n\r\n /** Already founded, without loop */\r\n if (anchorNode.contentEditable == 'true') {\r\n flag = true;\r\n }\r\n\r\n while (anchorNode.contentEditable != 'true') {\r\n anchorNode = anchorNode.parentNode;\r\n\r\n if (anchorNode.contentEditable == 'true') {\r\n flag = true;\r\n }\r\n\r\n if (anchorNode == document.body) {\r\n break;\r\n }\r\n }\r\n\r\n /** If editable element founded, flag is \"TRUE\", Therefore we return \"FALSE\" */\r\n editor.content.editorAreaHightlighted = !flag;\r\n }\r\n };\r\n\r\n /**\r\n * Toolbar button click handler\r\n *\r\n * @param {Object} event - cursor to the button\r\n * @protected\r\n *\r\n * @description gets current tool and calls render method\r\n */\r\n callbacks.toolbarButtonClicked = function (event) {\r\n var button = this;\r\n\r\n editor.toolbar.current = button.dataset.type;\r\n\r\n editor.toolbar.toolbox.toolClicked(event);\r\n editor.toolbar.close();\r\n };\r\n\r\n /**\r\n * Show or Hide toolbox when plus button is clicked\r\n */\r\n callbacks.plusButtonClicked = function () {\r\n if (!editor.nodes.toolbox.classList.contains('opened')) {\r\n editor.toolbar.toolbox.open();\r\n } else {\r\n editor.toolbar.toolbox.close();\r\n }\r\n };\r\n\r\n /**\r\n * Block handlers for KeyDown events\r\n *\r\n * @protected\r\n * @param {Object} event\r\n *\r\n * Handles keydowns on block\r\n * @see blockRightOrDownArrowPressed_\r\n * @see backspacePressed_\r\n * @see blockLeftOrUpArrowPressed_\r\n */\r\n callbacks.blockKeydown = function (event) {\r\n let block = event.target; // event.target is input\r\n\r\n switch (event.keyCode) {\r\n case editor.core.keys.DOWN:\r\n case editor.core.keys.RIGHT:\r\n blockRightOrDownArrowPressed_(event);\r\n break;\r\n\r\n case editor.core.keys.BACKSPACE:\r\n backspacePressed_(block, event);\r\n break;\r\n\r\n case editor.core.keys.UP:\r\n case editor.core.keys.LEFT:\r\n blockLeftOrUpArrowPressed_(event);\r\n break;\r\n }\r\n };\r\n\r\n /**\r\n * RIGHT or DOWN keydowns on block\r\n *\r\n * @param {Object} event\r\n * @private\r\n *\r\n * @description watches the selection and gets closest editable element.\r\n * Uses method getDeepestTextNodeFromPosition to get the last node of next block\r\n * Sets caret if it is contenteditable\r\n */\r\n var blockRightOrDownArrowPressed_ = function (event) {\r\n var selection = window.getSelection(),\r\n inputs = editor.state.inputs,\r\n focusedNode = selection.anchorNode,\r\n focusedNodeHolder;\r\n\r\n /** Check for caret existance */\r\n if (!focusedNode) {\r\n return false;\r\n }\r\n\r\n /** Looking for closest (parent) contentEditable element of focused node */\r\n while (focusedNode.contentEditable != 'true') {\r\n focusedNodeHolder = focusedNode.parentNode;\r\n focusedNode = focusedNodeHolder;\r\n }\r\n\r\n /** Input index in DOM level */\r\n var editableElementIndex = 0;\r\n\r\n while (focusedNode != inputs[editableElementIndex]) {\r\n editableElementIndex ++;\r\n }\r\n\r\n /**\r\n * Founded contentEditable element doesn't have childs\r\n * Or maybe New created block\r\n */\r\n if (!focusedNode.textContent) {\r\n editor.caret.setToNextBlock(editableElementIndex);\r\n return;\r\n }\r\n\r\n /**\r\n * Do nothing when caret doesn not reaches the end of last child\r\n */\r\n var caretInLastChild = false,\r\n caretAtTheEndOfText = false;\r\n\r\n var lastChild,\r\n deepestTextnode;\r\n\r\n lastChild = focusedNode.childNodes[focusedNode.childNodes.length - 1 ];\r\n\r\n if (editor.core.isDomNode(lastChild)) {\r\n deepestTextnode = editor.content.getDeepestTextNodeFromPosition(lastChild, lastChild.childNodes.length);\r\n } else {\r\n deepestTextnode = lastChild;\r\n }\r\n\r\n caretInLastChild = selection.anchorNode == deepestTextnode;\r\n caretAtTheEndOfText = deepestTextnode.length == selection.anchorOffset;\r\n\r\n if ( !caretInLastChild || !caretAtTheEndOfText ) {\r\n editor.core.log('arrow [down|right] : caret does not reached the end');\r\n return false;\r\n }\r\n\r\n editor.caret.setToNextBlock(editableElementIndex);\r\n };\r\n\r\n /**\r\n * LEFT or UP keydowns on block\r\n *\r\n * @param {Object} event\r\n * @private\r\n *\r\n * watches the selection and gets closest editable element.\r\n * Uses method getDeepestTextNodeFromPosition to get the last node of previous block\r\n * Sets caret if it is contenteditable\r\n *\r\n */\r\n var blockLeftOrUpArrowPressed_ = function (event) {\r\n var selection = window.getSelection(),\r\n inputs = editor.state.inputs,\r\n focusedNode = selection.anchorNode,\r\n focusedNodeHolder;\r\n\r\n /** Check for caret existance */\r\n if (!focusedNode) {\r\n return false;\r\n }\r\n\r\n /**\r\n * LEFT or UP not at the beginning\r\n */\r\n if ( selection.anchorOffset !== 0) {\r\n return false;\r\n }\r\n\r\n /** Looking for parent contentEditable block */\r\n while (focusedNode.contentEditable != 'true') {\r\n focusedNodeHolder = focusedNode.parentNode;\r\n focusedNode = focusedNodeHolder;\r\n }\r\n\r\n /** Input index in DOM level */\r\n var editableElementIndex = 0;\r\n\r\n while (focusedNode != inputs[editableElementIndex]) {\r\n editableElementIndex ++;\r\n }\r\n\r\n /**\r\n * Do nothing if caret is not at the beginning of first child\r\n */\r\n var caretInFirstChild = false,\r\n caretAtTheBeginning = false;\r\n\r\n var firstChild,\r\n deepestTextnode;\r\n\r\n /**\r\n * Founded contentEditable element doesn't have childs\r\n * Or maybe New created block\r\n */\r\n if (!focusedNode.textContent) {\r\n editor.caret.setToPreviousBlock(editableElementIndex);\r\n return;\r\n }\r\n\r\n firstChild = focusedNode.childNodes[0];\r\n\r\n if (editor.core.isDomNode(firstChild)) {\r\n deepestTextnode = editor.content.getDeepestTextNodeFromPosition(firstChild, 0);\r\n } else {\r\n deepestTextnode = firstChild;\r\n }\r\n\r\n caretInFirstChild = selection.anchorNode == deepestTextnode;\r\n caretAtTheBeginning = selection.anchorOffset === 0;\r\n\r\n if ( caretInFirstChild && caretAtTheBeginning ) {\r\n editor.caret.setToPreviousBlock(editableElementIndex);\r\n }\r\n };\r\n\r\n /**\r\n * Handles backspace keydown\r\n *\r\n * @param {Element} block\r\n * @param {Object} event\r\n * @private\r\n *\r\n * @description if block is empty, delete the block and set caret to the previous block\r\n * If block is not empty, try to merge two blocks - current and previous\r\n * But it we try'n to remove first block, then we should set caret to the next block, not previous.\r\n * If we removed the last block, create new one\r\n */\r\n var backspacePressed_ = function (block, event) {\r\n var currentInputIndex = editor.caret.getCurrentInputIndex(),\r\n range,\r\n selectionLength,\r\n firstLevelBlocksCount;\r\n\r\n if (editor.core.isNativeInput(event.target)) {\r\n /** If input value is empty - remove block */\r\n if (event.target.value.trim() == '') {\r\n block.remove();\r\n } else {\r\n return;\r\n }\r\n }\r\n\r\n if (block.textContent.trim()) {\r\n range = editor.content.getRange();\r\n selectionLength = range.endOffset - range.startOffset;\r\n\r\n if (editor.caret.position.atStart() && !selectionLength && editor.state.inputs[currentInputIndex - 1]) {\r\n editor.content.mergeBlocks(currentInputIndex);\r\n } else {\r\n return;\r\n }\r\n }\r\n\r\n if (!selectionLength) {\r\n block.remove();\r\n }\r\n\r\n\r\n firstLevelBlocksCount = editor.nodes.redactor.childNodes.length;\r\n\r\n /**\r\n * If all blocks are removed\r\n */\r\n if (firstLevelBlocksCount === 0) {\r\n /** update currentNode variable */\r\n editor.content.currentNode = null;\r\n\r\n /** Inserting new empty initial block */\r\n editor.ui.addInitialBlock();\r\n\r\n /** Updating inputs state after deleting last block */\r\n editor.ui.saveInputs();\r\n\r\n /** Set to current appended block */\r\n window.setTimeout(function () {\r\n editor.caret.setToPreviousBlock(1);\r\n }, 10);\r\n } else {\r\n if (editor.caret.inputIndex !== 0) {\r\n /** Target block is not first */\r\n editor.caret.setToPreviousBlock(editor.caret.inputIndex);\r\n } else {\r\n /** If we try to delete first block */\r\n editor.caret.setToNextBlock(editor.caret.inputIndex);\r\n }\r\n }\r\n\r\n editor.toolbar.move();\r\n\r\n if (!editor.toolbar.opened) {\r\n editor.toolbar.open();\r\n }\r\n\r\n /** Updating inputs state */\r\n editor.ui.saveInputs();\r\n\r\n /** Prevent default browser behaviour */\r\n event.preventDefault();\r\n };\r\n\r\n /**\r\n * used by UI module\r\n * Clicks on block settings button\r\n *\r\n * @param {Object} event\r\n * @protected\r\n * @description Opens toolbar settings\r\n */\r\n callbacks.showSettingsButtonClicked = function (event) {\r\n /**\r\n * Get type of current block\r\n * It uses to append settings from tool.settings property.\r\n * ...\r\n * Type is stored in data-type attribute on block\r\n */\r\n var currentToolType = editor.content.currentNode.dataset.tool;\r\n\r\n editor.toolbar.settings.toggle(currentToolType);\r\n\r\n /** Close toolbox when settings button is active */\r\n editor.toolbar.toolbox.close();\r\n editor.toolbar.settings.hideRemoveActions();\r\n };\r\n\r\n return callbacks;\r\n})({});","/**\r\n * Codex Editor Caret Module\r\n *\r\n * @author Codex Team\r\n * @version 1.0\r\n */\r\n\r\nmodule.exports = (function (caret) {\r\n let editor = codex.editor;\r\n\r\n /**\r\n * @var {int} InputIndex - editable element in DOM\r\n */\r\n caret.inputIndex = null;\r\n\r\n /**\r\n * @var {int} offset - caret position in a text node.\r\n */\r\n caret.offset = null;\r\n\r\n /**\r\n * @var {int} focusedNodeIndex - we get index of child node from first-level block\r\n */\r\n caret.focusedNodeIndex = null;\r\n\r\n /**\r\n * Creates Document Range and sets caret to the element.\r\n * @protected\r\n * @uses caret.save — if you need to save caret position\r\n * @param {Element} el - Changed Node.\r\n */\r\n caret.set = function ( el, index, offset) {\r\n offset = offset || caret.offset || 0;\r\n index = index || caret.focusedNodeIndex || 0;\r\n\r\n var childs = el.childNodes,\r\n nodeToSet;\r\n\r\n if ( childs.length === 0 ) {\r\n nodeToSet = el;\r\n } else {\r\n nodeToSet = childs[index];\r\n }\r\n\r\n /** If Element is INPUT */\r\n if (el.contentEditable != 'true') {\r\n el.focus();\r\n return;\r\n }\r\n\r\n if (editor.core.isDomNode(nodeToSet)) {\r\n nodeToSet = editor.content.getDeepestTextNodeFromPosition(nodeToSet, nodeToSet.childNodes.length);\r\n }\r\n\r\n var range = document.createRange(),\r\n selection = window.getSelection();\r\n\r\n window.setTimeout(function () {\r\n range.setStart(nodeToSet, offset);\r\n range.setEnd(nodeToSet, offset);\r\n\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n\r\n editor.caret.saveCurrentInputIndex();\r\n }, 20);\r\n };\r\n\r\n /**\r\n * @protected\r\n * Updates index of input and saves it in caret object\r\n */\r\n caret.saveCurrentInputIndex = function () {\r\n /** Index of Input that we paste sanitized content */\r\n var selection = window.getSelection(),\r\n inputs = editor.state.inputs,\r\n focusedNode = selection.anchorNode,\r\n focusedNodeHolder;\r\n\r\n if (!focusedNode) {\r\n return;\r\n }\r\n\r\n /** Looking for parent contentEditable block */\r\n while (focusedNode.contentEditable != 'true') {\r\n focusedNodeHolder = focusedNode.parentNode;\r\n focusedNode = focusedNodeHolder;\r\n }\r\n\r\n /** Input index in DOM level */\r\n var editableElementIndex = 0;\r\n\r\n while (focusedNode != inputs[editableElementIndex]) {\r\n editableElementIndex ++;\r\n }\r\n\r\n caret.inputIndex = editableElementIndex;\r\n };\r\n\r\n /**\r\n * Returns current input index (caret object)\r\n */\r\n caret.getCurrentInputIndex = function () {\r\n return caret.inputIndex;\r\n };\r\n\r\n /**\r\n * @param {int} index - index of first-level block after that we set caret into next input\r\n */\r\n caret.setToNextBlock = function (index) {\r\n var inputs = editor.state.inputs,\r\n nextInput = inputs[index + 1];\r\n\r\n if (!nextInput) {\r\n editor.core.log('We are reached the end');\r\n return;\r\n }\r\n\r\n /**\r\n * When new Block created or deleted content of input\r\n * We should add some text node to set caret\r\n */\r\n if (!nextInput.childNodes.length) {\r\n var emptyTextElement = document.createTextNode('');\r\n\r\n nextInput.appendChild(emptyTextElement);\r\n }\r\n\r\n editor.caret.inputIndex = index + 1;\r\n editor.caret.set(nextInput, 0, 0);\r\n editor.content.workingNodeChanged(nextInput);\r\n };\r\n\r\n /**\r\n * @param {int} index - index of target input.\r\n * Sets caret to input with this index\r\n */\r\n caret.setToBlock = function (index) {\r\n var inputs = editor.state.inputs,\r\n targetInput = inputs[index];\r\n\r\n if ( !targetInput ) {\r\n return;\r\n }\r\n\r\n /**\r\n * When new Block created or deleted content of input\r\n * We should add some text node to set caret\r\n */\r\n if (!targetInput.childNodes.length) {\r\n var emptyTextElement = document.createTextNode('');\r\n\r\n targetInput.appendChild(emptyTextElement);\r\n }\r\n\r\n editor.caret.inputIndex = index;\r\n editor.caret.set(targetInput, 0, 0);\r\n editor.content.workingNodeChanged(targetInput);\r\n };\r\n\r\n /**\r\n * @param {int} index - index of input\r\n */\r\n caret.setToPreviousBlock = function (index) {\r\n index = index || 0;\r\n\r\n var inputs = editor.state.inputs,\r\n previousInput = inputs[index - 1],\r\n lastChildNode,\r\n lengthOfLastChildNode,\r\n emptyTextElement;\r\n\r\n\r\n if (!previousInput) {\r\n editor.core.log('We are reached first node');\r\n return;\r\n }\r\n\r\n lastChildNode = editor.content.getDeepestTextNodeFromPosition(previousInput, previousInput.childNodes.length);\r\n lengthOfLastChildNode = lastChildNode.length;\r\n\r\n /**\r\n * When new Block created or deleted content of input\r\n * We should add some text node to set caret\r\n */\r\n if (!previousInput.childNodes.length) {\r\n emptyTextElement = document.createTextNode('');\r\n previousInput.appendChild(emptyTextElement);\r\n }\r\n editor.caret.inputIndex = index - 1;\r\n editor.caret.set(previousInput, previousInput.childNodes.length - 1, lengthOfLastChildNode);\r\n editor.content.workingNodeChanged(inputs[index - 1]);\r\n };\r\n\r\n caret.position = {\r\n\r\n atStart : function () {\r\n var selection = window.getSelection(),\r\n anchorOffset = selection.anchorOffset,\r\n anchorNode = selection.anchorNode,\r\n firstLevelBlock = editor.content.getFirstLevelBlock(anchorNode),\r\n pluginsRender = firstLevelBlock.childNodes[0];\r\n\r\n if (!editor.core.isDomNode(anchorNode)) {\r\n anchorNode = anchorNode.parentNode;\r\n }\r\n\r\n var isFirstNode = anchorNode === pluginsRender.childNodes[0],\r\n isOffsetZero = anchorOffset === 0;\r\n\r\n return isFirstNode && isOffsetZero;\r\n },\r\n\r\n atTheEnd : function () {\r\n var selection = window.getSelection(),\r\n anchorOffset = selection.anchorOffset,\r\n anchorNode = selection.anchorNode;\r\n\r\n /** Caret is at the end of input */\r\n return !anchorNode || !anchorNode.length || anchorOffset === anchorNode.length;\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Inserts node at the caret location\r\n * @param {HTMLElement|DocumentFragment} node\r\n */\r\n caret.insertNode = function (node) {\r\n var selection, range,\r\n lastNode = node;\r\n\r\n if (node.nodeType == editor.core.nodeTypes.DOCUMENT_FRAGMENT) {\r\n lastNode = node.lastChild;\r\n }\r\n\r\n selection = window.getSelection();\r\n\r\n range = selection.getRangeAt(0);\r\n range.deleteContents();\r\n\r\n range.insertNode(node);\r\n\r\n range.setStartAfter(lastNode);\r\n range.collapse(true);\r\n\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n };\r\n\r\n return caret;\r\n})({});","/**\r\n * Codex Editor Content Module\r\n * Works with DOM\r\n *\r\n * @class Content\r\n * @classdesc Class works provides COdex Editor appearance logic\r\n *\r\n * @author Codex Team\r\n * @version 2.0.0\r\n */\r\n\r\nimport $ from '../dom';\r\n\r\nmodule.exports = class Content {\r\n /**\r\n * Module key name\r\n * @returns {string}\r\n */\r\n static get name() {\r\n return 'Content';\r\n }\r\n\r\n /**\r\n * @constructor\r\n *\r\n * @param {EditorConfig} config\r\n */\r\n constructor(config) {\r\n this.config = config;\r\n this.Editor = null;\r\n\r\n this.CSS = {\r\n block: 'ce-block',\r\n content: 'ce-block__content',\r\n stretched: 'ce-block--stretched',\r\n highlighted: 'ce-block--highlighted',\r\n };\r\n\r\n this._currentNode = null;\r\n this._currentIndex = 0;\r\n }\r\n\r\n /**\r\n * Editor modules setter\r\n * @param {object} Editor\r\n */\r\n set state(Editor) {\r\n this.Editor = Editor;\r\n }\r\n\r\n /**\r\n * Get current working node\r\n *\r\n * @returns {null|HTMLElement}\r\n */\r\n get currentNode() {\r\n return this._currentNode;\r\n }\r\n\r\n /**\r\n * Set working node. Working node should be first level block, so we find it before set one to _currentNode property\r\n *\r\n * @param {HTMLElement} node\r\n */\r\n set currentNode(node) {\r\n let firstLevelBlock = this.getFirstLevelBlock(node);\r\n\r\n this._currentNode = firstLevelBlock;\r\n }\r\n\r\n\r\n /**\r\n * @private\r\n * @param pluginHTML\r\n * @param {Boolean} isStretched - make stretched block or not\r\n *\r\n * @description adds necessary information to wrap new created block by first-level holder\r\n */\r\n composeBlock_(pluginHTML, isStretched = false) {\r\n let block = $.make('DIV', this.CSS.block),\r\n blockContent = $.make('DIV', this.CSS.content);\r\n\r\n blockContent.appendChild(pluginHTML);\r\n block.appendChild(blockContent);\r\n\r\n if (isStretched) {\r\n blockContent.classList.add(this.CSS.stretched);\r\n }\r\n\r\n block.dataset.toolId = this._currentIndex++;\r\n\r\n return block;\r\n };\r\n\r\n /**\r\n * Finds first-level block\r\n * @description looks for first-level block.\r\n * gets parent while node is not first-level\r\n *\r\n * @param {Element} node - selected or clicked in redactors area node\r\n * @protected\r\n *\r\n */\r\n getFirstLevelBlock(node) {\r\n if (!$.isElement(node)) {\r\n node = node.parentNode;\r\n }\r\n\r\n if (node === this.Editor.ui.nodes.redactor || node === document.body) {\r\n return null;\r\n } else {\r\n while(node.classList && !node.classList.contains(this.CSS.block)) {\r\n node = node.parentNode;\r\n }\r\n\r\n return node;\r\n }\r\n };\r\n\r\n /**\r\n * Insert new block to working area\r\n *\r\n * @param {HTMLElement} tool\r\n *\r\n * @returns {Number} tool index\r\n *\r\n */\r\n insertBlock(tool) {\r\n let newBlock = this.composeBlock_(tool);\r\n\r\n if (this.currentNode) {\r\n this.currentNode.insertAdjacentElement('afterend', newBlock);\r\n } else {\r\n /**\r\n * If redactor is empty, append as first child\r\n */\r\n this.Editor.ui.nodes.redactor.appendChild(newBlock);\r\n }\r\n\r\n /**\r\n * Set new node as current\r\n */\r\n this.currentNode = newBlock;\r\n\r\n return newBlock.dataset.toolId;\r\n }\r\n};\r\n\r\n// module.exports = (function (content) {\r\n//\r\n// let editor = codex.editor;\r\n//\r\n// /**\r\n// * Links to current active block\r\n// * @type {null | Element}\r\n// */\r\n// content.currentNode = null;\r\n//\r\n// /**\r\n// * clicked in redactor area\r\n// * @type {null | Boolean}\r\n// */\r\n// content.editorAreaHightlighted = null;\r\n//\r\n// /**\r\n// * @deprecated\r\n// * Synchronizes redactor with original textarea\r\n// */\r\n// content.sync = function () {\r\n//\r\n// editor.core.log('syncing...');\r\n//\r\n// /**\r\n// * Save redactor content to editor.state\r\n// */\r\n// editor.state.html = editor.nodes.redactor.innerHTML;\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Appends background to the block\r\n// *\r\n// * @description add CSS class to highlight visually first-level block area\r\n// */\r\n// content.markBlock = function () {\r\n//\r\n// editor.content.currentNode.classList.add(editor.ui.className.BLOCK_HIGHLIGHTED);\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Clear background\r\n// *\r\n// * @description clears styles that highlights block\r\n// */\r\n// content.clearMark = function () {\r\n//\r\n// if (editor.content.currentNode) {\r\n//\r\n// editor.content.currentNode.classList.remove(editor.ui.className.BLOCK_HIGHLIGHTED);\r\n//\r\n// }\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Finds first-level block\r\n// *\r\n// * @param {Element} node - selected or clicked in redactors area node\r\n// * @protected\r\n// *\r\n// * @description looks for first-level block.\r\n// * gets parent while node is not first-level\r\n// */\r\n// content.getFirstLevelBlock = function (node) {\r\n//\r\n// if (!editor.core.isDomNode(node)) {\r\n//\r\n// node = node.parentNode;\r\n//\r\n// }\r\n//\r\n// if (node === editor.nodes.redactor || node === document.body) {\r\n//\r\n// return null;\r\n//\r\n// } else {\r\n//\r\n// while(!node.classList.contains(editor.ui.className.BLOCK_CLASSNAME)) {\r\n//\r\n// node = node.parentNode;\r\n//\r\n// }\r\n//\r\n// return node;\r\n//\r\n// }\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Trigger this event when working node changed\r\n// * @param {Element} targetNode - first-level of this node will be current\r\n// * @protected\r\n// *\r\n// * @description If targetNode is first-level then we set it as current else we look for parents to find first-level\r\n// */\r\n// content.workingNodeChanged = function (targetNode) {\r\n//\r\n// /** Clear background from previous marked block before we change */\r\n// editor.content.clearMark();\r\n//\r\n// if (!targetNode) {\r\n//\r\n// return;\r\n//\r\n// }\r\n//\r\n// content.currentNode = content.getFirstLevelBlock(targetNode);\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Replaces one redactor block with another\r\n// * @protected\r\n// * @param {Element} targetBlock - block to replace. Mostly currentNode.\r\n// * @param {Element} newBlock\r\n// * @param {string} newBlockType - type of new block; we need to store it to data-attribute\r\n// *\r\n// * [!] Function does not saves old block content.\r\n// * You can get it manually and pass with newBlock.innerHTML\r\n// */\r\n// content.replaceBlock = function (targetBlock, newBlock) {\r\n//\r\n// if (!targetBlock || !newBlock) {\r\n//\r\n// editor.core.log('replaceBlock: missed params');\r\n// return;\r\n//\r\n// }\r\n//\r\n// /** If target-block is not a frist-level block, then we iterate parents to find it */\r\n// while(!targetBlock.classList.contains(editor.ui.className.BLOCK_CLASSNAME)) {\r\n//\r\n// targetBlock = targetBlock.parentNode;\r\n//\r\n// }\r\n//\r\n// /** Replacing */\r\n// editor.nodes.redactor.replaceChild(newBlock, targetBlock);\r\n//\r\n// /**\r\n// * Set new node as current\r\n// */\r\n// editor.content.workingNodeChanged(newBlock);\r\n//\r\n// /**\r\n// * Add block handlers\r\n// */\r\n// editor.ui.addBlockHandlers(newBlock);\r\n//\r\n// /**\r\n// * Save changes\r\n// */\r\n// editor.ui.saveInputs();\r\n//\r\n// };\r\n//\r\n// /**\r\n// * @protected\r\n// *\r\n// * Inserts new block to redactor\r\n// * Wrapps block into a DIV with BLOCK_CLASSNAME class\r\n// *\r\n// * @param blockData {object}\r\n// * @param blockData.block {Element} element with block content\r\n// * @param blockData.type {string} block plugin\r\n// * @param needPlaceCaret {bool} pass true to set caret in new block\r\n// *\r\n// */\r\n// content.insertBlock = function ( blockData, needPlaceCaret ) {\r\n//\r\n// var workingBlock = editor.content.currentNode,\r\n// newBlockContent = blockData.block,\r\n// blockType = blockData.type,\r\n// isStretched = blockData.stretched;\r\n//\r\n// var newBlock = composeNewBlock_(newBlockContent, blockType, isStretched);\r\n//\r\n// if (workingBlock) {\r\n//\r\n// editor.core.insertAfter(workingBlock, newBlock);\r\n//\r\n// } else {\r\n//\r\n// /**\r\n// * If redactor is empty, append as first child\r\n// */\r\n// editor.nodes.redactor.appendChild(newBlock);\r\n//\r\n// }\r\n//\r\n// /**\r\n// * Block handler\r\n// */\r\n// editor.ui.addBlockHandlers(newBlock);\r\n//\r\n// /**\r\n// * Set new node as current\r\n// */\r\n// editor.content.workingNodeChanged(newBlock);\r\n//\r\n// /**\r\n// * Save changes\r\n// */\r\n// editor.ui.saveInputs();\r\n//\r\n//\r\n// if ( needPlaceCaret ) {\r\n//\r\n// /**\r\n// * If we don't know input index then we set default value -1\r\n// */\r\n// var currentInputIndex = editor.caret.getCurrentInputIndex() || -1;\r\n//\r\n//\r\n// if (currentInputIndex == -1) {\r\n//\r\n//\r\n// var editableElement = newBlock.querySelector('[contenteditable]'),\r\n// emptyText = document.createTextNode('');\r\n//\r\n// editableElement.appendChild(emptyText);\r\n// editor.caret.set(editableElement, 0, 0);\r\n//\r\n// editor.toolbar.move();\r\n// editor.toolbar.showPlusButton();\r\n//\r\n//\r\n// } else {\r\n//\r\n// if (currentInputIndex === editor.state.inputs.length - 1)\r\n// return;\r\n//\r\n// /** Timeout for browsers execution */\r\n// window.setTimeout(function () {\r\n//\r\n// /** Setting to the new input */\r\n// editor.caret.setToNextBlock(currentInputIndex);\r\n// editor.toolbar.move();\r\n// editor.toolbar.open();\r\n//\r\n// }, 10);\r\n//\r\n// }\r\n//\r\n// }\r\n//\r\n// /**\r\n// * Block is inserted, wait for new click that defined focusing on editors area\r\n// * @type {boolean}\r\n// */\r\n// content.editorAreaHightlighted = false;\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Replaces blocks with saving content\r\n// * @protected\r\n// * @param {Element} noteToReplace\r\n// * @param {Element} newNode\r\n// * @param {Element} blockType\r\n// */\r\n// content.switchBlock = function (blockToReplace, newBlock, tool) {\r\n//\r\n// tool = tool || editor.content.currentNode.dataset.tool;\r\n// var newBlockComposed = composeNewBlock_(newBlock, tool);\r\n//\r\n// /** Replacing */\r\n// editor.content.replaceBlock(blockToReplace, newBlockComposed);\r\n//\r\n// /** Save new Inputs when block is changed */\r\n// editor.ui.saveInputs();\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Iterates between child noted and looking for #text node on deepest level\r\n// * @protected\r\n// *\r\n// * @param {Element} block - node where find\r\n// * @param {int} postiton - starting postion\r\n// * Example: childNodex.length to find from the end\r\n// * or 0 to find from the start\r\n// * @return {Text} block\r\n// * @uses DFS\r\n// */\r\n// content.getDeepestTextNodeFromPosition = function (block, position) {\r\n//\r\n// /**\r\n// * Clear Block from empty and useless spaces with trim.\r\n// * Such nodes we should remove\r\n// */\r\n// var blockChilds = block.childNodes,\r\n// index,\r\n// node,\r\n// text;\r\n//\r\n// for(index = 0; index < blockChilds.length; index++) {\r\n//\r\n// node = blockChilds[index];\r\n//\r\n// if (node.nodeType == editor.core.nodeTypes.TEXT) {\r\n//\r\n// text = node.textContent.trim();\r\n//\r\n// /** Text is empty. We should remove this child from node before we start DFS\r\n// * decrease the quantity of childs.\r\n// */\r\n// if (text === '') {\r\n//\r\n// block.removeChild(node);\r\n// position--;\r\n//\r\n// }\r\n//\r\n// }\r\n//\r\n// }\r\n//\r\n// if (block.childNodes.length === 0) {\r\n//\r\n// return document.createTextNode('');\r\n//\r\n// }\r\n//\r\n// /** Setting default position when we deleted all empty nodes */\r\n// if ( position < 0 )\r\n// position = 1;\r\n//\r\n// var lookingFromStart = false;\r\n//\r\n// /** For looking from START */\r\n// if (position === 0) {\r\n//\r\n// lookingFromStart = true;\r\n// position = 1;\r\n//\r\n// }\r\n//\r\n// while ( position ) {\r\n//\r\n// /** initial verticle of node. */\r\n// if ( lookingFromStart ) {\r\n//\r\n// block = block.childNodes[0];\r\n//\r\n// } else {\r\n//\r\n// block = block.childNodes[position - 1];\r\n//\r\n// }\r\n//\r\n// if ( block.nodeType == editor.core.nodeTypes.TAG ) {\r\n//\r\n// position = block.childNodes.length;\r\n//\r\n// } else if (block.nodeType == editor.core.nodeTypes.TEXT ) {\r\n//\r\n// position = 0;\r\n//\r\n// }\r\n//\r\n// }\r\n//\r\n// return block;\r\n//\r\n// };\r\n//\r\n// /**\r\n// * @private\r\n// * @param {Element} block - current plugins render\r\n// * @param {String} tool - plugins name\r\n// * @param {Boolean} isStretched - make stretched block or not\r\n// *\r\n// * @description adds necessary information to wrap new created block by first-level holder\r\n// */\r\n// var composeNewBlock_ = function (block, tool, isStretched) {\r\n//\r\n// var newBlock = editor.draw.node('DIV', editor.ui.className.BLOCK_CLASSNAME, {}),\r\n// blockContent = editor.draw.node('DIV', editor.ui.className.BLOCK_CONTENT, {});\r\n//\r\n// blockContent.appendChild(block);\r\n// newBlock.appendChild(blockContent);\r\n//\r\n// if (isStretched) {\r\n//\r\n// blockContent.classList.add(editor.ui.className.BLOCK_STRETCHED);\r\n//\r\n// }\r\n//\r\n// newBlock.dataset.tool = tool;\r\n// return newBlock;\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Returns Range object of current selection\r\n// * @protected\r\n// */\r\n// content.getRange = function () {\r\n//\r\n// var selection = window.getSelection().getRangeAt(0);\r\n//\r\n// return selection;\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Divides block in two blocks (after and before caret)\r\n// *\r\n// * @protected\r\n// * @param {int} inputIndex - target input index\r\n// *\r\n// * @description splits current input content to the separate blocks\r\n// * When enter is pressed among the words, that text will be splited.\r\n// */\r\n// content.splitBlock = function (inputIndex) {\r\n//\r\n// var selection = window.getSelection(),\r\n// anchorNode = selection.anchorNode,\r\n// anchorNodeText = anchorNode.textContent,\r\n// caretOffset = selection.anchorOffset,\r\n// textBeforeCaret,\r\n// textNodeBeforeCaret,\r\n// textAfterCaret,\r\n// textNodeAfterCaret;\r\n//\r\n// var currentBlock = editor.content.currentNode.querySelector('[contentEditable]');\r\n//\r\n//\r\n// textBeforeCaret = anchorNodeText.substring(0, caretOffset);\r\n// textAfterCaret = anchorNodeText.substring(caretOffset);\r\n//\r\n// textNodeBeforeCaret = document.createTextNode(textBeforeCaret);\r\n//\r\n// if (textAfterCaret) {\r\n//\r\n// textNodeAfterCaret = document.createTextNode(textAfterCaret);\r\n//\r\n// }\r\n//\r\n// var previousChilds = [],\r\n// nextChilds = [],\r\n// reachedCurrent = false;\r\n//\r\n// if (textNodeAfterCaret) {\r\n//\r\n// nextChilds.push(textNodeAfterCaret);\r\n//\r\n// }\r\n//\r\n// for ( var i = 0, child; !!(child = currentBlock.childNodes[i]); i++) {\r\n//\r\n// if ( child != anchorNode ) {\r\n//\r\n// if ( !reachedCurrent ) {\r\n//\r\n// previousChilds.push(child);\r\n//\r\n// } else {\r\n//\r\n// nextChilds.push(child);\r\n//\r\n// }\r\n//\r\n// } else {\r\n//\r\n// reachedCurrent = true;\r\n//\r\n// }\r\n//\r\n// }\r\n//\r\n// /** Clear current input */\r\n// editor.state.inputs[inputIndex].innerHTML = '';\r\n//\r\n// /**\r\n// * Append all childs founded before anchorNode\r\n// */\r\n// var previousChildsLength = previousChilds.length;\r\n//\r\n// for(i = 0; i < previousChildsLength; i++) {\r\n//\r\n// editor.state.inputs[inputIndex].appendChild(previousChilds[i]);\r\n//\r\n// }\r\n//\r\n// editor.state.inputs[inputIndex].appendChild(textNodeBeforeCaret);\r\n//\r\n// /**\r\n// * Append text node which is after caret\r\n// */\r\n// var nextChildsLength = nextChilds.length,\r\n// newNode = document.createElement('div');\r\n//\r\n// for(i = 0; i < nextChildsLength; i++) {\r\n//\r\n// newNode.appendChild(nextChilds[i]);\r\n//\r\n// }\r\n//\r\n// newNode = newNode.innerHTML;\r\n//\r\n// /** This type of block creates when enter is pressed */\r\n// var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;\r\n//\r\n// /**\r\n// * Make new paragraph with text after caret\r\n// */\r\n// editor.content.insertBlock({\r\n// type : NEW_BLOCK_TYPE,\r\n// block : editor.tools[NEW_BLOCK_TYPE].render({\r\n// text : newNode\r\n// })\r\n// }, true );\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Merges two blocks — current and target\r\n// * If target index is not exist, then previous will be as target\r\n// *\r\n// * @protected\r\n// * @param {int} currentInputIndex\r\n// * @param {int} targetInputIndex\r\n// *\r\n// * @description gets two inputs indexes and merges into one\r\n// */\r\n// content.mergeBlocks = function (currentInputIndex, targetInputIndex) {\r\n//\r\n// /** If current input index is zero, then prevent method execution */\r\n// if (currentInputIndex === 0) {\r\n//\r\n// return;\r\n//\r\n// }\r\n//\r\n// var targetInput,\r\n// currentInputContent = editor.state.inputs[currentInputIndex].innerHTML;\r\n//\r\n// if (!targetInputIndex) {\r\n//\r\n// targetInput = editor.state.inputs[currentInputIndex - 1];\r\n//\r\n// } else {\r\n//\r\n// targetInput = editor.state.inputs[targetInputIndex];\r\n//\r\n// }\r\n//\r\n// targetInput.innerHTML += currentInputContent;\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Iterates all right siblings and parents, which has right siblings\r\n// * while it does not reached the first-level block\r\n// *\r\n// * @param {Element} node\r\n// * @return {boolean}\r\n// */\r\n// content.isLastNode = function (node) {\r\n//\r\n// // console.log('погнали перебор родителей');\r\n//\r\n// var allChecked = false;\r\n//\r\n// while ( !allChecked ) {\r\n//\r\n// // console.log('Смотрим на %o', node);\r\n// // console.log('Проверим, пустые ли соседи справа');\r\n//\r\n// if ( !allSiblingsEmpty_(node) ) {\r\n//\r\n// // console.log('Есть непустые соседи. Узел не последний. Выходим.');\r\n// return false;\r\n//\r\n// }\r\n//\r\n// node = node.parentNode;\r\n//\r\n// /**\r\n// * Проверяем родителей до тех пор, пока не найдем блок первого уровня\r\n// */\r\n// if ( node.classList.contains(editor.ui.className.BLOCK_CONTENT) ) {\r\n//\r\n// allChecked = true;\r\n//\r\n// }\r\n//\r\n// }\r\n//\r\n// return true;\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Checks if all element right siblings is empty\r\n// * @param node\r\n// */\r\n// var allSiblingsEmpty_ = function (node) {\r\n//\r\n// /**\r\n// * Нужно убедиться, что после пустого соседа ничего нет\r\n// */\r\n// var sibling = node.nextSibling;\r\n//\r\n// while ( sibling ) {\r\n//\r\n// if (sibling.textContent.length) {\r\n//\r\n// return false;\r\n//\r\n// }\r\n//\r\n// sibling = sibling.nextSibling;\r\n//\r\n// }\r\n//\r\n// return true;\r\n//\r\n// };\r\n//\r\n// /**\r\n// * @public\r\n// *\r\n// * @param {string} htmlData - html content as string\r\n// * @param {string} plainData - plain text\r\n// * @return {string} - html content as string\r\n// */\r\n// content.wrapTextWithParagraphs = function (htmlData, plainData) {\r\n//\r\n// if (!htmlData.trim()) {\r\n//\r\n// return wrapPlainTextWithParagraphs(plainData);\r\n//\r\n// }\r\n//\r\n// var wrapper = document.createElement('DIV'),\r\n// newWrapper = document.createElement('DIV'),\r\n// i,\r\n// paragraph,\r\n// firstLevelBlocks = ['DIV', 'P'],\r\n// blockTyped,\r\n// node;\r\n//\r\n// /**\r\n// * Make HTML Element to Wrap Text\r\n// * It allows us to work with input data as HTML content\r\n// */\r\n// wrapper.innerHTML = htmlData;\r\n// paragraph = document.createElement('P');\r\n//\r\n// for (i = 0; i < wrapper.childNodes.length; i++) {\r\n//\r\n// node = wrapper.childNodes[i];\r\n//\r\n// blockTyped = firstLevelBlocks.indexOf(node.tagName) != -1;\r\n//\r\n// /**\r\n// * If node is first-levet\r\n// * we add this node to our new wrapper\r\n// */\r\n// if ( blockTyped ) {\r\n//\r\n// /**\r\n// * If we had splitted inline nodes to paragraph before\r\n// */\r\n// if ( paragraph.childNodes.length ) {\r\n//\r\n// newWrapper.appendChild(paragraph.cloneNode(true));\r\n//\r\n// /** empty paragraph */\r\n// paragraph = null;\r\n// paragraph = document.createElement('P');\r\n//\r\n// }\r\n//\r\n// newWrapper.appendChild(node.cloneNode(true));\r\n//\r\n// } else {\r\n//\r\n// /** Collect all inline nodes to one as paragraph */\r\n// paragraph.appendChild(node.cloneNode(true));\r\n//\r\n// /** if node is last we should append this node to paragraph and paragraph to new wrapper */\r\n// if ( i == wrapper.childNodes.length - 1 ) {\r\n//\r\n// newWrapper.appendChild(paragraph.cloneNode(true));\r\n//\r\n// }\r\n//\r\n// }\r\n//\r\n// }\r\n//\r\n// return newWrapper.innerHTML;\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Splits strings on new line and wraps paragraphs with

    tag\r\n// * @param plainText\r\n// * @returns {string}\r\n// */\r\n// var wrapPlainTextWithParagraphs = function (plainText) {\r\n//\r\n// if (!plainText) return '';\r\n//\r\n// return '

    ' + plainText.split('\\n\\n').join('

    ') + '

    ';\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Finds closest Contenteditable parent from Element\r\n// * @param {Element} node element looking from\r\n// * @return {Element} node contenteditable\r\n// */\r\n// content.getEditableParent = function (node) {\r\n//\r\n// while (node && node.contentEditable != 'true') {\r\n//\r\n// node = node.parentNode;\r\n//\r\n// }\r\n//\r\n// return node;\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Clear editors content\r\n// *\r\n// * @param {Boolean} all — if true, delete all article data (content, id, etc.)\r\n// */\r\n// content.clear = function (all) {\r\n//\r\n// editor.nodes.redactor.innerHTML = '';\r\n// editor.content.sync();\r\n// editor.ui.saveInputs();\r\n// if (all) {\r\n//\r\n// editor.state.blocks = {};\r\n//\r\n// } else if (editor.state.blocks) {\r\n//\r\n// editor.state.blocks.items = [];\r\n//\r\n// }\r\n//\r\n// editor.content.currentNode = null;\r\n//\r\n// };\r\n//\r\n// /**\r\n// *\r\n// * Load new data to editor\r\n// * If editor is not empty, just append articleData.items\r\n// *\r\n// * @param articleData.items\r\n// */\r\n// content.load = function (articleData) {\r\n//\r\n// var currentContent = Object.assign({}, editor.state.blocks);\r\n//\r\n// editor.content.clear();\r\n//\r\n// if (!Object.keys(currentContent).length) {\r\n//\r\n// editor.state.blocks = articleData;\r\n//\r\n// } else if (!currentContent.items) {\r\n//\r\n// currentContent.items = articleData.items;\r\n// editor.state.blocks = currentContent;\r\n//\r\n// } else {\r\n//\r\n// currentContent.items = currentContent.items.concat(articleData.items);\r\n// editor.state.blocks = currentContent;\r\n//\r\n// }\r\n//\r\n// editor.renderer.makeBlocksFromData();\r\n//\r\n// };\r\n//\r\n// return content;\r\n//\r\n// })({});","/**\r\n * Codex Editor Destroyer module\r\n *\r\n * @auhor Codex Team\r\n * @version 1.0\r\n */\r\n\r\nmodule.exports = function (destroyer) {\r\n let editor = codex.editor;\r\n\r\n destroyer.removeNodes = function () {\r\n editor.nodes.wrapper.remove();\r\n editor.nodes.notifications.remove();\r\n };\r\n\r\n destroyer.destroyPlugins = function () {\r\n for (var tool in editor.tools) {\r\n if (typeof editor.tools[tool].destroy === 'function') {\r\n editor.tools[tool].destroy();\r\n }\r\n }\r\n };\r\n\r\n destroyer.destroyScripts = function () {\r\n var scripts = document.getElementsByTagName('SCRIPT');\r\n\r\n for (var i = 0; i < scripts.length; i++) {\r\n if (scripts[i].id.indexOf(editor.scriptPrefix) + 1) {\r\n scripts[i].remove();\r\n i--;\r\n }\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Delete editor data from webpage.\r\n * You should send settings argument with boolean flags:\r\n * @param settings.ui- remove redactor event listeners and DOM nodes\r\n * @param settings.scripts - remove redactor scripts from DOM\r\n * @param settings.plugins - remove plugin's objects\r\n * @param settings.core - remove editor core. You can remove core only if UI and scripts flags is true\r\n * }\r\n *\r\n */\r\n destroyer.destroy = function (settings) {\r\n if (!settings || typeof settings !== 'object') {\r\n return;\r\n }\r\n\r\n if (settings.ui) {\r\n destroyer.removeNodes();\r\n editor.listeners.removeAll();\r\n }\r\n\r\n if (settings.scripts) {\r\n destroyer.destroyScripts();\r\n }\r\n\r\n if (settings.plugins) {\r\n destroyer.destroyPlugins();\r\n }\r\n\r\n if (settings.ui && settings.scripts && settings.core) {\r\n delete codex.editor;\r\n }\r\n };\r\n\r\n return destroyer;\r\n}({});","/**\r\n * Codex Editor Notification Module\r\n *\r\n * @author Codex Team\r\n * @version 1.0\r\n */\r\n\r\nmodule.exports = (function (notifications) {\r\n let editor = codex.editor;\r\n\r\n var queue = [];\r\n\r\n var addToQueue = function (settings) {\r\n queue.push(settings);\r\n\r\n var index = 0;\r\n\r\n while ( index < queue.length && queue.length > 5) {\r\n if (queue[index].type == 'confirm' || queue[index].type == 'prompt') {\r\n index++;\r\n continue;\r\n }\r\n\r\n queue[index].close();\r\n queue.splice(index, 1);\r\n }\r\n };\r\n\r\n notifications.createHolder = function () {\r\n var holder = editor.draw.node('DIV', 'cdx-notifications-block');\r\n\r\n editor.nodes.notifications = document.body.appendChild(holder);\r\n\r\n return holder;\r\n };\r\n\r\n\r\n /**\r\n * Error notificator. Shows block with message\r\n * @protected\r\n */\r\n notifications.errorThrown = function (errorMsg, event) {\r\n editor.notifications.notification({message: 'This action is not available currently', type: event.type});\r\n };\r\n\r\n /**\r\n *\r\n * Appends notification\r\n *\r\n * settings = {\r\n * type - notification type (reserved types: alert, confirm, prompt). Just add class 'cdx-notification-'+type\r\n * message - notification message\r\n * okMsg - confirm button text (default - 'Ok')\r\n * cancelBtn - cancel button text (default - 'Cancel'). Only for confirm and prompt types\r\n * confirm - function-handler for ok button click\r\n * cancel - function-handler for cancel button click. Only for confirm and prompt types\r\n * time - time (in seconds) after which notification will close (default - 10s)\r\n * }\r\n *\r\n * @param settings\r\n */\r\n notifications.notification = function (constructorSettings) {\r\n /** Private vars and methods */\r\n var notification = null,\r\n cancel = null,\r\n type = null,\r\n confirm = null,\r\n inputField = null;\r\n\r\n var confirmHandler = function () {\r\n close();\r\n\r\n if (typeof confirm !== 'function' ) {\r\n return;\r\n }\r\n\r\n if (type == 'prompt') {\r\n confirm(inputField.value);\r\n return;\r\n }\r\n\r\n confirm();\r\n };\r\n\r\n var cancelHandler = function () {\r\n close();\r\n\r\n if (typeof cancel !== 'function' ) {\r\n return;\r\n }\r\n\r\n cancel();\r\n };\r\n\r\n\r\n /** Public methods */\r\n function create(settings) {\r\n if (!(settings && settings.message)) {\r\n editor.core.log('Can\\'t create notification. Message is missed');\r\n return;\r\n }\r\n\r\n settings.type = settings.type || 'alert';\r\n settings.time = settings.time*1000 || 10000;\r\n\r\n var wrapper = editor.draw.node('DIV', 'cdx-notification'),\r\n message = editor.draw.node('DIV', 'cdx-notification__message'),\r\n input = editor.draw.node('INPUT', 'cdx-notification__input'),\r\n okBtn = editor.draw.node('SPAN', 'cdx-notification__ok-btn'),\r\n cancelBtn = editor.draw.node('SPAN', 'cdx-notification__cancel-btn');\r\n\r\n message.textContent = settings.message;\r\n okBtn.textContent = settings.okMsg || 'ОК';\r\n cancelBtn.textContent = settings.cancelMsg || 'Отмена';\r\n\r\n editor.listeners.add(okBtn, 'click', confirmHandler);\r\n editor.listeners.add(cancelBtn, 'click', cancelHandler);\r\n\r\n wrapper.appendChild(message);\r\n\r\n if (settings.type == 'prompt') {\r\n wrapper.appendChild(input);\r\n }\r\n\r\n wrapper.appendChild(okBtn);\r\n\r\n if (settings.type == 'prompt' || settings.type == 'confirm') {\r\n wrapper.appendChild(cancelBtn);\r\n }\r\n\r\n wrapper.classList.add('cdx-notification-' + settings.type);\r\n wrapper.dataset.type = settings.type;\r\n\r\n notification = wrapper;\r\n type = settings.type;\r\n confirm = settings.confirm;\r\n cancel = settings.cancel;\r\n inputField = input;\r\n\r\n if (settings.type != 'prompt' && settings.type != 'confirm') {\r\n window.setTimeout(close, settings.time);\r\n }\r\n };\r\n\r\n /**\r\n * Show notification block\r\n */\r\n function send() {\r\n editor.nodes.notifications.appendChild(notification);\r\n inputField.focus();\r\n\r\n editor.nodes.notifications.classList.add('cdx-notification__notification-appending');\r\n\r\n window.setTimeout(function () {\r\n editor.nodes.notifications.classList.remove('cdx-notification__notification-appending');\r\n }, 100);\r\n\r\n addToQueue({type: type, close: close});\r\n };\r\n\r\n /**\r\n * Remove notification block\r\n */\r\n function close() {\r\n notification.remove();\r\n };\r\n\r\n\r\n if (constructorSettings) {\r\n create(constructorSettings);\r\n send();\r\n }\r\n\r\n return {\r\n create: create,\r\n send: send,\r\n close: close\r\n };\r\n };\r\n\r\n notifications.clear = function () {\r\n editor.nodes.notifications.innerHTML = '';\r\n queue = [];\r\n };\r\n\r\n return notifications;\r\n})({});","/**\r\n * Codex Editor Parser Module\r\n *\r\n * @author Codex Team\r\n * @version 1.1\r\n */\r\n\r\nmodule.exports = (function (parser) {\r\n let editor = codex.editor;\r\n\r\n /** inserting text */\r\n parser.insertPastedContent = function (blockType, tag) {\r\n editor.content.insertBlock({\r\n type : blockType.type,\r\n block : blockType.render({\r\n text : tag.innerHTML\r\n })\r\n });\r\n };\r\n\r\n /**\r\n * Check DOM node for display style: separated block or child-view\r\n */\r\n parser.isFirstLevelBlock = function (node) {\r\n return node.nodeType == editor.core.nodeTypes.TAG &&\r\n node.classList.contains(editor.ui.className.BLOCK_CLASSNAME);\r\n };\r\n\r\n return parser;\r\n})({});\r\n","/**\r\n * Codex Editor Paste module\r\n *\r\n * @author Codex Team\r\n * @version 1.1.1\r\n */\r\n\r\nmodule.exports = function (paste) {\r\n let editor = codex.editor;\r\n\r\n var patterns = [];\r\n\r\n paste.prepare = function () {\r\n var tools = editor.tools;\r\n\r\n for (var tool in tools) {\r\n if (!tools[tool].renderOnPastePatterns || !Array.isArray(tools[tool].renderOnPastePatterns)) {\r\n continue;\r\n }\r\n\r\n tools[tool].renderOnPastePatterns.map(function (pattern) {\r\n patterns.push(pattern);\r\n });\r\n }\r\n\r\n return Promise.resolve();\r\n };\r\n\r\n /**\r\n * Saves data\r\n * @param event\r\n */\r\n paste.pasted = function (event) {\r\n var clipBoardData = event.clipboardData || window.clipboardData,\r\n content = clipBoardData.getData('Text');\r\n\r\n var result = analize(content);\r\n\r\n if (result) {\r\n event.preventDefault();\r\n event.stopImmediatePropagation();\r\n }\r\n\r\n return result;\r\n };\r\n\r\n /**\r\n * Analizes pated string and calls necessary method\r\n */\r\n\r\n var analize = function (string) {\r\n var result = false,\r\n content = editor.content.currentNode,\r\n plugin = content.dataset.tool;\r\n\r\n patterns.map( function (pattern) {\r\n var execArray = pattern.regex.exec(string),\r\n match = execArray && execArray[0];\r\n\r\n if ( match && match === string.trim()) {\r\n /** current block is not empty */\r\n if ( content.textContent.trim() && plugin == editor.settings.initialBlockPlugin ) {\r\n pasteToNewBlock_();\r\n }\r\n\r\n pattern.callback(string, pattern);\r\n result = true;\r\n }\r\n });\r\n\r\n return result;\r\n };\r\n\r\n var pasteToNewBlock_ = function () {\r\n /** Create new initial block */\r\n editor.content.insertBlock({\r\n\r\n type : editor.settings.initialBlockPlugin,\r\n block : editor.tools[editor.settings.initialBlockPlugin].render({\r\n text : ''\r\n })\r\n\r\n }, false);\r\n };\r\n\r\n /**\r\n * This method prevents default behaviour.\r\n *\r\n * @param {Object} event\r\n * @protected\r\n *\r\n * @description We get from clipboard pasted data, sanitize, make a fragment that contains of this sanitized nodes.\r\n * Firstly, we need to memorize the caret position. We can do that by getting the range of selection.\r\n * After all, we insert clear fragment into caret placed position. Then, we should move the caret to the last node\r\n */\r\n paste.blockPasteCallback = function (event) {\r\n if (!needsToHandlePasteEvent(event.target)) {\r\n return;\r\n }\r\n\r\n /** Prevent default behaviour */\r\n event.preventDefault();\r\n\r\n /** get html pasted data - dirty data */\r\n var htmlData = event.clipboardData.getData('text/html'),\r\n plainData = event.clipboardData.getData('text/plain');\r\n\r\n /** Temporary DIV that is used to work with text's paragraphs as DOM-elements*/\r\n var paragraphs = editor.draw.node('DIV', '', {}),\r\n cleanData,\r\n wrappedData;\r\n\r\n /** Create fragment, that we paste to range after proccesing */\r\n cleanData = editor.sanitizer.clean(htmlData);\r\n\r\n /**\r\n * We wrap pasted text with

    tags to split it logically\r\n * @type {string}\r\n */\r\n wrappedData = editor.content.wrapTextWithParagraphs(cleanData, plainData);\r\n paragraphs.innerHTML = wrappedData;\r\n\r\n /**\r\n * If there only one paragraph, just insert in at the caret location\r\n */\r\n if (paragraphs.childNodes.length == 1) {\r\n emulateUserAgentBehaviour(paragraphs.firstChild);\r\n return;\r\n }\r\n\r\n insertPastedParagraphs(paragraphs.childNodes);\r\n };\r\n\r\n /**\r\n * Checks if we should handle paste event on block\r\n * @param block\r\n *\r\n * @return {boolean}\r\n */\r\n var needsToHandlePasteEvent = function (block) {\r\n /** If area is input or textarea then allow default behaviour */\r\n if ( editor.core.isNativeInput(block) ) {\r\n return false;\r\n }\r\n\r\n var editableParent = editor.content.getEditableParent(block);\r\n\r\n /** Allow paste when event target placed in Editable element */\r\n if (!editableParent) {\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n /**\r\n * Inserts new initial plugin blocks with data in paragraphs\r\n *\r\n * @param {Array} paragraphs - array of paragraphs (

    ) whit content, that should be inserted\r\n */\r\n var insertPastedParagraphs = function (paragraphs) {\r\n var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin,\r\n currentNode = editor.content.currentNode;\r\n\r\n\r\n paragraphs.forEach(function (paragraph) {\r\n /** Don't allow empty paragraphs */\r\n if (editor.core.isBlockEmpty(paragraph)) {\r\n return;\r\n }\r\n\r\n editor.content.insertBlock({\r\n type : NEW_BLOCK_TYPE,\r\n block : editor.tools[NEW_BLOCK_TYPE].render({\r\n text : paragraph.innerHTML\r\n })\r\n });\r\n\r\n editor.caret.inputIndex++;\r\n });\r\n\r\n editor.caret.setToPreviousBlock(editor.caret.getCurrentInputIndex() + 1);\r\n\r\n\r\n /**\r\n * If there was no data in working node, remove it\r\n */\r\n if (editor.core.isBlockEmpty(currentNode)) {\r\n currentNode.remove();\r\n editor.ui.saveInputs();\r\n }\r\n };\r\n\r\n /**\r\n * Inserts node content at the caret position\r\n *\r\n * @param {Node} node - DOM node (could be DocumentFragment), that should be inserted at the caret location\r\n */\r\n var emulateUserAgentBehaviour = function (node) {\r\n var newNode;\r\n\r\n if (node.childElementCount) {\r\n newNode = document.createDocumentFragment();\r\n\r\n node.childNodes.forEach(function (current) {\r\n if (!editor.core.isDomNode(current) && current.data.trim() === '') {\r\n return;\r\n }\r\n\r\n newNode.appendChild(current.cloneNode(true));\r\n });\r\n } else {\r\n newNode = document.createTextNode(node.textContent);\r\n }\r\n\r\n editor.caret.insertNode(newNode);\r\n };\r\n\r\n\r\n return paste;\r\n}({});","/**\r\n *\r\n * Codex.Editor Transport Module\r\n *\r\n * @copyright 2017 Codex-Team\r\n * @version 1.2.0\r\n */\r\n\r\nmodule.exports = (function (transport) {\r\n let editor = codex.editor;\r\n\r\n\r\n /**\r\n * @private {Object} current XmlHttpRequest instance\r\n */\r\n var currentRequest = null;\r\n\r\n\r\n /**\r\n * @type {null} | {DOMElement} input - keeps input element in memory\r\n */\r\n transport.input = null;\r\n\r\n /**\r\n * @property {Object} arguments - keep plugin settings and defined callbacks\r\n */\r\n transport.arguments = null;\r\n\r\n /**\r\n * Prepares input element where will be files\r\n */\r\n transport.prepare = function () {\r\n let input = editor.draw.node( 'INPUT', '', { type : 'file' } );\r\n\r\n editor.listeners.add(input, 'change', editor.transport.fileSelected);\r\n editor.transport.input = input;\r\n };\r\n\r\n /** Clear input when files is uploaded */\r\n transport.clearInput = function () {\r\n /** Remove old input */\r\n transport.input = null;\r\n\r\n /** Prepare new one */\r\n transport.prepare();\r\n };\r\n\r\n /**\r\n * Callback for file selection\r\n * @param {Event} event\r\n */\r\n transport.fileSelected = function () {\r\n var input = this,\r\n i,\r\n files = input.files,\r\n formData = new FormData();\r\n\r\n if (editor.transport.arguments.multiple === true) {\r\n for ( i = 0; i < files.length; i++) {\r\n formData.append('files[]', files[i], files[i].name);\r\n }\r\n } else {\r\n formData.append('files', files[0], files[0].name);\r\n }\r\n\r\n currentRequest = editor.core.ajax({\r\n type : 'POST',\r\n data : formData,\r\n url : editor.transport.arguments.url,\r\n beforeSend : editor.transport.arguments.beforeSend,\r\n success : editor.transport.arguments.success,\r\n error : editor.transport.arguments.error,\r\n progress : editor.transport.arguments.progress\r\n });\r\n\r\n /** Clear input */\r\n transport.clearInput();\r\n };\r\n\r\n /**\r\n * Use plugin callbacks\r\n * @protected\r\n *\r\n * @param {Object} args - can have :\r\n * @param {String} args.url - fetch URL\r\n * @param {Function} args.beforeSend - function calls before sending ajax\r\n * @param {Function} args.success - success callback\r\n * @param {Function} args.error - on error handler\r\n * @param {Function} args.progress - xhr onprogress handler\r\n * @param {Boolean} args.multiple - allow select several files\r\n * @param {String} args.accept - adds accept attribute\r\n */\r\n transport.selectAndUpload = function (args) {\r\n transport.arguments = args;\r\n\r\n if ( args.multiple === true) {\r\n transport.input.setAttribute('multiple', 'multiple');\r\n }\r\n\r\n if ( args.accept ) {\r\n transport.input.setAttribute('accept', args.accept);\r\n }\r\n\r\n transport.input.click();\r\n };\r\n\r\n transport.abort = function () {\r\n currentRequest.abort();\r\n\r\n currentRequest = null;\r\n };\r\n\r\n return transport;\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 * Save Editor config. API provides passed configuration to the Blocks\r\n */\r\n constructor({ config }) {\r\n super({ config });\r\n }\r\n /**\r\n * Available methods\r\n * @return {IBlocksAPI}\r\n */\r\n get methods() {\r\n return {\r\n clear: () => this.clear(),\r\n render: (data) => this.render(data),\r\n delete: () => this.delete(),\r\n swap: (fromIndex, toIndex) => this.swap(fromIndex, toIndex),\r\n getBlockByIndex: (index) => this.getBlockByIndex(index),\r\n getCurrentBlockIndex: () => this.getCurrentBlockIndex(),\r\n getBlocksCount: () => this.getBlocksCount(),\r\n };\r\n }\r\n /**\r\n * Returns Blocks count\r\n * @return {number}\r\n */\r\n getBlocksCount() {\r\n return this.Editor.BlockManager.blocks.length;\r\n }\r\n /**\r\n * Returns current block index\r\n * @return {number}\r\n */\r\n getCurrentBlockIndex() {\r\n return this.Editor.BlockManager.currentBlockIndex;\r\n }\r\n /**\r\n * Returns Current Block\r\n * @param {Number} index\r\n *\r\n * @return {Object}\r\n */\r\n getBlockByIndex(index) {\r\n return this.Editor.BlockManager.getBlockByIndex(index);\r\n }\r\n /**\r\n * Call Block Manager method that swap Blocks\r\n * @param {number} fromIndex - position of first Block\r\n * @param {number} toIndex - position of second Block\r\n */\r\n swap(fromIndex, toIndex) {\r\n this.Editor.BlockManager.swap(fromIndex, toIndex);\r\n /**\r\n * Move toolbar\r\n * DO not close the settings\r\n */\r\n this.Editor.Toolbar.move(false);\r\n }\r\n /**\r\n * Deletes Block\r\n * @param blockIndex\r\n */\r\n delete(blockIndex) {\r\n this.Editor.BlockManager.removeBlock(blockIndex);\r\n /**\r\n * in case of last block deletion\r\n * Insert new initial 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 * In case of deletion first block we need to set caret to the current Block\r\n */\r\n if (this.Editor.BlockManager.currentBlockIndex === 0) {\r\n this.Editor.Caret.setToBlock(this.Editor.BlockManager.currentBlock);\r\n }\r\n else {\r\n this.Editor.Caret.navigatePrevious(true);\r\n }\r\n this.Editor.Toolbar.close();\r\n }\r\n /**\r\n * Clear Editor's area\r\n */\r\n clear() {\r\n this.Editor.BlockManager.clear(true);\r\n }\r\n /**\r\n * Fills Editor with Blocks data\r\n * @param {IInputOutputData} data — Saved Editor data\r\n */\r\n render(data) {\r\n this.Editor.BlockManager.clear();\r\n this.Editor.Renderer.render(data.items);\r\n }\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 * Save Editor config. API provides passed configuration to the Blocks\r\n */\r\n constructor({ config }) {\r\n super({ config });\r\n }\r\n /**\r\n * Available methods\r\n * @return {IEventsAPI}\r\n */\r\n get methods() {\r\n return {\r\n emit: (eventName, data) => this.emit(eventName, data),\r\n off: (eventName, callback) => this.off(eventName, callback),\r\n on: (eventName, callback) => this.on(eventName, callback),\r\n };\r\n }\r\n /**\r\n * Subscribe on Events\r\n * @param {String} eventName\r\n * @param {Function} callback\r\n */\r\n on(eventName, callback) {\r\n this.Editor.Events.on(eventName, callback);\r\n }\r\n /**\r\n * Emit event with data\r\n * @param {String} eventName\r\n * @param {Object} data\r\n */\r\n emit(eventName, data) {\r\n this.Editor.Events.emit(eventName, data);\r\n }\r\n /**\r\n * Unsubscribe from Event\r\n * @param {String} eventName\r\n * @param {Function} callback\r\n */\r\n off(eventName, callback) {\r\n this.Editor.Events.off(eventName, callback);\r\n }\r\n}\r\n","/**\r\n * @class API\r\n * Provides with methods working with DOM Listener\r\n */\r\nexport default class ListenerAPI extends Module {\r\n /**\r\n * Save Editor config. API provides passed configuration to the Blocks\r\n */\r\n constructor({ config }) {\r\n super({ config });\r\n }\r\n /**\r\n * Available methods\r\n * @return {IToolbarAPI}\r\n */\r\n get methods() {\r\n return {\r\n on: (element, eventType, handler, useCapture) => this.on(element, eventType, handler, useCapture),\r\n off: (element, eventType, handler) => this.off(element, eventType, handler),\r\n };\r\n }\r\n /**\r\n * adds DOM event listener\r\n *\r\n * @param {HTMLElement} element\r\n * @param {string} eventType\r\n * @param {() => void} handler\r\n * @param {boolean} useCapture\r\n */\r\n on(element, eventType, handler, useCapture) {\r\n this.Editor.Listeners.on(element, eventType, handler, useCapture);\r\n }\r\n /**\r\n * Removes DOM listener from element\r\n *\r\n * @param element\r\n * @param eventType\r\n * @param handler\r\n */\r\n off(element, eventType, handler) {\r\n this.Editor.Listeners.off(element, eventType, handler);\r\n }\r\n}\r\n","/**\r\n * @class API\r\n * Provides CodeX Editor Sanitizer that allows developers to clean their HTML\r\n */\r\nexport default class SanitizerAPI extends Module {\r\n /**\r\n * Save Editor config. API provides passed configuration to the Blocks\r\n */\r\n constructor({ config }) {\r\n super({ config });\r\n }\r\n /**\r\n * Available methods\r\n * @return {ISanitizerAPI}\r\n */\r\n get methods() {\r\n return {\r\n clean: (taintString, config) => this.clean(taintString, config),\r\n };\r\n }\r\n clean(taintString, config) {\r\n return this.Editor.Sanitizer.clean(taintString, config);\r\n }\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 * Save Editor config. API provides passed configuration to the Blocks\r\n */\r\n constructor({ config }) {\r\n super({ config });\r\n }\r\n /**\r\n * Available methods\r\n * @return {ISaverAPI}\r\n */\r\n get methods() {\r\n return {\r\n save: () => this.save(),\r\n };\r\n }\r\n /**\r\n * Return Editor's data\r\n */\r\n save() {\r\n return this.Editor.Saver.save();\r\n }\r\n}\r\n","import Selection from '../selection';\r\n/**\r\n * @class API\r\n * Provides with methods working with Selection\r\n */\r\nexport default class SelectionAPI extends Module {\r\n /**\r\n * Save Editor config. API provides passed configuration to the Blocks\r\n */\r\n constructor({ config }) {\r\n super({ config });\r\n }\r\n /**\r\n * Available methods\r\n * @return {ISelectionAPI}\r\n */\r\n get methods() {\r\n return {\r\n findParentTag: (tagName, className) => this.findParentTag(tagName, className),\r\n expandToTag: (node) => this.expandToTag(node),\r\n };\r\n }\r\n /**\r\n * Looks ahead from selection and find passed tag with class name\r\n * @param {string} tagName - tag to find\r\n * @param {string} className - tag's class name\r\n * @return {HTMLElement|null}\r\n */\r\n findParentTag(tagName, className) {\r\n return new Selection().findParentTag(tagName, className);\r\n }\r\n /**\r\n * Expand selection to passed tag\r\n * @param {HTMLElement} node - tag that should contain selection\r\n */\r\n expandToTag(node) {\r\n new Selection().expandToTag(node);\r\n }\r\n}\r\n","/**\r\n * @class ToolbarsAPI\r\n * provides with methods working with Toolbar\r\n */\r\nexport default class ToolbarAPI extends Module {\r\n /**\r\n * Save Editor config. API provides passed configuration to the Blocks\r\n */\r\n constructor({ config }) {\r\n super({ config });\r\n }\r\n /**\r\n * Available methods\r\n * @return {IToolbarAPI}\r\n */\r\n get methods() {\r\n return {\r\n close: () => this.close(),\r\n open: () => this.open(),\r\n };\r\n }\r\n /**\r\n * Open toolbar\r\n */\r\n open() {\r\n this.Editor.Toolbar.open();\r\n }\r\n /**\r\n * Close toolbar and all included elements\r\n */\r\n close() {\r\n this.Editor.Toolbar.close();\r\n }\r\n}\r\n","/**\r\n * @class API\r\n */\r\nexport default class API extends Module {\r\n /**\r\n * Save Editor config. API provides passed configuration to the Blocks\r\n * @param {EditorConfig} config\r\n */\r\n constructor({ config }) {\r\n super({ config });\r\n }\r\n get methods() {\r\n return {\r\n blocks: this.Editor.BlocksAPI.methods,\r\n caret: {},\r\n events: this.Editor.EventsAPI.methods,\r\n listener: this.Editor.ListenerAPI.methods,\r\n sanitizer: this.Editor.SanitizerAPI.methods,\r\n saver: this.Editor.SaverAPI.methods,\r\n selection: this.Editor.SelectionAPI.methods,\r\n toolbar: this.Editor.ToolbarAPI.methods,\r\n };\r\n }\r\n}\r\n","export default class BlockEvents extends Module {\r\n /**\r\n * @constructor\r\n */\r\n constructor({ config }) {\r\n super({ config });\r\n }\r\n /**\r\n * All keydowns on Block\r\n * @param {KeyboardEvent} event - keydown\r\n */\r\n keydown(event) {\r\n /**\r\n * Run common method for all keydown events\r\n */\r\n this.beforeKeydownProcessing();\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 case _.keyCodes.ENTER:\r\n this.enter(event);\r\n break;\r\n case _.keyCodes.DOWN:\r\n case _.keyCodes.RIGHT:\r\n this.arrowRightAndDown();\r\n break;\r\n case _.keyCodes.UP:\r\n case _.keyCodes.LEFT:\r\n this.arrowLeftAndUp();\r\n break;\r\n default:\r\n this.defaultHandler();\r\n break;\r\n }\r\n }\r\n /**\r\n * Fires on keydown before event processing\r\n */\r\n beforeKeydownProcessing() {\r\n /**\r\n * Clear all highlightings\r\n */\r\n this.Editor.BlockManager.clearHighlightings();\r\n /**\r\n * Hide Toolbar\r\n */\r\n this.Editor.Toolbar.close();\r\n }\r\n /**\r\n * Key up on Block:\r\n * - shows Inline Toolbar if something selected\r\n */\r\n keyup(event) {\r\n this.Editor.InlineToolbar.handleShowingEvent(event);\r\n }\r\n /**\r\n * Mouse up on Block:\r\n * - shows Inline Toolbar if something selected\r\n */\r\n mouseUp(event) {\r\n this.Editor.InlineToolbar.handleShowingEvent(event);\r\n }\r\n /**\r\n * ENTER pressed on block\r\n * @param {KeyboardEvent} event - keydown\r\n */\r\n enter(event) {\r\n const currentBlock = this.Editor.BlockManager.currentBlock, toolsConfig = this.config.toolsConfig[currentBlock.name];\r\n /**\r\n * Don't handle Enter keydowns when Tool sets enableLineBreaks to true.\r\n * Uses for Tools like where line breaks should be handled by default behaviour.\r\n */\r\n if (toolsConfig && toolsConfig[this.Editor.Tools.apiSettings.IS_ENABLED_LINE_BREAKS]) {\r\n return;\r\n }\r\n /**\r\n * Allow to create linebreaks by Shift+Enter\r\n */\r\n if (event.shiftKey) {\r\n return;\r\n }\r\n /**\r\n * Split the Current Block into two blocks\r\n */\r\n this.Editor.BlockManager.split();\r\n /**\r\n * Renew local current node after split\r\n */\r\n const newCurrent = this.Editor.BlockManager.currentBlock;\r\n this.Editor.Toolbar.move();\r\n /**\r\n * If new Block is empty\r\n */\r\n if (this.Editor.Tools.isInitial(newCurrent.tool) && newCurrent.isEmpty) {\r\n /**\r\n * Show Toolbar\r\n */\r\n this.Editor.Toolbar.open();\r\n /**\r\n * Show Plus Button\r\n */\r\n this.Editor.Toolbar.plusButton.show();\r\n }\r\n event.preventDefault();\r\n }\r\n /**\r\n * Handle backspace keydown on Block\r\n * @param {KeyboardEvent} event - keydown\r\n */\r\n backspace(event) {\r\n const BM = this.Editor.BlockManager;\r\n const isFirstBlock = BM.currentBlockIndex === 0, canMergeBlocks = this.Editor.Caret.isAtStart && !isFirstBlock;\r\n /** If current Block is empty just remove this Block */\r\n if (this.Editor.BlockManager.currentBlock.isEmpty) {\r\n this.Editor.BlockManager.removeBlock();\r\n if (this.Editor.Caret.navigatePrevious(true)) {\r\n this.Editor.Toolbar.close();\r\n }\r\n return;\r\n }\r\n if (!canMergeBlocks) {\r\n return;\r\n }\r\n // preventing browser default behaviour\r\n event.preventDefault();\r\n const targetBlock = BM.getBlockByIndex(BM.currentBlockIndex - 1), blockToMerge = BM.currentBlock;\r\n /**\r\n * Blocks that can be merged:\r\n * 1) with the same Name\r\n * 2) Tool has 'merge' method\r\n *\r\n * other case will handle as usual ARROW LEFT behaviour\r\n */\r\n if (blockToMerge.name !== targetBlock.name || !targetBlock.mergeable) {\r\n if (this.Editor.Caret.navigatePrevious()) {\r\n this.Editor.Toolbar.close();\r\n }\r\n return;\r\n }\r\n this.Editor.Caret.createShadow(targetBlock.pluginsContent);\r\n BM.mergeBlocks(targetBlock, blockToMerge)\r\n .then(() => {\r\n /** Restore caret position after merge */\r\n this.Editor.Caret.restoreCaret(targetBlock.pluginsContent);\r\n targetBlock.pluginsContent.normalize();\r\n this.Editor.Toolbar.close();\r\n });\r\n }\r\n /**\r\n * Handle right and down keyboard keys\r\n */\r\n arrowRightAndDown() {\r\n this.Editor.Caret.navigateNext();\r\n }\r\n /**\r\n * Handle left and up keyboard keys\r\n */\r\n arrowLeftAndUp() {\r\n this.Editor.Caret.navigatePrevious();\r\n }\r\n /**\r\n * Default keydown handler\r\n */\r\n defaultHandler() { }\r\n}\r\n","/**\r\n * @class BlockManager\r\n * @classdesc Manage editor`s blocks storage and appearance\r\n *\r\n * @module BlockManager\r\n *\r\n * @version 2.0.0\r\n */\r\n\r\nimport Block from '../block';\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 * @constructor\r\n * @param {EditorConfig} config\r\n */\r\n constructor({config}) {\r\n super({config});\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 this._blocks = null;\r\n\r\n /**\r\n * Index of current working block\r\n *\r\n * @type {number}\r\n * @private\r\n */\r\n this.currentBlockIndex = -1;\r\n }\r\n\r\n /**\r\n * Should be called after Editor.UI preparation\r\n * Define this._blocks property\r\n *\r\n * @returns {Promise}\r\n */\r\n prepare() {\r\n return new Promise(resolve => {\r\n let 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 *\r\n * @todo proxy the enumerate method\r\n *\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 resolve();\r\n });\r\n }\r\n\r\n /**\r\n * Creates Block instance by tool name\r\n *\r\n * @param {String} toolName - tools passed in editor config {@link EditorConfig#tools}\r\n * @param {Object} data - constructor params\r\n * @param {Object} settings - block settings\r\n *\r\n * @return {Block}\r\n */\r\n composeBlock(toolName, data, settings) {\r\n let toolInstance = this.Editor.Tools.construct(toolName, data),\r\n block = new Block(toolName, toolInstance, settings, this.Editor.API.methods);\r\n\r\n this.bindEvents(block);\r\n /**\r\n * Apply callback before inserting html\r\n */\r\n block.call('appendCallback', {});\r\n\r\n return block;\r\n }\r\n\r\n /**\r\n * Bind Events\r\n * @param {Object} block\r\n */\r\n bindEvents(block) {\r\n this.Editor.Listeners.on(block.holder, 'keydown', (event) => this.Editor.BlockEvents.keydown(event));\r\n this.Editor.Listeners.on(block.holder, 'mouseup', (event) => this.Editor.BlockEvents.mouseUp(event));\r\n this.Editor.Listeners.on(block.holder, 'keyup', (event) => this.Editor.BlockEvents.keyup(event));\r\n }\r\n\r\n /**\r\n * Insert new block into _blocks\r\n *\r\n * @param {String} toolName — plugin name, by default method inserts initial block type\r\n * @param {Object} data — plugin data\r\n * @param {Object} settings - default settings\r\n *\r\n * @return {Block}\r\n */\r\n insert(toolName = this.config.initialBlock, data = {}, settings = {}) {\r\n let block = this.composeBlock(toolName, data, settings);\r\n\r\n this._blocks[++this.currentBlockIndex] = block;\r\n this.Editor.Caret.setToBlock(block);\r\n\r\n return block;\r\n }\r\n\r\n /**\r\n * Always inserts at the end\r\n */\r\n insertAtEnd() {\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 initial typed block\r\n */\r\n this.insert();\r\n }\r\n\r\n /**\r\n * Merge two blocks\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 *\r\n * @return {Promise} - the sequence that can be continued\r\n */\r\n mergeBlocks(targetBlock, blockToMerge) {\r\n let blockToMergeIndex = this._blocks.indexOf(blockToMerge);\r\n\r\n return Promise.resolve()\r\n .then( () => {\r\n if (blockToMerge.isEmpty) {\r\n return;\r\n }\r\n\r\n return blockToMerge.data\r\n .then((blockToMergeInfo) => {\r\n targetBlock.mergeWith(blockToMergeInfo.data);\r\n });\r\n })\r\n .then( () => {\r\n this.removeBlock(blockToMergeIndex);\r\n this.currentBlockIndex = this._blocks.indexOf(targetBlock);\r\n });\r\n }\r\n\r\n /**\r\n * Remove block with passed index or remove last\r\n * @param {Number|null} index\r\n */\r\n removeBlock(index) {\r\n if (!index) {\r\n index = this.currentBlockIndex;\r\n }\r\n this._blocks.remove(index);\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 split() {\r\n let extractedFragment = this.Editor.Caret.extractFragmentFromCaretPosition(),\r\n wrapper = $.make('div');\r\n\r\n wrapper.append(extractedFragment);\r\n\r\n /**\r\n * @todo make object in accordance with Tool\r\n */\r\n let data = {\r\n text: $.isEmpty(wrapper) ? '' : wrapper.innerHTML,\r\n };\r\n\r\n /**\r\n * Renew current Block\r\n * @type {Block}\r\n */\r\n const blockInserted = this.insert(this.config.initialBlock, data);\r\n\r\n this.currentNode = blockInserted.pluginsContent;\r\n }\r\n\r\n /**\r\n * Replace current working block\r\n *\r\n * @param {String} toolName — plugin name\r\n * @param {Object} data — plugin data\r\n */\r\n replace(toolName, data = {}) {\r\n let block = this.composeBlock(toolName, data);\r\n\r\n this._blocks.insert(this.currentBlockIndex, block, true);\r\n }\r\n\r\n /**\r\n * returns last Block\r\n * @return {Block}\r\n */\r\n get lastBlock() {\r\n return this._blocks[this._blocks.length - 1];\r\n }\r\n\r\n /**\r\n * Returns Block by passed index\r\n * @param {Number} index\r\n * @return {Block}\r\n */\r\n getBlockByIndex(index) {\r\n return this._blocks[index];\r\n }\r\n\r\n /**\r\n * Get Block instance by html element\r\n * @param {Node} element\r\n * @returns {Block}\r\n */\r\n getBlock(element) {\r\n if (!$.isElement(element)) {\r\n element = element.parentNode;\r\n }\r\n\r\n let nodes = this._blocks.nodes,\r\n firstLevelBlock = element.closest(`.${Block.CSS.wrapper}`),\r\n index = nodes.indexOf(firstLevelBlock);\r\n\r\n if (index >= 0) {\r\n return this._blocks[index];\r\n }\r\n }\r\n\r\n /**\r\n * Get current Block instance\r\n *\r\n * @return {Block}\r\n */\r\n get currentBlock() {\r\n return this._blocks[this.currentBlockIndex];\r\n }\r\n\r\n /**\r\n * Returns next Block instance\r\n * @return {Block|null}\r\n */\r\n get nextBlock() {\r\n let 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 * Returns previous Block instance\r\n * @return {Block|null}\r\n */\r\n get previousBlock() {\r\n let 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 working html element\r\n *\r\n * @return {HTMLElement}\r\n */\r\n get currentNode() {\r\n return this._blocks.nodes[this.currentBlockIndex];\r\n }\r\n\r\n /**\r\n * Set currentBlockIndex to passed block\r\n * @param {Node} element\r\n */\r\n set currentNode(element) {\r\n let nodes = this._blocks.nodes,\r\n firstLevelBlock = element.closest(`.${Block.CSS.wrapper}`);\r\n\r\n /**\r\n * Update current Block's index\r\n * @type {number}\r\n */\r\n this.currentBlockIndex = nodes.indexOf(firstLevelBlock);\r\n }\r\n\r\n /**\r\n * Remove selection from all Blocks then highlight only Current Block\r\n */\r\n highlightCurrentNode() {\r\n /**\r\n * Remove previous selected Block's state\r\n */\r\n this.clearHighlightings();\r\n\r\n /**\r\n * Mark current Block as selected\r\n * @type {boolean}\r\n */\r\n this.currentBlock.selected = true;\r\n }\r\n\r\n /**\r\n * Remove selection from all Blocks\r\n */\r\n clearHighlightings() {\r\n this.blocks.forEach( block => block.selected = false);\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 get blocks() {\r\n return this._blocks.array;\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 {Element|Text} childNode - look ahead from this node.\r\n * @throws Error - when passed Node is not included at the Block\r\n */\r\n setCurrentBlockByChildNode(childNode) {\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 let parentFirstLevelBlock = childNode.closest(`.${Block.CSS.wrapper}`);\r\n\r\n if (parentFirstLevelBlock) {\r\n this.currentNode = parentFirstLevelBlock;\r\n } else {\r\n throw new Error('Can not find a Block from this child Node');\r\n }\r\n }\r\n\r\n /**\r\n * Swap Blocks Position\r\n * @param {Number} fromIndex\r\n * @param {Number} toIndex\r\n */\r\n swap(fromIndex, toIndex) {\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 * Sets current Block Index -1 which means unknown\r\n * and clear highlightings\r\n */\r\n dropPointer() {\r\n this.currentBlockIndex = -1;\r\n this.clearHighlightings();\r\n }\r\n\r\n /**\r\n * Clears Editor\r\n * @param {boolean} needAddInitialBlock - 1) in internal calls (for example, in api.blocks.render)\r\n * we don't need to add empty initial block\r\n * 2) in api.blocks.clear we should add empty block\r\n */\r\n clear(needAddInitialBlock = false) {\r\n this._blocks.removeAll();\r\n this.dropPointer();\r\n\r\n if (needAddInitialBlock) {\r\n this.insert(this.config.initialBlock);\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * @class Blocks\r\n * @classdesc Class to work with Block instances array\r\n *\r\n * @private\r\n *\r\n * @property {HTMLElement} workingArea — editor`s working node\r\n *\r\n */\r\nclass Blocks {\r\n /**\r\n * @constructor\r\n *\r\n * @param {HTMLElement} workingArea — editor`s working node\r\n */\r\n constructor(workingArea) {\r\n this.blocks = [];\r\n this.workingArea = workingArea;\r\n }\r\n\r\n /**\r\n * Push back new Block\r\n *\r\n * @param {Block} block\r\n */\r\n push(block) {\r\n this.blocks.push(block);\r\n this.workingArea.appendChild(block.holder);\r\n }\r\n\r\n /**\r\n * Swaps blocks with indexes first and second\r\n * @param {Number} first - first block index\r\n * @param {Number} second - second block index\r\n */\r\n swap(first, second) {\r\n let 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 * 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 insert(index, block, replace = false) {\r\n if (!this.length) {\r\n this.push(block);\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 }\r\n\r\n let deleteCount = replace ? 1 : 0;\r\n\r\n this.blocks.splice(index, deleteCount, block);\r\n\r\n if (index > 0) {\r\n let previousBlock = this.blocks[index - 1];\r\n\r\n previousBlock.holder.insertAdjacentElement('afterend', block.holder);\r\n } else {\r\n let nextBlock = this.blocks[index + 1];\r\n\r\n if (nextBlock) {\r\n nextBlock.holder.insertAdjacentElement('beforebegin', block.holder);\r\n } else {\r\n this.workingArea.appendChild(block.holder);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Remove block\r\n * @param {Number|null} index\r\n */\r\n remove(index) {\r\n if (isNaN(index)) {\r\n index = this.length - 1;\r\n }\r\n\r\n this.blocks[index].holder.remove();\r\n this.blocks.splice(index, 1);\r\n }\r\n\r\n /**\r\n * Remove all blocks\r\n */\r\n removeAll() {\r\n this.workingArea.innerHTML = '';\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 *\r\n * @param {Block} targetBlock — target after wich Block should be inserted\r\n * @param {Block} newBlock — Block to insert\r\n */\r\n insertAfter(targetBlock, newBlock) {\r\n let 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 get(index) {\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\r\n * @returns {Number}\r\n */\r\n indexOf(block) {\r\n return this.blocks.indexOf(block);\r\n }\r\n\r\n /**\r\n * Get length of Block instances array\r\n *\r\n * @returns {Number}\r\n */\r\n get length() {\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 get array() {\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 get nodes() {\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 *\r\n * @param {Blocks} instance — Blocks instance\r\n * @param {Number|String} index — block index\r\n * @param {Block} block — Block to set\r\n * @returns {Boolean}\r\n */\r\n static set(instance, index, block) {\r\n if (isNaN(Number(index))) {\r\n return false;\r\n }\r\n\r\n instance.insert(index, 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 {Number|String} index — Block index\r\n * @returns {Block|*}\r\n */\r\n static get(instance, index) {\r\n if (isNaN(Number(index))) {\r\n return instance[index];\r\n }\r\n\r\n return instance.get(index);\r\n }\r\n}\r\n","/**\r\n * @class Caret\r\n * @classdesc Contains methods for working Caret\r\n *\r\n * Uses Range methods to manipulate with caret\r\n *\r\n * @module Caret\r\n *\r\n * @version 2.0.0\r\n */\r\n\r\nimport Selection from '../selection';\r\n\r\n/**\r\n * @typedef {Caret} Caret\r\n */\r\nexport default class Caret extends Module {\r\n /**\r\n * @constructor\r\n */\r\n constructor({config}) {\r\n super({config});\r\n }\r\n\r\n /**\r\n * Elements styles that can be useful for Caret Module\r\n */\r\n static get CSS() {\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 {Number} offset - caret offset regarding to the text node\r\n * @param {Boolean} atEnd - put caret at the end of the text node or not\r\n */\r\n setToBlock(block, offset = 0, atEnd = false) {\r\n let element = block.pluginsContent;\r\n\r\n /** If Element is INPUT */\r\n if ($.isNativeInput(element)) {\r\n element.focus();\r\n return;\r\n }\r\n\r\n let nodeToSet = $.getDeepestNode(element, atEnd);\r\n\r\n if (atEnd || offset > nodeToSet.length) {\r\n offset = nodeToSet.length;\r\n }\r\n\r\n /** if found deepest node is native input */\r\n if ($.isNativeInput(nodeToSet)) {\r\n nodeToSet.focus();\r\n return;\r\n }\r\n\r\n /**\r\n * @todo try to fix via Promises or use querySelectorAll to not to use timeout\r\n */\r\n _.delay( () => {\r\n this.set(nodeToSet, offset);\r\n }, 20)();\r\n\r\n this.Editor.BlockManager.currentNode = block.holder;\r\n }\r\n\r\n /**\r\n * Creates Document Range and sets caret to the element with offset\r\n * @param {Element} element - target node.\r\n * @param {Number} offset - offset\r\n */\r\n set( element, offset = 0) {\r\n let range = document.createRange(),\r\n selection = Selection.get();\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\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 setToTheLastBlock() {\r\n let lastBlock = this.Editor.BlockManager.lastBlock;\r\n\r\n if (!lastBlock) return;\r\n\r\n /**\r\n * If last block is empty and it is an initialBlock, set to that.\r\n * Otherwise, append new empty block and set to that\r\n */\r\n if (lastBlock.isEmpty) {\r\n this.setToBlock(lastBlock);\r\n } else {\r\n this.Editor.BlockManager.insertAtEnd();\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 extractFragmentFromCaretPosition() {\r\n let selection = Selection.get();\r\n\r\n if (selection.rangeCount) {\r\n let selectRange = selection.getRangeAt(0),\r\n blockElem = this.Editor.BlockManager.currentBlock.pluginsContent;\r\n\r\n selectRange.deleteContents();\r\n\r\n if (blockElem) {\r\n let range = selectRange.cloneRange(true);\r\n\r\n range.selectNodeContents(blockElem);\r\n range.setStart(selectRange.endContainer, selectRange.endOffset);\r\n return range.extractContents();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get all first-level (first child of [contenteditabel]) siblings from passed node\r\n * Then you can check it for emptiness\r\n *\r\n * @example\r\n *
    \r\n *\r\n * @return {Element[]}\r\n */\r\n getHigherLevelSiblings(from, direction ) {\r\n let current = from,\r\n siblings = [];\r\n\r\n /**\r\n * Find passed node's firs-level parent (in example - blockquote)\r\n */\r\n while (current.parentNode && current.parentNode.contentEditable !== 'true') {\r\n current = current.parentNode;\r\n }\r\n\r\n let sibling = direction === 'left' ? 'previousSibling' : 'nextSibling';\r\n\r\n /**\r\n * Find all left/right siblings\r\n */\r\n while (current[sibling]) {\r\n current = current[sibling];\r\n siblings.push(current);\r\n }\r\n\r\n return siblings;\r\n }\r\n\r\n /**\r\n * Set's caret to the next Block\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 - force navigation even if caret is not at the end\r\n *\r\n * @return {Boolean}\r\n */\r\n navigateNext(force = false) {\r\n let nextBlock = this.Editor.BlockManager.nextBlock;\r\n\r\n if (!nextBlock) {\r\n return false;\r\n }\r\n\r\n if (force || this.isAtEnd) {\r\n this.setToBlock(nextBlock);\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 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 - force navigation even if caret is not at the start\r\n *\r\n * @return {Boolean}\r\n */\r\n navigatePrevious(force = false) {\r\n let previousBlock = this.Editor.BlockManager.previousBlock;\r\n\r\n if (!previousBlock) {\r\n return false;\r\n }\r\n\r\n if (force || this.isAtStart) {\r\n this.setToBlock( previousBlock, 0, true );\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Get's deepest first node and checks if offset is zero\r\n * @return {boolean}\r\n */\r\n get isAtStart() {\r\n /**\r\n * Don't handle ranges\r\n */\r\n if (!Selection.isCollapsed) {\r\n return false;\r\n }\r\n\r\n let selection = Selection.get(),\r\n anchorNode = selection.anchorNode,\r\n firstNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent);\r\n\r\n /**\r\n * Workaround case when caret in the text like \" |Hello!\"\r\n * selection.anchorOffset is 1, but real caret visible position is 0\r\n * @type {number}\r\n */\r\n let firstLetterPosition = anchorNode.textContent.search(/\\S/);\r\n\r\n if (firstLetterPosition === -1) { // empty text\r\n firstLetterPosition = 0;\r\n }\r\n\r\n /**\r\n * In case of\r\n *
    \r\n *

    <-- first (and deepest) node is \r\n * |adaddad <-- anchor node\r\n *
    \r\n */\r\n if ($.isEmpty(firstNode)) {\r\n let leftSiblings = this.getHigherLevelSiblings(anchorNode, 'left'),\r\n nothingAtLeft = leftSiblings.every( node => $.isEmpty(node) );\r\n\r\n\r\n\r\n if (nothingAtLeft && selection.anchorOffset === firstLetterPosition) {\r\n return true;\r\n }\r\n }\r\n\r\n /**\r\n * We use <= comparison for case:\r\n * \"| Hello\" <--- selection.anchorOffset is 0, but firstLetterPosition is 1\r\n */\r\n return firstNode === null || anchorNode === firstNode && selection.anchorOffset <= firstLetterPosition;\r\n }\r\n\r\n /**\r\n * Get's deepest last node and checks if offset is last node text length\r\n * @return {boolean}\r\n */\r\n get isAtEnd() {\r\n /**\r\n * Don't handle ranges\r\n */\r\n if (!Selection.isCollapsed) {\r\n return false;\r\n }\r\n\r\n let selection = Selection.get(),\r\n anchorNode = selection.anchorNode,\r\n lastNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent, true);\r\n\r\n /**\r\n * In case of\r\n *
    \r\n * adaddad| <-- anchor node\r\n *

    <-- first (and deepest) node is \r\n *
    \r\n */\r\n if ($.isEmpty(lastNode)) {\r\n let leftSiblings = this.getHigherLevelSiblings(anchorNode, 'right'),\r\n nothingAtRight = leftSiblings.every( node => $.isEmpty(node) );\r\n\r\n if (nothingAtRight && selection.anchorOffset === anchorNode.textContent.length) {\r\n return true;\r\n }\r\n }\r\n\r\n /**\r\n * Workaround case:\r\n * hello | <--- anchorOffset will be 5, but textContent.length will be 6.\r\n * Why not regular .trim():\r\n * in case of ' hello |' trim() will also remove space at the beginning, so length will be lower than anchorOffset\r\n */\r\n let rightTrimmedText = lastNode.textContent.replace(/\\s+$/, '');\r\n\r\n /**\r\n * We use >= comparison for case:\r\n * \"Hello |\" <--- selection.anchorOffset is 7, but rightTrimmedText is 6\r\n */\r\n return anchorNode === lastNode && selection.anchorOffset >= rightTrimmedText.length;\r\n }\r\n\r\n /**\r\n * Inserts shadow element after passed element where caret can be placed\r\n * @param {Node} element\r\n */\r\n createShadow(element) {\r\n let 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 * @param {Node} element\r\n */\r\n restoreCaret(element) {\r\n let 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 let sel = new Selection();\r\n\r\n sel.expandToTag(shadowCaret);\r\n\r\n setTimeout(() => {\r\n let newRange = document.createRange();\r\n\r\n newRange.selectNode(shadowCaret);\r\n newRange.extractContents();\r\n }, 50);\r\n }\r\n}\r\n","/**\r\n * @module eventDispatcher\r\n *\r\n * Has two important methods:\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 - unsubsribes callback\r\n *\r\n * @version 1.0.0\r\n *\r\n * @typedef {Events} Events\r\n * @property {Object} subscribers - all subscribers grouped by event name\r\n */\r\nexport default class Events extends Module {\r\n /**\r\n * @constructor\r\n */\r\n constructor({config}) {\r\n super({config});\r\n this.subscribers = {};\r\n }\r\n\r\n /**\r\n * Subscribe any event on callback\r\n *\r\n * @param {String} eventName - event name\r\n * @param {Function} callback - subscriber\r\n */\r\n on(eventName, callback) {\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 * Emit callbacks with passed data\r\n *\r\n * @param {String} eventName - event name\r\n * @param {Object} data - subscribers get this data when they were fired\r\n */\r\n emit(eventName, data) {\r\n if (!this.subscribers[eventName]) {\r\n return;\r\n }\r\n\r\n this.subscribers[eventName].reduce(function (previousData, currentHandler) {\r\n let newData = currentHandler(previousData);\r\n\r\n return newData ? newData : previousData;\r\n }, data);\r\n }\r\n\r\n /**\r\n * Unsubsribe callback from event\r\n *\r\n * @param eventName\r\n * @param callback\r\n */\r\n off(eventName, callback) {\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 subsribers list\r\n */\r\n destroy() {\r\n this.subscribers = null;\r\n }\r\n}\r\n","/**\r\n * Codex Editor Listeners module\r\n *\r\n * @module Listeners\r\n *\r\n * Module-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 {Array} allListeners\r\n */\r\nexport default class Listeners extends Module {\r\n /**\r\n * @constructor\r\n * @param {EditorConfig} config\r\n */\r\n constructor({config}) {\r\n super({config});\r\n this.allListeners = [];\r\n }\r\n\r\n /**\r\n * Assigns event listener on element\r\n *\r\n * @param {Element} 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} useCapture - use event bubbling\r\n */\r\n on(element, eventType, handler, useCapture = false) {\r\n let assignedEventData = {\r\n element,\r\n eventType,\r\n handler,\r\n useCapture\r\n };\r\n\r\n let alreadyExist = this.findOne(element, eventType, handler);\r\n\r\n if (alreadyExist) return;\r\n\r\n this.allListeners.push(assignedEventData);\r\n element.addEventListener(eventType, handler, useCapture);\r\n }\r\n\r\n /**\r\n * Removes event listener from element\r\n *\r\n * @param {Element} 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} useCapture - use event bubbling\r\n */\r\n off(element, eventType, handler, useCapture = false) {\r\n let existingListeners = this.findAll(element, eventType, handler);\r\n\r\n for (let i = 0; i < existingListeners.length; i++) {\r\n let index = this.allListeners.indexOf(existingListeners[i]);\r\n\r\n if (index > 0) {\r\n this.allListeners.splice(index, 1);\r\n }\r\n }\r\n\r\n element.removeEventListener(eventType, handler, useCapture);\r\n }\r\n\r\n /**\r\n * Search method: looks for listener by passed element\r\n * @param {Element} element - searching element\r\n * @returns {Array} listeners that found on element\r\n */\r\n findByElement(element) {\r\n let listenersOnElement = [];\r\n\r\n for (let i = 0; i < this.allListeners.length; i++) {\r\n let listener = this.allListeners[i];\r\n\r\n if (listener.element === element) {\r\n listenersOnElement.push(listener);\r\n }\r\n }\r\n\r\n return listenersOnElement;\r\n }\r\n\r\n /**\r\n * Search method: looks for listener by passed event type\r\n * @param {String} eventType\r\n * @return {Array} listeners that found on element\r\n */\r\n findByType(eventType) {\r\n let listenersWithType = [];\r\n\r\n for (let i = 0; i < this.allListeners.length; i++) {\r\n let listener = this.allListeners[i];\r\n\r\n if (listener.type === eventType) {\r\n listenersWithType.push(listener);\r\n }\r\n }\r\n\r\n return listenersWithType;\r\n }\r\n\r\n /**\r\n * Search method: looks for listener by passed handler\r\n * @param {Function} handler\r\n * @return {Array} listeners that found on element\r\n */\r\n findByHandler(handler) {\r\n let listenersWithHandler = [];\r\n\r\n for (let i = 0; i < this.allListeners.length; i++) {\r\n let listener = this.allListeners[i];\r\n\r\n if (listener.handler === handler) {\r\n listenersWithHandler.push(listener);\r\n }\r\n }\r\n\r\n return listenersWithHandler;\r\n }\r\n\r\n /**\r\n * @param {Element} element\r\n * @param {String} eventType\r\n * @param {Function} handler\r\n * @return {Element|null}\r\n */\r\n findOne(element, eventType, handler) {\r\n let 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 * @param {Element} element\r\n * @param {String} eventType\r\n * @param {Function} handler\r\n * @return {Array}\r\n */\r\n findAll(element, eventType, handler) {\r\n let found,\r\n foundByElements = element ? this.findByElement(element) : [];\r\n // foundByEventType = eventType ? this.findByType(eventType) : [],\r\n // foundByHandler = handler ? this.findByHandler(handler) : [];\r\n\r\n if (element && eventType && handler) {\r\n found = foundByElements.filter( event => event.eventType === eventType && event.handler === handler );\r\n } else if (element && eventType) {\r\n found = foundByElements.filter( event => event.eventType === eventType);\r\n } else {\r\n found = foundByElements;\r\n }\r\n\r\n return found;\r\n }\r\n\r\n /**\r\n * Removes all listeners\r\n */\r\n removeAll() {\r\n this.allListeners.map( (current) => {\r\n current.element.removeEventListener(current.eventType, current.handler);\r\n });\r\n\r\n this.allListeners = [];\r\n }\r\n}\r\n","/**\r\n * Codex Editor Renderer Module\r\n *\r\n * @module Renderer\r\n * @author CodeX Team\r\n *\r\n * @version 2.0.0\r\n */\r\nexport default class Renderer extends Module {\r\n /**\r\n * @constructor\r\n * @param {EditorConfig} config\r\n */\r\n constructor({config}) {\r\n super({config});\r\n }\r\n\r\n /**\r\n * @typedef {Object} RendererItems\r\n * @property {String} type - tool name\r\n * @property {Object} data - tool data\r\n */\r\n\r\n /**\r\n * @example\r\n *\r\n * items: [\r\n * {\r\n * type : 'paragraph',\r\n * data : {\r\n * text : 'Hello from Codex!'\r\n * }\r\n * },\r\n * {\r\n * type : 'paragraph',\r\n * data : {\r\n * text : 'Leave feedback if you like it!'\r\n * }\r\n * },\r\n * ]\r\n *\r\n */\r\n\r\n /**\r\n * Make plugin blocks from array of plugin`s data\r\n * @param {RendererItems[]} items\r\n */\r\n render(items) {\r\n let chainData = [];\r\n\r\n for (let i = 0; i < items.length; i++) {\r\n chainData.push({\r\n function: () => this.insertBlock(items[i])\r\n });\r\n }\r\n\r\n return _.sequence(chainData);\r\n }\r\n\r\n /**\r\n * Get plugin instance\r\n * Add plugin instance to BlockManager\r\n * Insert block to working zone\r\n *\r\n * @param {Object} item\r\n * @returns {Promise.}\r\n * @private\r\n */\r\n insertBlock(item) {\r\n let tool = item.type,\r\n data = item.data,\r\n settings = item.settings;\r\n\r\n if (tool in this.Editor.Tools.available) {\r\n this.Editor.BlockManager.insert(tool, data, settings);\r\n } else {\r\n /**\r\n * @todo show warning notification message\r\n *\r\n * `${tool} blocks was skipped.`\r\n */\r\n\r\n _.log(`Tool «${tool}» is not found. Check 'tools' property at your initial CodeX Editor config.`, 'warn');\r\n }\r\n\r\n return Promise.resolve();\r\n }\r\n}\r\n","/**\r\n * CodeX Sanitizer\r\n *\r\n * @module Sanitizer\r\n * Clears HTML from taint tags\r\n *\r\n * @version 2.0.0\r\n *\r\n * @example\r\n * Module can be used within two ways:\r\n * 1) When you have an instance\r\n * - this.Editor.Sanitizer.clean(yourTaintString);\r\n * 2) As static method\r\n * - CodexEditor.Sanitizer.clean(yourTaintString, yourCustomConfiguration);\r\n *\r\n * {@link SanitizerConfig}\r\n */\r\n\r\n\r\n/**\r\n * @typedef {Object} SanitizerConfig\r\n * @property {Object} tags - define tags restrictions\r\n *\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\nexport default class Sanitizer extends Module {\r\n /**\r\n * Initializes Sanitizer module\r\n * Sets default configuration if custom not exists\r\n *\r\n * @property {SanitizerConfig} this.defaultConfig\r\n * @property {HTMLJanitor} this._sanitizerInstance - Sanitizer library\r\n *\r\n * @param {SanitizerConfig} config\r\n */\r\n constructor({config}) {\r\n super({config});\r\n\r\n // default config\r\n this.defaultConfig = null;\r\n this._sanitizerInstance = null;\r\n\r\n /** Custom configuration */\r\n this.sanitizerConfig = config.settings ? config.settings.sanitizer : {};\r\n\r\n /** HTML Janitor library */\r\n this.sanitizerInstance = require('html-janitor');\r\n }\r\n\r\n /**\r\n * If developer uses editor's API, then he can customize sanitize restrictions.\r\n * Or, sanitizing config can be defined globally in editors initialization. That config will be used everywhere\r\n * At least, if there is no config overrides, that API uses Default configuration\r\n *\r\n * @uses https://www.npmjs.com/package/html-janitor\r\n *\r\n * @param {HTMLJanitor} library - sanitizer extension\r\n */\r\n set sanitizerInstance(library) {\r\n this._sanitizerInstance = new library(this.defaultConfig);\r\n }\r\n\r\n /**\r\n * Sets sanitizer configuration. Uses default config if user didn't pass the restriction\r\n * @param {SanitizerConfig} config\r\n */\r\n set sanitizerConfig(config) {\r\n if (_.isEmpty(config)) {\r\n this.defaultConfig = {\r\n tags: {\r\n p: {},\r\n a: {\r\n href: true,\r\n target: '_blank',\r\n rel: 'nofollow'\r\n }\r\n }\r\n };\r\n } else {\r\n this.defaultConfig = config;\r\n }\r\n }\r\n\r\n /**\r\n * Cleans string from unwanted tags\r\n * @param {String} taintString - HTML string\r\n * @param {Object} customConfig - custom sanitizer configuration. Method uses default if param is empty\r\n * @return {String} clean HTML\r\n */\r\n clean(taintString, customConfig = {}) {\r\n if (_.isEmpty(customConfig)) {\r\n return this._sanitizerInstance.clean(taintString);\r\n } else {\r\n return Sanitizer.clean(taintString, customConfig);\r\n }\r\n }\r\n\r\n /**\r\n * Cleans string from unwanted tags\r\n * @static\r\n *\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 *\r\n * @return {String} clean HTML\r\n */\r\n static clean(taintString, customConfig) {\r\n let newInstance = Sanitizer(customConfig);\r\n\r\n return newInstance.clean(taintString);\r\n }\r\n}\r\n","/**\r\n * Codex Editor Saver\r\n *\r\n * @module Saver\r\n * @author Codex Team\r\n * @version 2.0.0\r\n */\r\n\r\n/**\r\n * @typedef {Object} SavedData\r\n * @property {Date} time - saving proccess time\r\n * @property {Object} items - extracted data\r\n * @property {String} version - CodexEditor version\r\n */\r\n\r\n/**\r\n * @classdesc This method reduces all Blocks asyncronically and calls Block's save method to extract data\r\n *\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 * @constructor\r\n * @param config\r\n */\r\n constructor({config}) {\r\n super({config});\r\n\r\n this.output = null;\r\n this.blocksData = [];\r\n }\r\n\r\n /**\r\n * Composes new chain of Promises to fire them alternatelly\r\n * @return {SavedData}\r\n */\r\n save() {\r\n let blocks = this.Editor.BlockManager.blocks,\r\n chainData = [];\r\n\r\n blocks.forEach((block) => {\r\n chainData.push(block.data);\r\n });\r\n\r\n return Promise.all(chainData)\r\n .then((allExtractedData) => this.makeOutput(allExtractedData))\r\n .then((outputData) => {\r\n return outputData;\r\n });\r\n }\r\n\r\n /**\r\n * Creates output object with saved data, time and version of editor\r\n * @param {Object} allExtractedData\r\n * @return {SavedData}\r\n */\r\n makeOutput(allExtractedData) {\r\n let items = [],\r\n totalTime = 0;\r\n\r\n console.groupCollapsed('[CodexEditor saving]:');\r\n\r\n allExtractedData.forEach((extraction) => {\r\n /** Group process info */\r\n console.log(`«${extraction.tool}» saving info`, extraction);\r\n totalTime += extraction.time;\r\n items.push({\r\n type: extraction.tool,\r\n data: extraction.data\r\n });\r\n });\r\n\r\n console.log('Total', totalTime);\r\n console.groupEnd();\r\n\r\n return {\r\n time : +new Date(),\r\n items : items,\r\n version : VERSION,\r\n };\r\n }\r\n}\r\n\r\n// module.exports = (function (saver) {\r\n//\r\n// let editor = codex.editor;\r\n//\r\n// /**\r\n// * @public\r\n// * Save blocks\r\n// */\r\n// saver.save = function () {\r\n//\r\n// /** Save html content of redactor to memory */\r\n// editor.state.html = editor.nodes.redactor.innerHTML;\r\n//\r\n// /** Clean jsonOutput state */\r\n// editor.state.jsonOutput = [];\r\n//\r\n// return saveBlocks(editor.nodes.redactor.childNodes);\r\n//\r\n// };\r\n//\r\n// /**\r\n// * @private\r\n// * Save each block data\r\n// *\r\n// * @param blocks\r\n// * @returns {Promise.}\r\n// */\r\n// let saveBlocks = function (blocks) {\r\n//\r\n// let data = [];\r\n//\r\n// for(let index = 0; index < blocks.length; index++) {\r\n//\r\n// data.push(getBlockData(blocks[index]));\r\n//\r\n// }\r\n//\r\n// return Promise.all(data)\r\n// .then(makeOutput)\r\n// .catch(editor.core.log);\r\n//\r\n// };\r\n//\r\n// /** Save and validate block data */\r\n// let getBlockData = function (block) {\r\n//\r\n// return saveBlockData(block)\r\n// .then(validateBlockData)\r\n// .catch(editor.core.log);\r\n//\r\n// };\r\n//\r\n// /**\r\n// * @private\r\n// * Call block`s plugin save method and return saved data\r\n// *\r\n// * @param block\r\n// * @returns {Object}\r\n// */\r\n// let saveBlockData = function (block) {\r\n//\r\n// let pluginName = block.dataset.tool;\r\n//\r\n// /** Check for plugin existence */\r\n// if (!editor.tools[pluginName]) {\r\n//\r\n// editor.core.log(`Plugin «${pluginName}» not found`, 'error');\r\n// return {data: null, pluginName: null};\r\n//\r\n// }\r\n//\r\n// /** Check for plugin having save method */\r\n// if (typeof editor.tools[pluginName].save !== 'function') {\r\n//\r\n// editor.core.log(`Plugin «${pluginName}» must have save method`, 'error');\r\n// return {data: null, pluginName: null};\r\n//\r\n// }\r\n//\r\n// /** Result saver */\r\n// let blockContent = block.childNodes[0],\r\n// pluginsContent = blockContent.childNodes[0],\r\n// position = pluginsContent.dataset.inputPosition;\r\n//\r\n// /** If plugin wasn't available then return data from cache */\r\n// if ( editor.tools[pluginName].available === false ) {\r\n//\r\n// return Promise.resolve({data: codex.editor.state.blocks.items[position].data, pluginName});\r\n//\r\n// }\r\n//\r\n// return Promise.resolve(pluginsContent)\r\n// .then(editor.tools[pluginName].save)\r\n// .then(data => Object({data, pluginName}));\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Call plugin`s validate method. Return false if validation failed\r\n// *\r\n// * @param data\r\n// * @param pluginName\r\n// * @returns {Object|Boolean}\r\n// */\r\n// let validateBlockData = function ({data, pluginName}) {\r\n//\r\n// if (!data || !pluginName) {\r\n//\r\n// return false;\r\n//\r\n// }\r\n//\r\n// if (editor.tools[pluginName].validate) {\r\n//\r\n// let result = editor.tools[pluginName].validate(data);\r\n//\r\n// /**\r\n// * Do not allow invalid data\r\n// */\r\n// if (!result) {\r\n//\r\n// return false;\r\n//\r\n// }\r\n//\r\n// }\r\n//\r\n// return {data, pluginName};\r\n//\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Compile article output\r\n// *\r\n// * @param savedData\r\n// * @returns {{time: number, version, items: (*|Array)}}\r\n// */\r\n// let makeOutput = function (savedData) {\r\n//\r\n// savedData = savedData.filter(blockData => blockData);\r\n//\r\n// let items = savedData.map(blockData => Object({type: blockData.pluginName, data: blockData.data}));\r\n//\r\n// editor.state.jsonOutput = items;\r\n//\r\n// return {\r\n// id: editor.state.blocks.id || null,\r\n// time: +new Date(),\r\n// version: editor.version,\r\n// items\r\n// };\r\n//\r\n// };\r\n//\r\n// return saver;\r\n//\r\n// })({});\r\n","/**\r\n * 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\nexport default class BlockSettings extends Module {\r\n /**\r\n * @constructor\r\n */\r\n constructor({config}) {\r\n super({config});\r\n\r\n this.nodes = {\r\n wrapper: null,\r\n toolSettings: null,\r\n defaultSettings: null\r\n };\r\n }\r\n\r\n /**\r\n * Module Events\r\n * @return {{opened: string, closed: string}}\r\n */\r\n get events() {\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 * @return {{wrapper, wrapperOpened, toolSettings, defaultSettings, button}}\r\n */\r\n static get CSS() {\r\n return {\r\n // Settings Panel\r\n wrapper: 'ce-settings',\r\n wrapperOpened: 'ce-settings--opened',\r\n toolSettings: 'ce-settings__plugin-zone',\r\n defaultSettings: 'ce-settings__default-zone',\r\n\r\n button: 'ce-settings__button'\r\n };\r\n }\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 * @return {Element}\r\n */\r\n make() {\r\n this.nodes.wrapper = $.make('div', BlockSettings.CSS.wrapper);\r\n\r\n this.nodes.toolSettings = $.make('div', BlockSettings.CSS.toolSettings);\r\n this.nodes.defaultSettings = $.make('div', BlockSettings.CSS.defaultSettings);\r\n\r\n $.append(this.nodes.wrapper, [this.nodes.toolSettings, this.nodes.defaultSettings]);\r\n }\r\n\r\n /**\r\n * Add Tool's settings\r\n */\r\n addToolSettings() {\r\n if (typeof this.Editor.BlockManager.currentBlock.tool.renderSettings === 'function') {\r\n $.append(this.nodes.toolSettings, this.Editor.BlockManager.currentBlock.tool.renderSettings());\r\n }\r\n }\r\n\r\n /**\r\n * Add default settings\r\n */\r\n addDefaultSettings() {\r\n $.append(this.nodes.defaultSettings, this.Editor.BlockManager.currentBlock.renderTunes());\r\n }\r\n\r\n /**\r\n * Is Block Settings opened or not\r\n * @returns {boolean}\r\n */\r\n get opened() {\r\n return this.nodes.wrapper.classList.contains(BlockSettings.CSS.wrapperOpened);\r\n }\r\n\r\n /**\r\n * Open Block Settings pane\r\n */\r\n open() {\r\n this.nodes.wrapper.classList.add(BlockSettings.CSS.wrapperOpened);\r\n\r\n /**\r\n * Fill Tool's settings\r\n */\r\n this.addToolSettings();\r\n\r\n /**\r\n * Add default settings that presents for all Blocks\r\n */\r\n this.addDefaultSettings();\r\n\r\n /** Tell to subscribers that block settings is opened */\r\n this.Editor.Events.emit(this.events.opened);\r\n }\r\n\r\n /**\r\n * Close Block Settings pane\r\n */\r\n close() {\r\n this.nodes.wrapper.classList.remove(BlockSettings.CSS.wrapperOpened);\r\n\r\n /** Clear settings */\r\n this.nodes.toolSettings.innerHTML = '';\r\n this.nodes.defaultSettings.innerHTML = '';\r\n\r\n /** Tell to subscribers that block settings is closed */\r\n this.Editor.Events.emit(this.events.closed);\r\n }\r\n}\r\n","import 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 Selection from '../selection';\r\nexport default class InlineToolbar extends Module {\r\n /**\r\n * @constructor\r\n */\r\n constructor({ config }) {\r\n super({ config });\r\n /**\r\n * CSS styles\r\n */\r\n this.CSS = {\r\n inlineToolbar: 'ce-inline-toolbar',\r\n inlineToolbarShowed: 'ce-inline-toolbar--showed',\r\n buttonsWrapper: 'ce-inline-toolbar__buttons',\r\n actionsWrapper: 'ce-inline-toolbar__actions',\r\n };\r\n /**\r\n * Inline Toolbar elements\r\n */\r\n this.nodes = {\r\n wrapper: null,\r\n buttons: null,\r\n /**\r\n * Zone below the buttons where Tools can create additional actions by 'renderActions()' method\r\n * For example, input for the 'link' tool or textarea for the 'comment' tool\r\n */\r\n actions: null,\r\n };\r\n /**\r\n * Margin above/below the Toolbar\r\n */\r\n this.toolbarVerticalMargin = 20;\r\n }\r\n /**\r\n * Inline Toolbar Tools\r\n * @todo Merge internal tools with external\r\n */\r\n get tools() {\r\n if (!this.toolsInstances) {\r\n this.toolsInstances = [\r\n new BoldInlineTool(this.Editor.API.methods),\r\n new ItalicInlineTool(this.Editor.API.methods),\r\n new LinkInlineTool(this.Editor.API.methods),\r\n ...this.Editor.Tools.inline.map((Tool) => new Tool(this.Editor.API.methods)),\r\n ];\r\n }\r\n return this.toolsInstances;\r\n }\r\n /**\r\n * Making DOM\r\n */\r\n make() {\r\n this.nodes.wrapper = $.make('div', this.CSS.inlineToolbar);\r\n this.nodes.buttons = $.make('div', this.CSS.buttonsWrapper);\r\n this.nodes.actions = $.make('div', this.CSS.actionsWrapper);\r\n /**\r\n * Append Inline Toolbar to the Editor\r\n */\r\n $.append(this.nodes.wrapper, [this.nodes.buttons, this.nodes.actions]);\r\n $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\r\n /**\r\n * Append Inline Toolbar Tools\r\n */\r\n this.addTools();\r\n }\r\n /**\r\n *\r\n *\r\n * Moving / appearance\r\n * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n *\r\n */\r\n /**\r\n * Shows Inline Toolbar by keyup/mouseup\r\n * @param {KeyboardEvent|MouseEvent} event\r\n */\r\n handleShowingEvent(event) {\r\n if (!this.allowedToShow(event)) {\r\n this.close();\r\n return;\r\n }\r\n this.move();\r\n this.open();\r\n /** Check Tools state for selected fragment */\r\n this.checkToolsState();\r\n }\r\n /**\r\n * Move Toolbar to the selected text\r\n */\r\n move() {\r\n const selectionRect = Selection.rect;\r\n const wrapperOffset = this.Editor.UI.nodes.wrapper.getBoundingClientRect();\r\n const newCoords = {\r\n x: selectionRect.x - wrapperOffset.left,\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 * If we know selections width, place InlineToolbar to center\r\n */\r\n if (selectionRect.width) {\r\n newCoords.x += Math.floor(selectionRect.width / 2);\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 * Shows Inline Toolbar\r\n */\r\n open() {\r\n this.nodes.wrapper.classList.add(this.CSS.inlineToolbarShowed);\r\n this.tools.forEach((tool) => {\r\n if (typeof tool.clear === 'function') {\r\n tool.clear();\r\n }\r\n });\r\n }\r\n /**\r\n * Hides Inline Toolbar\r\n */\r\n close() {\r\n this.nodes.wrapper.classList.remove(this.CSS.inlineToolbarShowed);\r\n this.tools.forEach((tool) => {\r\n if (typeof tool.clear === 'function') {\r\n tool.clear();\r\n }\r\n });\r\n }\r\n /**\r\n * Need to show Inline Toolbar or not\r\n * @param {KeyboardEvent|MouseEvent} event\r\n */\r\n allowedToShow(event) {\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 if (event && tagsConflictsWithSelection.includes(event.target.tagName)) {\r\n return false;\r\n }\r\n const currentSelection = Selection.get(), selectedText = Selection.text;\r\n // old browsers\r\n if (!currentSelection || !currentSelection.anchorNode) {\r\n return false;\r\n }\r\n // empty selection\r\n if (currentSelection.isCollapsed || selectedText.length < 1) {\r\n return false;\r\n }\r\n // is enabled by current Block's Tool\r\n const currentBlock = this.Editor.BlockManager.getBlock(currentSelection.anchorNode);\r\n if (!currentBlock) {\r\n return false;\r\n }\r\n const toolConfig = this.config.toolsConfig[currentBlock.name];\r\n return toolConfig && toolConfig[this.Editor.Tools.apiSettings.IS_ENABLED_INLINE_TOOLBAR];\r\n }\r\n /**\r\n *\r\n *\r\n * Working with Tools\r\n * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n *\r\n */\r\n /**\r\n * Fill Inline Toolbar with Tools\r\n */\r\n addTools() {\r\n this.tools.forEach((tool) => {\r\n this.addTool(tool);\r\n });\r\n }\r\n /**\r\n * Add tool button and activate clicks\r\n * @param {InlineTool} tool - Tool's instance\r\n */\r\n addTool(tool) {\r\n const button = tool.render();\r\n if (!button) {\r\n _.log('Render method must return an instance of Node', 'warn', tool);\r\n return;\r\n }\r\n this.nodes.buttons.appendChild(button);\r\n if (typeof tool.renderActions === 'function') {\r\n const actions = tool.renderActions();\r\n this.nodes.actions.appendChild(actions);\r\n }\r\n this.Editor.Listeners.on(button, 'click', () => {\r\n this.toolClicked(tool);\r\n });\r\n }\r\n /**\r\n * Inline Tool button clicks\r\n * @param {InlineTool} tool - Tool's instance\r\n */\r\n toolClicked(tool) {\r\n const range = Selection.range;\r\n tool.surround(range);\r\n this.checkToolsState();\r\n }\r\n /**\r\n * Check Tools` state by selection\r\n */\r\n checkToolsState() {\r\n this.tools.forEach((tool) => {\r\n tool.checkState(Selection.get());\r\n });\r\n }\r\n}\r\n","/**\r\n * @class Toolbox\r\n * @classdesc Holder for Tools\r\n *\r\n * @typedef {Toolbox} Toolbox\r\n * @property {Boolean} opened - opening state\r\n * @property {Object} nodes - Toolbox nodes\r\n * @property {Object} CSS - CSS class names\r\n *\r\n */\r\nexport default class Toolbox extends Module {\r\n /**\r\n * @constructor\r\n */\r\n constructor({config}) {\r\n super({config});\r\n\r\n this.nodes = {\r\n toolbox: null,\r\n buttons: []\r\n };\r\n\r\n /**\r\n * Opening state\r\n * @type {boolean}\r\n */\r\n this.opened = false;\r\n }\r\n\r\n /**\r\n * CSS styles\r\n * @return {{toolbox: string, toolboxButton: string, toolboxOpened: string}}\r\n */\r\n static get CSS() {\r\n return {\r\n toolbox: 'ce-toolbox',\r\n toolboxButton: 'ce-toolbox__button',\r\n toolboxOpened: 'ce-toolbox--opened',\r\n };\r\n }\r\n\r\n /**\r\n * Makes the Toolbox\r\n */\r\n make() {\r\n this.nodes.toolbox = $.make('div', Toolbox.CSS.toolbox);\r\n $.append(this.Editor.Toolbar.nodes.content, this.nodes.toolbox);\r\n\r\n this.addTools();\r\n }\r\n\r\n /**\r\n * Iterates available tools and appends them to the Toolbox\r\n */\r\n addTools() {\r\n let tools = this.Editor.Tools.toolsAvailable;\r\n\r\n for (let toolName in tools) {\r\n this.addTool(toolName, tools[toolName]);\r\n }\r\n }\r\n\r\n /**\r\n * Append Tool to the Toolbox\r\n *\r\n * @param {string} toolName - tool name\r\n * @param {Tool} tool - tool class\r\n */\r\n addTool(toolName, tool) {\r\n const api = this.Editor.Tools.apiSettings;\r\n\r\n if (tool[api.IS_DISPLAYED_IN_TOOLBOX] && !tool[api.TOOLBAR_ICON_CLASS]) {\r\n _.log('Toolbar icon class name is missed. Tool %o skipped', 'warn', toolName);\r\n return;\r\n }\r\n\r\n /**\r\n * @todo Add checkup for the render method\r\n */\r\n // if (typeof tool.render !== 'function') {\r\n //\r\n // _.log('render method missed. Tool %o skipped', 'warn', tool);\r\n // return;\r\n //\r\n // }\r\n\r\n /**\r\n * Skip tools that pass 'displayInToolbox=false'\r\n */\r\n if (!tool[api.IS_DISPLAYED_IN_TOOLBOX]) {\r\n return;\r\n }\r\n\r\n let button = $.make('li', [Toolbox.CSS.toolboxButton, tool[api.TOOLBAR_ICON_CLASS]], {\r\n title: toolName\r\n });\r\n\r\n /**\r\n * Save tool's name in the button data-name\r\n */\r\n button.dataset.name = toolName;\r\n\r\n $.append(this.nodes.toolbox, button);\r\n\r\n this.nodes.toolbox.appendChild(button);\r\n this.nodes.buttons.push(button);\r\n\r\n /**\r\n * @todo add event with module Listeners\r\n */\r\n // this.Editor.Listeners.add();\r\n button.addEventListener('click', event => {\r\n this.buttonClicked(event);\r\n }, false);\r\n }\r\n\r\n /**\r\n * Toolbox button click listener\r\n * 1) if block is empty -> replace\r\n * 2) if block is not empty -> add new block below\r\n *\r\n * @param {MouseEvent} event\r\n */\r\n buttonClicked(event) {\r\n let toolButton = event.target,\r\n toolName = toolButton.dataset.name,\r\n tool = this.Editor.Tools.toolClasses[toolName];\r\n\r\n /**\r\n * @type {Block}\r\n */\r\n let currentBlock = this.Editor.BlockManager.currentBlock;\r\n\r\n /**\r\n * We do replace if:\r\n * - block is empty\r\n * - block is not irreplaceable\r\n * @type {Array}\r\n */\r\n if (!tool[this.Editor.Tools.apiSettings.IS_IRREPLACEBLE_TOOL] && currentBlock.isEmpty) {\r\n this.Editor.BlockManager.replace(toolName);\r\n } else {\r\n this.Editor.BlockManager.insert(toolName);\r\n }\r\n\r\n /**\r\n * @todo set caret to the new block\r\n */\r\n\r\n // window.setTimeout(function () {\r\n\r\n /** Set caret to current block */\r\n // editor.caret.setToBlock(currentInputIndex);\r\n\r\n // }, 10);\r\n\r\n /**\r\n * Move toolbar when node is changed\r\n */\r\n this.Editor.Toolbar.move();\r\n }\r\n\r\n /**\r\n * Open Toolbox with Tools\r\n */\r\n open() {\r\n this.nodes.toolbox.classList.add(Toolbox.CSS.toolboxOpened);\r\n this.opened = true;\r\n }\r\n\r\n /**\r\n * Close Toolbox\r\n */\r\n close() {\r\n this.nodes.toolbox.classList.remove(Toolbox.CSS.toolboxOpened);\r\n this.opened = false;\r\n }\r\n\r\n /**\r\n * Close Toolbox\r\n */\r\n toggle() {\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 *\r\n * «Toolbar» is the node that moves up/down over current block\r\n *\r\n * ______________________________________ Toolbar ____________________________________________\r\n * | |\r\n * | ..................... Content .................... ......... Block Actions .......... |\r\n * | . . . . |\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 * 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 *\r\n * @typedef {Toolbar} Toolbar\r\n * @property {Object} 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 {\r\n /**\r\n * @constructor\r\n */\r\n constructor({config}) {\r\n super({config});\r\n\r\n this.nodes = {\r\n wrapper : null,\r\n content : null,\r\n actions : null,\r\n\r\n // Content Zone\r\n plusButton : null,\r\n\r\n // Actions Zone\r\n blockActionsButtons: null,\r\n settingsToggler : null,\r\n };\r\n }\r\n\r\n /**\r\n * CSS styles\r\n * @return {Object}\r\n * @constructor\r\n */\r\n static get CSS() {\r\n return {\r\n toolbar: 'ce-toolbar',\r\n content: 'ce-toolbar__content',\r\n actions: 'ce-toolbar__actions',\r\n\r\n toolbarOpened: 'ce-toolbar--opened',\r\n\r\n // Content Zone\r\n plusButton: 'ce-toolbar__plus',\r\n plusButtonHidden: 'ce-toolbar__plus--hidden',\r\n\r\n // Actions Zone\r\n blockActionsButtons: 'ce-toolbar__actions-buttons',\r\n settingsToggler: 'ce-toolbar__settings-btn',\r\n };\r\n }\r\n\r\n /**\r\n * Makes toolbar\r\n */\r\n make() {\r\n this.nodes.wrapper = $.make('div', Toolbar.CSS.toolbar);\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', Toolbar.CSS[el]);\r\n $.append(this.nodes.wrapper, this.nodes[el]);\r\n });\r\n\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', Toolbar.CSS.plusButton);\r\n $.append(this.nodes.plusButton, $.svg('plus', 14, 14));\r\n $.append(this.nodes.content, this.nodes.plusButton);\r\n this.nodes.plusButton.addEventListener('click', event => this.plusButtonClicked(event), false);\r\n\r\n\r\n /**\r\n * Make a Toolbox\r\n */\r\n this.Editor.Toolbox.make();\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 this.nodes.blockActionsButtons = $.make('div', Toolbar.CSS.blockActionsButtons);\r\n this.nodes.settingsToggler = $.make('span', Toolbar.CSS.settingsToggler);\r\n const settingsIcon = $.svg('dots', 18, 4);\r\n\r\n $.append(this.nodes.settingsToggler, settingsIcon);\r\n $.append(this.nodes.blockActionsButtons, this.nodes.settingsToggler);\r\n $.append(this.nodes.actions, this.nodes.blockActionsButtons);\r\n\r\n /**\r\n * Make and append Settings Panel\r\n */\r\n this.Editor.BlockSettings.make();\r\n $.append(this.nodes.actions, this.Editor.BlockSettings.nodes.wrapper);\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 * Bind events on the Toolbar elements\r\n */\r\n this.bindEvents();\r\n }\r\n\r\n /**\r\n * Move Toolbar to the Current Block\r\n * @param {Boolean} forceClose - force close Toolbar Settings and Toolbar\r\n */\r\n move(forceClose = true) {\r\n if (forceClose) {\r\n /** Close Toolbox when we move toolbar */\r\n this.Editor.Toolbox.close();\r\n this.Editor.BlockSettings.close();\r\n }\r\n\r\n let currentNode = this.Editor.BlockManager.currentNode;\r\n\r\n /**\r\n * If no one Block selected as a Current\r\n */\r\n if (!currentNode) {\r\n return;\r\n }\r\n\r\n /**\r\n * @todo Compute dynamically on prepare\r\n * @type {number}\r\n */\r\n const defaultToolbarHeight = 49;\r\n const defaultOffset = 34;\r\n\r\n var newYCoordinate = currentNode.offsetTop - (defaultToolbarHeight / 2) + defaultOffset;\r\n\r\n this.nodes.wrapper.style.transform = `translate3D(0, ${Math.floor(newYCoordinate)}px, 0)`;\r\n }\r\n\r\n /**\r\n * Open Toolbar with Plus Button\r\n */\r\n open() {\r\n this.nodes.wrapper.classList.add(Toolbar.CSS.toolbarOpened);\r\n }\r\n\r\n /**\r\n * Close the Toolbar\r\n */\r\n close() {\r\n this.nodes.wrapper.classList.remove(Toolbar.CSS.toolbarOpened);\r\n }\r\n\r\n /**\r\n * Plus Button public methods\r\n * @return {{hide: function(): void, show: function(): void}}\r\n */\r\n get plusButton() {\r\n return {\r\n hide: () => this.nodes.plusButton.classList.add(Toolbar.CSS.plusButtonHidden),\r\n show: () => this.nodes.plusButton.classList.remove(Toolbar.CSS.plusButtonHidden)\r\n };\r\n }\r\n\r\n /**\r\n * Handler for Plus Button\r\n * @param {MouseEvent} event\r\n */\r\n plusButtonClicked() {\r\n this.Editor.Toolbox.toggle();\r\n }\r\n\r\n /**\r\n * Bind events on the Toolbar Elements:\r\n * - Block Settings\r\n */\r\n bindEvents() {\r\n /**\r\n * Settings toggler\r\n */\r\n this.Editor.Listeners.on(this.nodes.settingsToggler, 'click', (event) => {\r\n this.settingsTogglerClicked(event);\r\n });\r\n }\r\n\r\n /**\r\n * Clicks on the Block Settings toggler\r\n */\r\n settingsTogglerClicked() {\r\n if (this.Editor.BlockSettings.opened) {\r\n this.Editor.BlockSettings.close();\r\n } else {\r\n this.Editor.BlockSettings.open();\r\n }\r\n }\r\n}\r\n","/**\r\n * Inline toolbar\r\n *\r\n * Contains from tools:\r\n * Bold, Italic, Underline and Anchor\r\n *\r\n * @author Codex Team\r\n * @version 1.0\r\n */\r\n\r\nmodule.exports = (function (inline) {\r\n let editor = codex.editor;\r\n\r\n inline.buttonsOpened = null;\r\n inline.actionsOpened = null;\r\n inline.wrappersOffset = null;\r\n\r\n /**\r\n * saving selection that need for execCommand for styling\r\n *\r\n */\r\n inline.storedSelection = null;\r\n\r\n /**\r\n * @protected\r\n *\r\n * Open inline toobar\r\n */\r\n inline.show = function () {\r\n var currentNode = editor.content.currentNode,\r\n tool = currentNode.dataset.tool,\r\n plugin;\r\n\r\n /**\r\n * tool allowed to open inline toolbar\r\n */\r\n plugin = editor.tools[tool];\r\n\r\n if (!plugin.showInlineToolbar)\r\n return;\r\n\r\n var selectedText = inline.getSelectionText(),\r\n toolbar = editor.nodes.inlineToolbar.wrapper;\r\n\r\n if (selectedText.length > 0) {\r\n /** Move toolbar and open */\r\n editor.toolbar.inline.move();\r\n\r\n /** Open inline toolbar */\r\n toolbar.classList.add('opened');\r\n\r\n /** show buttons of inline toolbar */\r\n editor.toolbar.inline.showButtons();\r\n }\r\n };\r\n\r\n /**\r\n * @protected\r\n *\r\n * Closes inline toolbar\r\n */\r\n inline.close = function () {\r\n var toolbar = editor.nodes.inlineToolbar.wrapper;\r\n\r\n toolbar.classList.remove('opened');\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Moving toolbar\r\n */\r\n inline.move = function () {\r\n if (!this.wrappersOffset) {\r\n this.wrappersOffset = this.getWrappersOffset();\r\n }\r\n\r\n var coords = this.getSelectionCoords(),\r\n defaultOffset = 0,\r\n toolbar = editor.nodes.inlineToolbar.wrapper,\r\n newCoordinateX,\r\n newCoordinateY;\r\n\r\n if (toolbar.offsetHeight === 0) {\r\n defaultOffset = 40;\r\n }\r\n\r\n newCoordinateX = coords.x - this.wrappersOffset.left;\r\n newCoordinateY = coords.y + window.scrollY - this.wrappersOffset.top - defaultOffset - toolbar.offsetHeight;\r\n\r\n toolbar.style.transform = `translate3D(${Math.floor(newCoordinateX)}px, ${Math.floor(newCoordinateY)}px, 0)`;\r\n\r\n /** Close everything */\r\n editor.toolbar.inline.closeButtons();\r\n editor.toolbar.inline.closeAction();\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Tool Clicked\r\n */\r\n\r\n inline.toolClicked = function (event, type) {\r\n /**\r\n * For simple tools we use default browser function\r\n * For more complicated tools, we should write our own behavior\r\n */\r\n switch (type) {\r\n case 'createLink' : editor.toolbar.inline.createLinkAction(event, type); break;\r\n default : editor.toolbar.inline.defaultToolAction(type); break;\r\n }\r\n\r\n /**\r\n * highlight buttons\r\n * after making some action\r\n */\r\n editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight);\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Saving wrappers offset in DOM\r\n */\r\n inline.getWrappersOffset = function () {\r\n var wrapper = editor.nodes.wrapper,\r\n offset = this.getOffset(wrapper);\r\n\r\n this.wrappersOffset = offset;\r\n return offset;\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Calculates offset of DOM element\r\n *\r\n * @param el\r\n * @returns {{top: number, left: number}}\r\n */\r\n inline.getOffset = function ( el ) {\r\n var _x = 0;\r\n var _y = 0;\r\n\r\n while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {\r\n _x += (el.offsetLeft + el.clientLeft);\r\n _y += (el.offsetTop + el.clientTop);\r\n el = el.offsetParent;\r\n }\r\n return { top: _y, left: _x };\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Calculates position of selected text\r\n * @returns {{x: number, y: number}}\r\n */\r\n inline.getSelectionCoords = function () {\r\n var sel = document.selection, range;\r\n var x = 0, y = 0;\r\n\r\n if (sel) {\r\n if (sel.type != 'Control') {\r\n range = sel.createRange();\r\n range.collapse(true);\r\n x = range.boundingLeft;\r\n y = range.boundingTop;\r\n }\r\n } else if (window.getSelection) {\r\n sel = window.getSelection();\r\n\r\n if (sel.rangeCount) {\r\n range = sel.getRangeAt(0).cloneRange();\r\n if (range.getClientRects) {\r\n range.collapse(true);\r\n var rect = range.getClientRects()[0];\r\n\r\n if (!rect) {\r\n return;\r\n }\r\n\r\n x = rect.left;\r\n y = rect.top;\r\n }\r\n }\r\n }\r\n return { x: x, y: y };\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Returns selected text as String\r\n * @returns {string}\r\n */\r\n inline.getSelectionText = function () {\r\n var selectedText = '';\r\n\r\n // all modern browsers and IE9+\r\n if (window.getSelection) {\r\n selectedText = window.getSelection().toString();\r\n }\r\n\r\n return selectedText;\r\n };\r\n\r\n /** Opens buttons block */\r\n inline.showButtons = function () {\r\n var buttons = editor.nodes.inlineToolbar.buttons;\r\n\r\n buttons.classList.add('opened');\r\n\r\n editor.toolbar.inline.buttonsOpened = true;\r\n\r\n /** highlight buttons */\r\n editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight);\r\n };\r\n\r\n /** Makes buttons disappear */\r\n inline.closeButtons = function () {\r\n var buttons = editor.nodes.inlineToolbar.buttons;\r\n\r\n buttons.classList.remove('opened');\r\n\r\n editor.toolbar.inline.buttonsOpened = false;\r\n };\r\n\r\n /** Open buttons defined action if exist */\r\n inline.showActions = function () {\r\n var action = editor.nodes.inlineToolbar.actions;\r\n\r\n action.classList.add('opened');\r\n\r\n editor.toolbar.inline.actionsOpened = true;\r\n };\r\n\r\n /** Close actions block */\r\n inline.closeAction = function () {\r\n var action = editor.nodes.inlineToolbar.actions;\r\n\r\n action.innerHTML = '';\r\n action.classList.remove('opened');\r\n editor.toolbar.inline.actionsOpened = false;\r\n };\r\n\r\n\r\n /**\r\n * Callback for keydowns in inline toolbar \"Insert link...\" input\r\n */\r\n let inlineToolbarAnchorInputKeydown_ = function (event) {\r\n if (event.keyCode != editor.core.keys.ENTER) {\r\n return;\r\n }\r\n\r\n let editable = editor.content.currentNode,\r\n storedSelection = editor.toolbar.inline.storedSelection;\r\n\r\n editor.toolbar.inline.restoreSelection(editable, storedSelection);\r\n editor.toolbar.inline.setAnchor(this.value);\r\n\r\n /**\r\n * Preventing events that will be able to happen\r\n */\r\n event.preventDefault();\r\n event.stopImmediatePropagation();\r\n\r\n editor.toolbar.inline.clearRange();\r\n };\r\n\r\n /** Action for link creation or for setting anchor */\r\n inline.createLinkAction = function (event) {\r\n var isActive = this.isLinkActive();\r\n\r\n var editable = editor.content.currentNode,\r\n storedSelection = editor.toolbar.inline.saveSelection(editable);\r\n\r\n /** Save globally selection */\r\n editor.toolbar.inline.storedSelection = storedSelection;\r\n\r\n if (isActive) {\r\n /**\r\n * Changing stored selection. if we want to remove anchor from word\r\n * we should remove anchor from whole word, not only selected part.\r\n * The solution is than we get the length of current link\r\n * Change start position to - end of selection minus length of anchor\r\n */\r\n editor.toolbar.inline.restoreSelection(editable, storedSelection);\r\n\r\n editor.toolbar.inline.defaultToolAction('unlink');\r\n } else {\r\n /** Create input and close buttons */\r\n var action = editor.draw.inputForLink();\r\n\r\n editor.nodes.inlineToolbar.actions.appendChild(action);\r\n\r\n editor.toolbar.inline.closeButtons();\r\n editor.toolbar.inline.showActions();\r\n\r\n /**\r\n * focus to input\r\n * Solution: https://developer.mozilla.org/ru/docs/Web/API/HTMLElement/focus\r\n * Prevents event after showing input and when we need to focus an input which is in unexisted form\r\n */\r\n action.focus();\r\n event.preventDefault();\r\n\r\n /** Callback to link action */\r\n editor.listeners.add(action, 'keydown', inlineToolbarAnchorInputKeydown_, false);\r\n }\r\n };\r\n\r\n inline.isLinkActive = function () {\r\n var isActive = false;\r\n\r\n editor.nodes.inlineToolbar.buttons.childNodes.forEach(function (tool) {\r\n var dataType = tool.dataset.type;\r\n\r\n if (dataType == 'link' && tool.classList.contains('hightlighted')) {\r\n isActive = true;\r\n }\r\n });\r\n\r\n return isActive;\r\n };\r\n\r\n /** default action behavior of tool */\r\n inline.defaultToolAction = function (type) {\r\n document.execCommand(type, false, null);\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Sets URL\r\n *\r\n * @param {String} url - URL\r\n */\r\n inline.setAnchor = function (url) {\r\n document.execCommand('createLink', false, url);\r\n\r\n /** Close after URL inserting */\r\n editor.toolbar.inline.closeAction();\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Saves selection\r\n */\r\n inline.saveSelection = function (containerEl) {\r\n var range = window.getSelection().getRangeAt(0),\r\n preSelectionRange = range.cloneRange(),\r\n start;\r\n\r\n preSelectionRange.selectNodeContents(containerEl);\r\n preSelectionRange.setEnd(range.startContainer, range.startOffset);\r\n\r\n start = preSelectionRange.toString().length;\r\n\r\n return {\r\n start: start,\r\n end: start + range.toString().length\r\n };\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Sets to previous selection (Range)\r\n *\r\n * @param {Element} containerEl - editable element where we restore range\r\n * @param {Object} savedSel - range basic information to restore\r\n */\r\n inline.restoreSelection = function (containerEl, savedSel) {\r\n var range = document.createRange(),\r\n charIndex = 0;\r\n\r\n range.setStart(containerEl, 0);\r\n range.collapse(true);\r\n\r\n var nodeStack = [ containerEl ],\r\n node,\r\n foundStart = false,\r\n stop = false,\r\n nextCharIndex;\r\n\r\n while (!stop && (node = nodeStack.pop())) {\r\n if (node.nodeType == 3) {\r\n nextCharIndex = charIndex + node.length;\r\n\r\n if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {\r\n range.setStart(node, savedSel.start - charIndex);\r\n foundStart = true;\r\n }\r\n if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {\r\n range.setEnd(node, savedSel.end - charIndex);\r\n stop = true;\r\n }\r\n charIndex = nextCharIndex;\r\n } else {\r\n var i = node.childNodes.length;\r\n\r\n while (i--) {\r\n nodeStack.push(node.childNodes[i]);\r\n }\r\n }\r\n }\r\n\r\n var sel = window.getSelection();\r\n\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Removes all ranges from window selection\r\n */\r\n inline.clearRange = function () {\r\n var selection = window.getSelection();\r\n\r\n selection.removeAllRanges();\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * sets or removes hightlight\r\n */\r\n inline.hightlight = function (tool) {\r\n var dataType = tool.dataset.type;\r\n\r\n if (document.queryCommandState(dataType)) {\r\n editor.toolbar.inline.setButtonHighlighted(tool);\r\n } else {\r\n editor.toolbar.inline.removeButtonsHighLight(tool);\r\n }\r\n\r\n /**\r\n *\r\n * hightlight for anchors\r\n */\r\n var selection = window.getSelection(),\r\n tag = selection.anchorNode.parentNode;\r\n\r\n if (tag.tagName == 'A' && dataType == 'link') {\r\n editor.toolbar.inline.setButtonHighlighted(tool);\r\n }\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Mark button if text is already executed\r\n */\r\n inline.setButtonHighlighted = function (button) {\r\n button.classList.add('hightlighted');\r\n\r\n /** At link tool we also change icon */\r\n if (button.dataset.type == 'link') {\r\n var icon = button.childNodes[0];\r\n\r\n icon.classList.remove('ce-icon-link');\r\n icon.classList.add('ce-icon-unlink');\r\n }\r\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Removes hightlight\r\n */\r\n inline.removeButtonsHighLight = function (button) {\r\n button.classList.remove('hightlighted');\r\n\r\n /** At link tool we also change icon */\r\n if (button.dataset.type == 'link') {\r\n var icon = button.childNodes[0];\r\n\r\n icon.classList.remove('ce-icon-unlink');\r\n icon.classList.add('ce-icon-link');\r\n }\r\n };\r\n\r\n\r\n return inline;\r\n})({});","/**\r\n * Toolbar settings\r\n *\r\n * @version 1.0.5\r\n */\r\n\r\nmodule.exports = (function (settings) {\r\n let editor = codex.editor;\r\n\r\n settings.opened = false;\r\n\r\n settings.setting = null;\r\n settings.actions = null;\r\n\r\n /**\r\n * Append and open settings\r\n */\r\n settings.open = function (toolType) {\r\n /**\r\n * Append settings content\r\n * It's stored in tool.settings\r\n */\r\n if ( !editor.tools[toolType] || !editor.tools[toolType].renderSettings ) {\r\n return;\r\n }\r\n\r\n /**\r\n * Draw settings block\r\n */\r\n var settingsBlock = editor.tools[toolType].renderSettings();\r\n\r\n editor.nodes.pluginSettings.appendChild(settingsBlock);\r\n\r\n\r\n /** Open settings block */\r\n editor.nodes.blockSettings.classList.add('opened');\r\n this.opened = true;\r\n };\r\n\r\n /**\r\n * Close and clear settings\r\n */\r\n settings.close = function () {\r\n editor.nodes.blockSettings.classList.remove('opened');\r\n editor.nodes.pluginSettings.innerHTML = '';\r\n\r\n this.opened = false;\r\n };\r\n\r\n /**\r\n * @param {string} toolType - plugin type\r\n */\r\n settings.toggle = function ( toolType ) {\r\n if ( !this.opened ) {\r\n this.open(toolType);\r\n } else {\r\n this.close();\r\n }\r\n };\r\n\r\n /**\r\n * Here we will draw buttons and add listeners to components\r\n */\r\n settings.makeRemoveBlockButton = function () {\r\n var removeBlockWrapper = editor.draw.node('SPAN', 'ce-toolbar__remove-btn', {}),\r\n settingButton = editor.draw.node('SPAN', 'ce-toolbar__remove-setting', { innerHTML : '' }),\r\n actionWrapper = editor.draw.node('DIV', 'ce-toolbar__remove-confirmation', {}),\r\n confirmAction = editor.draw.node('DIV', 'ce-toolbar__remove-confirm', { textContent : 'Удалить блок' }),\r\n cancelAction = editor.draw.node('DIV', 'ce-toolbar__remove-cancel', { textContent : 'Отмена' });\r\n\r\n editor.listeners.add(settingButton, 'click', editor.toolbar.settings.removeButtonClicked, false);\r\n\r\n editor.listeners.add(confirmAction, 'click', editor.toolbar.settings.confirmRemovingRequest, false);\r\n\r\n editor.listeners.add(cancelAction, 'click', editor.toolbar.settings.cancelRemovingRequest, false);\r\n\r\n actionWrapper.appendChild(confirmAction);\r\n actionWrapper.appendChild(cancelAction);\r\n\r\n removeBlockWrapper.appendChild(settingButton);\r\n removeBlockWrapper.appendChild(actionWrapper);\r\n\r\n /** Save setting */\r\n editor.toolbar.settings.setting = settingButton;\r\n editor.toolbar.settings.actions = actionWrapper;\r\n\r\n return removeBlockWrapper;\r\n };\r\n\r\n settings.removeButtonClicked = function () {\r\n var action = editor.toolbar.settings.actions;\r\n\r\n if (action.classList.contains('opened')) {\r\n editor.toolbar.settings.hideRemoveActions();\r\n } else {\r\n editor.toolbar.settings.showRemoveActions();\r\n }\r\n\r\n editor.toolbar.toolbox.close();\r\n editor.toolbar.settings.close();\r\n };\r\n\r\n settings.cancelRemovingRequest = function () {\r\n editor.toolbar.settings.actions.classList.remove('opened');\r\n };\r\n\r\n settings.confirmRemovingRequest = function () {\r\n var currentBlock = editor.content.currentNode,\r\n firstLevelBlocksCount;\r\n\r\n currentBlock.remove();\r\n\r\n firstLevelBlocksCount = editor.nodes.redactor.childNodes.length;\r\n\r\n /**\r\n * If all blocks are removed\r\n */\r\n if (firstLevelBlocksCount === 0) {\r\n /** update currentNode variable */\r\n editor.content.currentNode = null;\r\n\r\n /** Inserting new empty initial block */\r\n editor.ui.addInitialBlock();\r\n }\r\n\r\n editor.ui.saveInputs();\r\n\r\n editor.toolbar.close();\r\n };\r\n\r\n settings.showRemoveActions = function () {\r\n editor.toolbar.settings.actions.classList.add('opened');\r\n };\r\n\r\n settings.hideRemoveActions = function () {\r\n editor.toolbar.settings.actions.classList.remove('opened');\r\n };\r\n\r\n return settings;\r\n})({});\r\n","/**\r\n * Codex Editor toolbar module\r\n *\r\n * Contains:\r\n * - Inline toolbox\r\n * - Toolbox within plus button\r\n * - Settings section\r\n *\r\n * @author Codex Team\r\n * @version 1.0\r\n */\r\n\r\nmodule.exports = (function (toolbar) {\r\n let editor = codex.editor;\r\n\r\n toolbar.settings = require('./settings');\r\n toolbar.inline = require('./inline');\r\n toolbar.toolbox = require('./toolbox');\r\n\r\n /**\r\n * Margin between focused node and toolbar\r\n */\r\n toolbar.defaultToolbarHeight = 49;\r\n\r\n toolbar.defaultOffset = 34;\r\n\r\n toolbar.opened = false;\r\n\r\n toolbar.current = null;\r\n\r\n /**\r\n * @protected\r\n */\r\n toolbar.open = function () {\r\n if (editor.hideToolbar) {\r\n return;\r\n }\r\n\r\n let toolType = editor.content.currentNode.dataset.tool;\r\n\r\n if (!editor.tools[toolType] || !editor.tools[toolType].renderSettings ) {\r\n editor.nodes.showSettingsButton.classList.add('hide');\r\n } else {\r\n editor.nodes.showSettingsButton.classList.remove('hide');\r\n }\r\n\r\n editor.nodes.toolbar.classList.add('opened');\r\n this.opened = true;\r\n };\r\n\r\n /**\r\n * @protected\r\n */\r\n toolbar.close = function () {\r\n editor.nodes.toolbar.classList.remove('opened');\r\n\r\n toolbar.opened = false;\r\n toolbar.current = null;\r\n\r\n for (var button in editor.nodes.toolbarButtons) {\r\n editor.nodes.toolbarButtons[button].classList.remove('selected');\r\n }\r\n\r\n /** Close toolbox when toolbar is not displayed */\r\n editor.toolbar.toolbox.close();\r\n editor.toolbar.settings.close();\r\n };\r\n\r\n toolbar.toggle = function () {\r\n if ( !this.opened ) {\r\n this.open();\r\n } else {\r\n this.close();\r\n }\r\n };\r\n\r\n toolbar.hidePlusButton = function () {\r\n editor.nodes.plusButton.classList.add('hide');\r\n };\r\n\r\n toolbar.showPlusButton = function () {\r\n editor.nodes.plusButton.classList.remove('hide');\r\n };\r\n\r\n /**\r\n * Moving toolbar to the specified node\r\n */\r\n toolbar.move = function () {\r\n /** Close Toolbox when we move toolbar */\r\n editor.toolbar.toolbox.close();\r\n\r\n if (!editor.content.currentNode) {\r\n return;\r\n }\r\n\r\n var newYCoordinate = editor.content.currentNode.offsetTop - (editor.toolbar.defaultToolbarHeight / 2) + editor.toolbar.defaultOffset;\r\n\r\n editor.nodes.toolbar.style.transform = `translate3D(0, ${Math.floor(newYCoordinate)}px, 0)`;\r\n\r\n /** Close trash actions */\r\n editor.toolbar.settings.hideRemoveActions();\r\n };\r\n\r\n return toolbar;\r\n})({});\r\n","/**\r\n * Codex Editor toolbox\r\n *\r\n * All tools be able to appended here\r\n *\r\n * @author Codex Team\r\n * @version 1.0\r\n */\r\n\r\nmodule.exports = (function (toolbox) {\r\n let editor = codex.editor;\r\n\r\n toolbox.opened = false;\r\n toolbox.openedOnBlock = null;\r\n\r\n /** Shows toolbox */\r\n toolbox.open = function () {\r\n /** Close setting if toolbox is opened */\r\n if (editor.toolbar.settings.opened) {\r\n editor.toolbar.settings.close();\r\n }\r\n\r\n /** Add 'toolbar-opened' class for current block **/\r\n toolbox.openedOnBlock = editor.content.currentNode;\r\n toolbox.openedOnBlock.classList.add('toolbar-opened');\r\n\r\n /** display toolbox */\r\n editor.nodes.toolbox.classList.add('opened');\r\n\r\n /** Animate plus button */\r\n editor.nodes.plusButton.classList.add('clicked');\r\n\r\n /** toolbox state */\r\n editor.toolbar.toolbox.opened = true;\r\n };\r\n\r\n /** Closes toolbox */\r\n toolbox.close = function () {\r\n /** Remove 'toolbar-opened' class from current block **/\r\n if (toolbox.openedOnBlock) toolbox.openedOnBlock.classList.remove('toolbar-opened');\r\n toolbox.openedOnBlock = null;\r\n\r\n /** Makes toolbox disappear */\r\n editor.nodes.toolbox.classList.remove('opened');\r\n\r\n /** Rotate plus button */\r\n editor.nodes.plusButton.classList.remove('clicked');\r\n\r\n /** toolbox state */\r\n editor.toolbar.toolbox.opened = false;\r\n\r\n editor.toolbar.current = null;\r\n };\r\n\r\n toolbox.leaf = function () {\r\n let currentTool = editor.toolbar.current,\r\n tools = Object.keys(editor.tools),\r\n barButtons = editor.nodes.toolbarButtons,\r\n nextToolIndex = 0,\r\n toolToSelect,\r\n visibleTool,\r\n tool;\r\n\r\n if ( !currentTool ) {\r\n /** Get first tool from object*/\r\n for(tool in editor.tools) {\r\n if (editor.tools[tool].displayInToolbox) {\r\n break;\r\n }\r\n\r\n nextToolIndex ++;\r\n }\r\n } else {\r\n nextToolIndex = (tools.indexOf(currentTool) + 1) % tools.length;\r\n visibleTool = tools[nextToolIndex];\r\n\r\n while (!editor.tools[visibleTool].displayInToolbox) {\r\n nextToolIndex = (nextToolIndex + 1) % tools.length;\r\n visibleTool = tools[nextToolIndex];\r\n }\r\n }\r\n\r\n toolToSelect = tools[nextToolIndex];\r\n\r\n for ( var button in barButtons ) {\r\n barButtons[button].classList.remove('selected');\r\n }\r\n\r\n barButtons[toolToSelect].classList.add('selected');\r\n editor.toolbar.current = toolToSelect;\r\n };\r\n\r\n /**\r\n * Transforming selected node type into selected toolbar element type\r\n * @param {event} event\r\n */\r\n toolbox.toolClicked = function (event) {\r\n /**\r\n * UNREPLACEBLE_TOOLS this types of tools are forbidden to replace even they are empty\r\n */\r\n var UNREPLACEBLE_TOOLS = ['image', 'link', 'list', 'instagram', 'twitter', 'embed'],\r\n tool = editor.tools[editor.toolbar.current],\r\n workingNode = editor.content.currentNode,\r\n currentInputIndex = editor.caret.inputIndex,\r\n newBlockContent,\r\n appendCallback,\r\n blockData;\r\n\r\n /** Make block from plugin */\r\n newBlockContent = tool.render();\r\n\r\n /** information about block */\r\n blockData = {\r\n block : newBlockContent,\r\n type : tool.type,\r\n stretched : false\r\n };\r\n\r\n if (\r\n workingNode &&\r\n UNREPLACEBLE_TOOLS.indexOf(workingNode.dataset.tool) === -1 &&\r\n workingNode.textContent.trim() === ''\r\n ) {\r\n /** Replace current block */\r\n editor.content.switchBlock(workingNode, newBlockContent, tool.type);\r\n } else {\r\n /** Insert new Block from plugin */\r\n editor.content.insertBlock(blockData);\r\n\r\n /** increase input index */\r\n currentInputIndex++;\r\n }\r\n\r\n /** Fire tool append callback */\r\n appendCallback = tool.appendCallback;\r\n\r\n if (appendCallback && typeof appendCallback == 'function') {\r\n appendCallback.call(event);\r\n }\r\n\r\n window.setTimeout(function () {\r\n /** Set caret to current block */\r\n editor.caret.setToBlock(currentInputIndex);\r\n }, 10);\r\n\r\n\r\n /**\r\n * Changing current Node\r\n */\r\n editor.content.workingNodeChanged();\r\n\r\n /**\r\n * Move toolbar when node is changed\r\n */\r\n editor.toolbar.move();\r\n };\r\n\r\n return toolbox;\r\n})({});","/**\r\n * @module Codex Editor 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 * Each Tool must contain the following important objects:\r\n *\r\n * @typedef {Object} ToolConfig {@link docs/tools.md}\r\n * @property {String} iconClassname - this a icon in toolbar\r\n * @property {Boolean} displayInToolbox - will be displayed in toolbox. Default value is TRUE\r\n * @property {Boolean} enableLineBreaks - inserts new block or break lines. Default value is FALSE\r\n * @property {Boolean|String[]} inlineToolbar - Pass `true` to enable the Inline Toolbar with all Tools, all pass an array with specified Tools list |\r\n * @property render @todo add description\r\n * @property save @todo add description\r\n * @property settings @todo add description\r\n * @property validate - method that validates output data before saving\r\n */\r\n\r\n/**\r\n * @typedef {Function} Tool {@link docs/tools.md}\r\n * @property {Boolean} displayInToolbox - By default, tools won't be added in the Toolbox. Pass true to add.\r\n * @property {String} iconClassName - CSS class name for the Toolbox button\r\n * @property {Boolean} irreplaceable - Toolbox behaviour: replace or add new block below\r\n * @property render\r\n * @property save\r\n * @property settings\r\n * @property validate\r\n *\r\n * @todo update according to current API\r\n * @todo describe Tool in the {@link docs/tools.md}\r\n */\r\n\r\n/**\r\n * Class properties:\r\n *\r\n * @typedef {Tools} Tools\r\n * @property {Tools[]} toolsAvailable - available Tools\r\n * @property {Tools[]} toolsUnavailable - unavailable Tools\r\n * @property {Object} toolsClasses - all classes\r\n * @property {EditorConfig} config - Editor config\r\n */\r\nexport default class Tools extends Module {\r\n /**\r\n * Returns available Tools\r\n * @return {Tool[]}\r\n */\r\n get available() {\r\n return this.toolsAvailable;\r\n }\r\n\r\n /**\r\n * Returns unavailable Tools\r\n * @return {Tool[]}\r\n */\r\n get unavailable() {\r\n return this.toolsUnavailable;\r\n }\r\n\r\n /**\r\n * Return Tools for the Inline Toolbar\r\n * @return {Array} - array of Inline Tool's classes\r\n */\r\n get inline() {\r\n return Object.values(this.available).filter( tool => {\r\n if (!tool[this.apiSettings.IS_INLINE]) {\r\n return false;\r\n }\r\n\r\n /**\r\n * Some Tools validation\r\n */\r\n const inlineToolRequiredMethods = ['render', 'surround', 'checkState'];\r\n const notImplementedMethods = inlineToolRequiredMethods.filter( method => !new tool()[method] );\r\n\r\n if (notImplementedMethods.length) {\r\n _.log(`Incorrect Inline Tool: ${tool.name}. Some of required methods is not implemented %o`, 'warn', notImplementedMethods);\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n }\r\n\r\n /**\r\n * Constant for available Tools Settings\r\n * @return {object}\r\n */\r\n get apiSettings() {\r\n return {\r\n IS_INLINE: 'isInline',\r\n TOOLBAR_ICON_CLASS: 'iconClassName',\r\n IS_DISPLAYED_IN_TOOLBOX: 'displayInToolbox',\r\n IS_ENABLED_LINE_BREAKS: 'enableLineBreaks',\r\n IS_IRREPLACEBLE_TOOL: 'irreplaceable',\r\n IS_ENABLED_INLINE_TOOLBAR: 'inlineToolbar',\r\n };\r\n }\r\n\r\n /**\r\n * Static getter for default Tool config fields\r\n * @return {ToolConfig}\r\n */\r\n get defaultConfig() {\r\n return {\r\n [this.apiSettings.TOOLBAR_ICON_CLASS] : false,\r\n [this.apiSettings.IS_DISPLAYED_IN_TOOLBOX] : false,\r\n [this.apiSettings.IS_ENABLED_LINE_BREAKS] : false,\r\n [this.apiSettings.IS_IRREPLACEBLE_TOOL] : false,\r\n [this.apiSettings.IS_ENABLED_INLINE_TOOLBAR]: false,\r\n };\r\n }\r\n\r\n /**\r\n * @constructor\r\n *\r\n * @param {EditorConfig} config\r\n */\r\n constructor({config}) {\r\n super({config});\r\n\r\n /**\r\n * Map {name: Class, ...} where:\r\n * name — block type name in JSON. Got from EditorConfig.tools keys\r\n * @type {Object}\r\n */\r\n this.toolClasses = {};\r\n\r\n /**\r\n * Available tools list\r\n * {name: Class, ...}\r\n * @type {Object}\r\n */\r\n this.toolsAvailable = {};\r\n\r\n /**\r\n * Tools that rejected a prepare method\r\n * {name: Class, ... }\r\n * @type {Object}\r\n */\r\n this.toolsUnavailable = {};\r\n }\r\n\r\n /**\r\n * Creates instances via passed or default configuration\r\n * @return {Promise}\r\n */\r\n prepare() {\r\n if (!this.config.hasOwnProperty('tools')) {\r\n return Promise.reject(\"Can't start without tools\");\r\n }\r\n\r\n for(let toolName in this.config.tools) {\r\n this.toolClasses[toolName] = this.config.tools[toolName];\r\n }\r\n\r\n /**\r\n * getting classes that has prepare method\r\n */\r\n let sequenceData = this.getListOfPrepareFunctions();\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 Util#sequence}\r\n */\r\n return _.sequence(sequenceData, (data) => {\r\n this.success(data);\r\n }, (data) => {\r\n this.fallback(data);\r\n });\r\n }\r\n\r\n /**\r\n * Binds prepare function of plugins with user or default config\r\n * @return {Array} list of functions that needs to be fired sequentially\r\n */\r\n getListOfPrepareFunctions() {\r\n let toolPreparationList = [];\r\n\r\n for(let toolName in this.toolClasses) {\r\n let toolClass = this.toolClasses[toolName];\r\n\r\n if (typeof toolClass.prepare === 'function') {\r\n toolPreparationList.push({\r\n function : toolClass.prepare,\r\n data : {\r\n toolName\r\n }\r\n });\r\n } else {\r\n /**\r\n * If Tool hasn't a prepare method, mark it as available\r\n */\r\n this.toolsAvailable[toolName] = toolClass;\r\n }\r\n }\r\n\r\n return toolPreparationList;\r\n }\r\n\r\n /**\r\n * @param {ChainData.data} data - append tool to available list\r\n */\r\n success(data) {\r\n this.toolsAvailable[data.toolName] = this.toolClasses[data.toolName];\r\n }\r\n\r\n /**\r\n * @param {ChainData.data} data - append tool to unavailable list\r\n */\r\n fallback(data) {\r\n this.toolsUnavailable[data.toolName] = this.toolClasses[data.toolName];\r\n }\r\n\r\n /**\r\n * Return tool`a instance\r\n *\r\n * @param {String} tool — tool name\r\n * @param {Object} data — initial data\r\n *\r\n * @todo throw exceptions if tool doesnt exist\r\n *\r\n */\r\n construct(tool, data) {\r\n let plugin = this.toolClasses[tool],\r\n config = this.config.toolsConfig[tool];\r\n\r\n let instance = new plugin(data, config || {});\r\n\r\n return instance;\r\n }\r\n\r\n /**\r\n * Check if passed Tool is an instance of Initial Block Tool\r\n * @param {Tool} tool - Tool to check\r\n * @return {Boolean}\r\n */\r\n isInitial(tool) {\r\n return tool instanceof this.available[this.config.initialBlock];\r\n }\r\n}\r\n","/**\r\n * Module UI\r\n *\r\n * @type {UI}\r\n */\r\n\r\n/**\r\n * Prebuilded sprite of SVG icons\r\n */\r\nimport sprite from '../../../build/sprite.svg';\r\nimport Selection from '../selection';\r\n\r\n/**\r\n * @class\r\n *\r\n * @classdesc Makes CodeX Editor UI:\r\n * \r\n * \r\n * \r\n * \r\n * \r\n *\r\n * @typedef {UI} UI\r\n * @property {EditorConfig} config - editor configuration {@link CodexEditor#configuration}\r\n * @property {Object} Editor - available editor modules {@link CodexEditor#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 - \r\n * @property {Element} nodes.redactor - \r\n */\r\nexport default class UI extends Module {\r\n /**\r\n * @constructor\r\n *\r\n * @param {EditorConfig} config\r\n */\r\n constructor({config}) {\r\n super({config});\r\n\r\n this.nodes = {\r\n holder: null,\r\n wrapper: null,\r\n redactor: null\r\n };\r\n }\r\n\r\n /**\r\n * Making main interface\r\n */\r\n prepare() {\r\n return this.make()\r\n /**\r\n * Append SVG sprite\r\n */\r\n .then(() => this.appendSVGSprite())\r\n /**\r\n * Make toolbar\r\n */\r\n .then(() => this.Editor.Toolbar.make())\r\n /**\r\n * Make the Inline toolbar\r\n */\r\n .then(() => this.Editor.InlineToolbar.make())\r\n /**\r\n * Load and append CSS\r\n */\r\n .then(() => this.loadStyles())\r\n /**\r\n * Bind events for the UI elements\r\n */\r\n .then(() => this.bindEvents())\r\n\r\n /** Make container for inline toolbar */\r\n // .then(makeInlineToolbar_)\r\n\r\n /** Add inline toolbar tools */\r\n // .then(addInlineToolbarTools_)\r\n\r\n /** Draw wrapper for notifications */\r\n // .then(makeNotificationHolder_)\r\n\r\n /** Add eventlisteners to redactor elements */\r\n // .then(bindEvents_)\r\n\r\n .catch(e => {\r\n console.error(e);\r\n\r\n // editor.core.log(\"Can't draw editor interface\");\r\n });\r\n }\r\n\r\n /**\r\n * CodeX Editor UI CSS class names\r\n * @return {{editorWrapper: string, editorZone: string, block: string}}\r\n */\r\n get CSS() {\r\n return {\r\n editorWrapper : 'codex-editor',\r\n editorZone : 'codex-editor__redactor',\r\n };\r\n }\r\n\r\n /**\r\n * Makes CodeX Editor interface\r\n * @return {Promise}\r\n */\r\n make() {\r\n return new Promise( (resolve, reject) => {\r\n /**\r\n * Element where we need to append CodeX Editor\r\n * @type {Element}\r\n */\r\n this.nodes.holder = document.getElementById(this.config.holderId);\r\n\r\n if (!this.nodes.holder) {\r\n reject(Error(\"Holder wasn't found by ID: #\" + this.config.holderId));\r\n return;\r\n }\r\n\r\n /**\r\n * Create and save main UI elements\r\n */\r\n this.nodes.wrapper = $.make('div', this.CSS.editorWrapper);\r\n this.nodes.redactor = $.make('div', this.CSS.editorZone);\r\n\r\n this.nodes.wrapper.appendChild(this.nodes.redactor);\r\n this.nodes.holder.appendChild(this.nodes.wrapper);\r\n\r\n resolve();\r\n });\r\n }\r\n\r\n /**\r\n * Appends CSS\r\n */\r\n loadStyles() {\r\n /**\r\n * Load CSS\r\n */\r\n let styles = require('../../styles/main.css');\r\n\r\n /**\r\n * Make tag\r\n */\r\n let tag = $.make('style', null, {\r\n textContent: styles.toString()\r\n });\r\n\r\n /**\r\n * Append styles\r\n */\r\n $.append(document.head, tag);\r\n }\r\n\r\n /**\r\n * Bind events on the CodeX Editor interface\r\n */\r\n bindEvents() {\r\n this.Editor.Listeners.on(this.nodes.redactor, 'click', event => this.redactorClicked(event), false );\r\n this.Editor.Listeners.on(document, 'keydown', event => this.documentKeydown(event), true );\r\n this.Editor.Listeners.on(document, 'click', event => this.documentClicked(event), false );\r\n }\r\n\r\n /**\r\n * All keydowns on document\r\n * @param event\r\n */\r\n documentKeydown(event) {\r\n switch (event.keyCode) {\r\n case _.keyCodes.ENTER:\r\n this.enterPressed(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 * @param {KeyboardEvent} event\r\n */\r\n defaultBehaviour(event) {\r\n const keyDownOnEditor = event.target.closest(`.${this.CSS.editorWrapper}`);\r\n\r\n /**\r\n * Ignore keydowns on document\r\n * clear pointer and close toolbar\r\n */\r\n if (!keyDownOnEditor) {\r\n /**\r\n * Remove all highlights and remove caret\r\n */\r\n this.Editor.BlockManager.dropPointer();\r\n\r\n /**\r\n * Close Toolbar\r\n */\r\n this.Editor.Toolbar.close();\r\n }\r\n }\r\n\r\n /**\r\n * Enter pressed on document\r\n * @param event\r\n */\r\n enterPressed(event) {\r\n let hasPointerToBlock = this.Editor.BlockManager.currentBlockIndex >= 0;\r\n\r\n /**\r\n * If Selection is out of Editor and document has some selection\r\n */\r\n if (!Selection.isAtEditor && Selection.anchorNode) {\r\n return;\r\n }\r\n\r\n /**\r\n * If there is no selection (caret is not placed) and BlockManager points some to Block\r\n */\r\n if (hasPointerToBlock && !Selection.anchorNode) {\r\n /**\r\n * Insert initial typed Block\r\n */\r\n this.Editor.BlockManager.insert();\r\n this.Editor.BlockManager.highlightCurrentNode();\r\n\r\n /**\r\n * Move toolbar and show plus button because new Block is empty\r\n */\r\n this.Editor.Toolbar.move();\r\n this.Editor.Toolbar.plusButton.show();\r\n }\r\n }\r\n\r\n /**\r\n * All clicks on document\r\n * @param {MouseEvent} event - Click\r\n */\r\n documentClicked(event) {\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 clickedOnInlineToolbarButton = event.target.closest(`.${this.Editor.InlineToolbar.CSS.inlineToolbar}`);\r\n const clickedInsideofEditor = event.target.closest(`.${this.CSS.editorWrapper}`);\r\n\r\n /** Clear highlightings and pointer on BlockManager */\r\n if (!clickedInsideofEditor) {\r\n this.Editor.BlockManager.dropPointer();\r\n this.Editor.Toolbar.close();\r\n }\r\n\r\n if (!clickedOnInlineToolbarButton) {\r\n this.Editor.InlineToolbar.handleShowingEvent(event);\r\n }\r\n }\r\n\r\n /**\r\n * All clicks on the redactor zone\r\n *\r\n * @param {MouseEvent} event\r\n *\r\n * @description\r\n * 1. Save clicked Block as a current {@link BlockManager#currentNode}\r\n * it uses for the following:\r\n * - add CSS modifier for the selected Block\r\n * - on Enter press, we make a new Block under that\r\n *\r\n * 2. Move and show the Toolbar\r\n *\r\n * 3. Set a Caret\r\n *\r\n * 4. 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 * 5. Hide the Inline Toolbar\r\n *\r\n * @see selectClickedBlock\r\n *\r\n */\r\n redactorClicked(event) {\r\n let clickedNode = event.target;\r\n\r\n /**\r\n * Select clicked Block as Current\r\n */\r\n try {\r\n /**\r\n * Renew Current Block\r\n */\r\n this.Editor.BlockManager.setCurrentBlockByChildNode(clickedNode);\r\n\r\n /**\r\n * Highlight Current Node\r\n */\r\n this.Editor.BlockManager.highlightCurrentNode();\r\n } catch (e) {\r\n /**\r\n * If clicked outside first-level Blocks, set Caret to the last empty Block\r\n */\r\n this.Editor.Caret.setToTheLastBlock();\r\n }\r\n\r\n /**\r\n * Move toolbar and open\r\n */\r\n this.Editor.Toolbar.move();\r\n this.Editor.Toolbar.open();\r\n\r\n /**\r\n * Hide the Plus Button\r\n * */\r\n this.Editor.Toolbar.plusButton.hide();\r\n\r\n /**\r\n * Show the Plus Button if:\r\n * - Block is an initial-block (Text)\r\n * - Block is empty\r\n */\r\n let isInitialBlock = this.Editor.Tools.isInitial(this.Editor.BlockManager.currentBlock.tool),\r\n isEmptyBlock = this.Editor.BlockManager.currentBlock.isEmpty;\r\n\r\n if (isInitialBlock && isEmptyBlock) {\r\n this.Editor.Toolbar.plusButton.show();\r\n }\r\n }\r\n\r\n /**\r\n * Append prebuilded sprite with SVG icons\r\n */\r\n appendSVGSprite() {\r\n let spriteHolder = $.make('div');\r\n\r\n spriteHolder.innerHTML = sprite;\r\n\r\n $.append(this.nodes.wrapper, spriteHolder);\r\n }\r\n}\r\n\r\n// /**\r\n// * Codex Editor UI module\r\n// *\r\n// * @author Codex Team\r\n// * @version 1.2.0\r\n// */\r\n//\r\n// module.exports = (function (ui) {\r\n//\r\n// let editor = codex.editor;\r\n//\r\n// /**\r\n// * Basic editor classnames\r\n// */\r\n// ui.prepare = function () {\r\n//\r\n\r\n//\r\n// };\r\n//\r\n// /** Draw notifications holder */\r\n// var makeNotificationHolder_ = function () {\r\n//\r\n// /** Append block with notifications to the document */\r\n// editor.nodes.notifications = editor.notifications.createHolder();\r\n//\r\n// };\r\n//\r\n//\r\n// var addInlineToolbarTools_ = function () {\r\n//\r\n// var tools = {\r\n//\r\n// bold: {\r\n// icon : 'ce-icon-bold',\r\n// command : 'bold'\r\n// },\r\n//\r\n// italic: {\r\n// icon : 'ce-icon-italic',\r\n// command : 'italic'\r\n// },\r\n//\r\n// link: {\r\n// icon : 'ce-icon-link',\r\n// command : 'createLink'\r\n// }\r\n// };\r\n//\r\n// var toolButton,\r\n// tool;\r\n//\r\n// for(var name in tools) {\r\n//\r\n// tool = tools[name];\r\n//\r\n// toolButton = editor.draw.toolbarButtonInline(name, tool.icon);\r\n//\r\n// editor.nodes.inlineToolbar.buttons.appendChild(toolButton);\r\n// /**\r\n// * Add callbacks to this buttons\r\n// */\r\n// editor.ui.setInlineToolbarButtonBehaviour(toolButton, tool.command);\r\n//\r\n// }\r\n//\r\n// };\r\n//\r\n// /**\r\n// * @private\r\n// * Bind editor UI events\r\n// */\r\n// var bindEvents_ = function () {\r\n//\r\n// editor.core.log('ui.bindEvents fired', 'info');\r\n//\r\n// // window.addEventListener('error', function (errorMsg, url, lineNumber) {\r\n// // editor.notifications.errorThrown(errorMsg, event);\r\n// // }, false );\r\n//\r\n// /** All keydowns on Document */\r\n// editor.listeners.add(document, 'keydown', editor.callback.globalKeydown, false);\r\n//\r\n// /** All keydowns on Redactor zone */\r\n// editor.listeners.add(editor.nodes.redactor, 'keydown', editor.callback.redactorKeyDown, false);\r\n//\r\n// /** All keydowns on Document */\r\n// editor.listeners.add(document, 'keyup', editor.callback.globalKeyup, false );\r\n//\r\n// /**\r\n// * Mouse click to radactor\r\n// */\r\n// editor.listeners.add(editor.nodes.redactor, 'click', editor.callback.redactorClicked, false );\r\n//\r\n// /**\r\n// * Clicks to the Plus button\r\n// */\r\n// editor.listeners.add(editor.nodes.plusButton, 'click', editor.callback.plusButtonClicked, false);\r\n//\r\n// /**\r\n// * Clicks to SETTINGS button in toolbar\r\n// */\r\n// editor.listeners.add(editor.nodes.showSettingsButton, 'click', editor.callback.showSettingsButtonClicked, false );\r\n//\r\n// /** Bind click listeners on toolbar buttons */\r\n// for (var button in editor.nodes.toolbarButtons) {\r\n//\r\n// editor.listeners.add(editor.nodes.toolbarButtons[button], 'click', editor.callback.toolbarButtonClicked, false);\r\n//\r\n// }\r\n//\r\n// };\r\n//\r\n// ui.addBlockHandlers = function (block) {\r\n//\r\n// if (!block) return;\r\n//\r\n// /**\r\n// * Block keydowns\r\n// */\r\n// editor.listeners.add(block, 'keydown', editor.callback.blockKeydown, false);\r\n//\r\n// /**\r\n// * Pasting content from another source\r\n// * We have two type of sanitization\r\n// * First - uses deep-first search algorithm to get sub nodes,\r\n// * sanitizes whole Block_content and replaces cleared nodes\r\n// * This method is deprecated\r\n// * Method is used in editor.callback.blockPaste(event)\r\n// *\r\n// * Secont - uses Mutation observer.\r\n// * Observer \"observe\" DOM changes and send changings to callback.\r\n// * Callback gets changed node, not whole Block_content.\r\n// * Inserted or changed node, which we've gotten have been cleared and replaced with diry node\r\n// *\r\n// * Method is used in editor.callback.blockPasteViaSanitize(event)\r\n// *\r\n// * @uses html-janitor\r\n// * @example editor.callback.blockPasteViaSanitize(event), the second method.\r\n// *\r\n// */\r\n// editor.listeners.add(block, 'paste', editor.paste.blockPasteCallback, false);\r\n//\r\n// /**\r\n// * Show inline toolbar for selected text\r\n// */\r\n// editor.listeners.add(block, 'mouseup', editor.toolbar.inline.show, false);\r\n// editor.listeners.add(block, 'keyup', editor.toolbar.inline.show, false);\r\n//\r\n// };\r\n//\r\n// /** getting all contenteditable elements */\r\n// ui.saveInputs = function () {\r\n//\r\n// var redactor = editor.nodes.redactor;\r\n//\r\n// editor.state.inputs = [];\r\n//\r\n// /** Save all inputs in global variable state */\r\n// var inputs = redactor.querySelectorAll('[contenteditable], input, textarea');\r\n//\r\n// Array.prototype.map.call(inputs, function (current) {\r\n//\r\n// if (!current.type || current.type == 'text' || current.type == 'textarea') {\r\n//\r\n// editor.state.inputs.push(current);\r\n//\r\n// }\r\n//\r\n// });\r\n//\r\n// };\r\n//\r\n// /**\r\n// * Adds first initial block on empty redactor\r\n// */\r\n// ui.addInitialBlock = function () {\r\n//\r\n// var initialBlockType = editor.settings.initialBlockPlugin,\r\n// initialBlock;\r\n//\r\n// if ( !editor.tools[initialBlockType] ) {\r\n//\r\n// editor.core.log('Plugin %o was not implemented and can\\'t be used as initial block', 'warn', initialBlockType);\r\n// return;\r\n//\r\n// }\r\n//\r\n// initialBlock = editor.tools[initialBlockType].render();\r\n//\r\n// initialBlock.setAttribute('data-placeholder', editor.settings.placeholder);\r\n//\r\n// editor.content.insertBlock({\r\n// type : initialBlockType,\r\n// block : initialBlock\r\n// });\r\n//\r\n// editor.content.workingNodeChanged(initialBlock);\r\n//\r\n// };\r\n//\r\n// ui.setInlineToolbarButtonBehaviour = function (button, type) {\r\n//\r\n// editor.listeners.add(button, 'mousedown', function (event) {\r\n//\r\n// editor.toolbar.inline.toolClicked(event, type);\r\n//\r\n// }, false);\r\n//\r\n// };\r\n//\r\n// return ui;\r\n//\r\n// })({});\r\n","/**\r\n * Element.closest()\r\n *\r\n * https://developer.mozilla.org/en-US/docs/Web/API/Element/closest\r\n */\r\nif (!Element.prototype.matches)\r\n Element.prototype.matches = Element.prototype.msMatchesSelector ||\r\n Element.prototype.webkitMatchesSelector;\r\n\r\nif (!Element.prototype.closest)\r\n Element.prototype.closest = function (s) {\r\n var el = this;\r\n\r\n if (!document.documentElement.contains(el)) return null;\r\n do {\r\n if (el.matches(s)) return el;\r\n el = el.parentElement || el.parentNode;\r\n } while (el !== null);\r\n return null;\r\n };\r\n","/**\r\n * Working with selection\r\n * @typedef {Selection} Selection\r\n */\r\nexport default class Selection {\r\n /**\r\n * @constructor\r\n */\r\n constructor() {\r\n this.instance = null;\r\n this.selection = null;\r\n\r\n /**\r\n * This property can store Selection's range for restoring later\r\n * @type {Range|null}\r\n */\r\n this.savedSelectionRange = null;\r\n }\r\n\r\n /**\r\n * Editor styles\r\n * @return {{editorWrapper: string, editorZone: string}}\r\n * @constructor\r\n */\r\n static get CSS() {\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 window Selection\r\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Window/getSelection}\r\n * @return {Selection}\r\n */\r\n static get() {\r\n return window.getSelection();\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 * @return {Node|null}\r\n */\r\n static get anchorNode() {\r\n const selection = window.getSelection();\r\n\r\n return selection ? selection.anchorNode : null;\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 * @return {Number|null}\r\n */\r\n static get anchorOffset() {\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 * @return {boolean|null}\r\n */\r\n static get isCollapsed() {\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 * @return {boolean}\r\n */\r\n static get isAtEditor() {\r\n let selection = Selection.get(),\r\n selectedNode,\r\n editorZone = false;\r\n\r\n /**\r\n * Something selected on document\r\n */\r\n selectedNode = selection.anchorNode || selection.focusNode;\r\n\r\n if (selectedNode && selectedNode.nodeType === Node.TEXT_NODE) {\r\n selectedNode = selectedNode.parentNode;\r\n }\r\n\r\n if (selectedNode) {\r\n editorZone = selectedNode.closest(`.${Selection.CSS.editorZone}`);\r\n }\r\n\r\n /**\r\n * Selection is not out of Editor because Editor's wrapper was found\r\n */\r\n return editorZone && editorZone.nodeType === Node.ELEMENT_NODE;\r\n }\r\n\r\n /**\r\n * Return first range\r\n * @return {Range|null}\r\n */\r\n static get range() {\r\n const selection = window.getSelection();\r\n\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 * @return {{x, y, width, height, top?, left?, bottom?, right?}}\r\n */\r\n static get rect() {\r\n let sel = document.selection, range;\r\n let rect = {\r\n x: 0,\r\n y: 0,\r\n width: 0,\r\n height: 0\r\n };\r\n\r\n if (sel && sel.type !== 'Control') {\r\n range = sel.createRange();\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 return rect;\r\n }\r\n\r\n sel = window.getSelection();\r\n\r\n if (!sel.rangeCount) {\r\n _.log('Method Selection.rangeCount() is not supported', 'warn');\r\n return rect;\r\n }\r\n\r\n range = sel.getRangeAt(0).cloneRange();\r\n\r\n if (range.getBoundingClientRect) {\r\n rect = range.getBoundingClientRect();\r\n }\r\n // Fall back to inserting a temporary element\r\n if (rect.x === 0 && rect.y === 0) {\r\n let 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();\r\n\r\n let 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 * @returns {string}\r\n */\r\n static get text() {\r\n return window.getSelection ? window.getSelection().toString() : '';\r\n };\r\n\r\n /**\r\n * Save Selection's range\r\n */\r\n save() {\r\n this.savedSelectionRange = Selection.range;\r\n }\r\n\r\n /**\r\n * Restore saved Selection's range\r\n */\r\n restore() {\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 clearSaved() {\r\n this.savedSelectionRange = null;\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 * @return {HTMLElement|null}\r\n */\r\n findParentTag(tagName, className, searchDepth = 10) {\r\n let selection = window.getSelection(),\r\n 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 let boundNodes = [\r\n /** the Node in which the selection begins */\r\n selection.anchorNode,\r\n /** the Node in which the selection ends */\r\n selection.focusNode\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 * Optional additional check for class-name matching\r\n */\r\n if (className && parent.classList && !parent.classList.contains(className)) {\r\n continue;\r\n }\r\n\r\n /**\r\n * If we have found required tag with class then save the result and go out from cycle\r\n */\r\n parentTag = parent;\r\n break;\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;\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} node\r\n */\r\n expandToTag(node) {\r\n let selection = window.getSelection();\r\n\r\n selection.removeAllRanges();\r\n let range = document.createRange();\r\n\r\n range.selectNodeContents(node);\r\n selection.addRange(range);\r\n }\r\n}\r\n","/**\r\n * Codex Editor Util\r\n */\r\nexport default class Util {\r\n /**\r\n * Custom logger\r\n *\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 */\r\n static log(msg, type, args) {\r\n type = type || 'log';\r\n\r\n if (!args) {\r\n args = msg || 'undefined';\r\n msg = '[codex-editor]: %o';\r\n } else {\r\n msg = '[codex-editor]: ' + msg;\r\n }\r\n\r\n try{\r\n if ( 'console' in window && window.console[ type ] ) {\r\n if ( args ) window.console[ type ]( msg, args );\r\n else window.console[ type ]( msg );\r\n }\r\n } catch(e) {\r\n // do nothing\r\n }\r\n }\r\n\r\n /**\r\n * Returns basic keycodes as constants\r\n * @return {{}}\r\n */\r\n static get keyCodes() {\r\n return {\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 };\r\n }\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 asynchronically\r\n */\r\n\r\n /**\r\n * Fires a promise sequence asyncronically\r\n *\r\n * @param {Object[]} 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 *\r\n * @return {Promise}\r\n */\r\n static sequence(chains, success = () => {}, fallback = () => {}) {\r\n return new Promise(function (resolve) {\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 chains.reduce(function (previousValue, currentValue, iteration) {\r\n return previousValue\r\n .then(() => waitNextBlock(currentValue, success, fallback))\r\n .then(() => {\r\n // finished\r\n if (iteration === chains.length - 1) {\r\n resolve();\r\n }\r\n });\r\n }, Promise.resolve());\r\n });\r\n\r\n /**\r\n * Decorator\r\n *\r\n * @param {ChainData} chainData\r\n *\r\n * @param {Function} successCallback\r\n * @param {Function} fallbackCallback\r\n *\r\n * @return {Promise}\r\n */\r\n function waitNextBlock(chainData, successCallback, fallbackCallback) {\r\n return new Promise(function (resolve) {\r\n chainData.function()\r\n .then(() => {\r\n successCallback(chainData.data || {});\r\n })\r\n .then(resolve)\r\n .catch(function () {\r\n fallbackCallback(chainData.data || {});\r\n\r\n // anyway, go ahead even it falls\r\n resolve();\r\n });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Make array from array-like collection\r\n *\r\n * @param {*} collection\r\n *\r\n * @return {Array}\r\n */\r\n static array(collection) {\r\n return Array.prototype.slice.call(collection);\r\n }\r\n\r\n /**\r\n * Checks if object is empty\r\n *\r\n * @param {Object} object\r\n * @return {boolean}\r\n */\r\n static isEmpty(object) {\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 * @param {*} object - object to check\r\n * @return {Boolean}\r\n */\r\n static isPromise(object) {\r\n return Promise.resolve(object) === object;\r\n }\r\n\r\n /**\r\n * Check if passed element is contenteditable\r\n * @param element\r\n * @return {boolean}\r\n */\r\n static isContentEditable(element) {\r\n return element.contentEditable === 'true';\r\n }\r\n\r\n /**\r\n * Delays method execution\r\n *\r\n * @param method\r\n * @param timeout\r\n */\r\n static delay(method, timeout) {\r\n return function () {\r\n let context = this,\r\n args = arguments;\r\n\r\n window.setTimeout(() => method.apply(context, args), timeout);\r\n };\r\n }\r\n};\r\n","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \":root {\\r\\n /**\\r\\n * Selection color\\r\\n */\\r\\n --selectionColor: rgba(61,166,239,0.63);\\r\\n\\r\\n /**\\r\\n * Toolbar buttons\\r\\n */\\r\\n --bg-light: #eff2f5;\\r\\n\\r\\n /**\\r\\n * All gray texts: placeholders, settings\\r\\n */\\r\\n --grayText: #707684;\\r\\n\\r\\n /** Blue icons */\\r\\n --color-active-icon: #388AE5;\\r\\n\\r\\n /**\\r\\n * Block content width\\r\\n */\\r\\n --content-width: 650px;\\r\\n\\r\\n /**\\r\\n * Toolbar buttons height and width\\r\\n */\\r\\n --toolbar-buttons-size: 34px;\\r\\n\\r\\n /**\\r\\n * Toolbar Plus Button and Toolbox buttons height and width\\r\\n */\\r\\n --toolbox-buttons-size: 20px;\\r\\n\\r\\n /**\\r\\n * Confirm deletion bg\\r\\n */\\r\\n --color-confirm: #E24A4A;\\r\\n}\\r\\n/**\\r\\n* Editor wrapper\\r\\n*/\\r\\n.codex-editor {\\r\\n position: relative;\\r\\n box-sizing: border-box;\\r\\n}\\r\\n.codex-editor .hide {\\r\\n display: none;\\r\\n }\\r\\n.codex-editor__redactor {\\r\\n padding-bottom: 300px;\\r\\n }\\r\\n.codex-editor svg {\\r\\n fill: currentColor;\\r\\n vertical-align: middle;\\r\\n max-height: 100%;\\r\\n }\\r\\n/**\\r\\n * Set color for native selection\\r\\n */\\r\\n::-moz-selection{\\r\\n background-color: rgba(61,166,239,0.63);\\r\\n background-color: var(--selectionColor);\\r\\n}\\r\\n::selection{\\r\\n background-color: rgba(61,166,239,0.63);\\r\\n background-color: var(--selectionColor);\\r\\n}\\r\\n/**\\r\\n * Add placeholder to content editable elements with data attribute\\r\\n * data-placeholder=\\\"Hello world!\\\"\\r\\n */\\r\\n[contentEditable=true][data-placeholder]:empty:not(:focus):before{\\r\\n content: attr(data-placeholder);\\r\\n color: #707684;\\r\\n color: var(--grayText);\\r\\n}\\r\\n.ce-toolbar {\\r\\n position: absolute;\\r\\n left: 0;\\r\\n right: 0;\\r\\n top: 0;\\r\\n /*opacity: 0;*/\\r\\n /*visibility: hidden;*/\\r\\n transition: opacity 100ms ease;\\r\\n will-change: opacity, transform;\\r\\n display: none;\\r\\n}\\r\\n.ce-toolbar--opened {\\r\\n display: block;\\r\\n /*opacity: 1;*/\\r\\n /*visibility: visible;*/\\r\\n }\\r\\n.ce-toolbar__content {\\r\\n max-width: 650px;\\r\\n max-width: var(--content-width);\\r\\n margin: 0 auto;\\r\\n position: relative;\\r\\n }\\r\\n.ce-toolbar__plus {\\r\\n color: #707684;\\r\\n color: var(--grayText);\\r\\n cursor: pointer;\\r\\n display: inline-block;\\r\\n width: 20px;\\r\\n width: var(--toolbox-buttons-size);\\r\\n height: 20px;\\r\\n height: var(--toolbox-buttons-size);\\r\\n line-height: 20px;\\r\\n line-height: var(--toolbox-buttons-size)\\r\\n }\\r\\n.ce-toolbar__plus:not(:last-of-type){\\r\\n margin-right: 3px;\\r\\n }\\r\\n.ce-toolbar__plus:hover {\\r\\n color: #388AE5;\\r\\n color: var(--color-active-icon);\\r\\n }\\r\\n.ce-toolbar__plus {\\r\\n\\r\\n position: absolute;\\r\\n top: -1px;\\r\\n left: calc(calc(20px + 10px) * -1);\\r\\n left: calc(calc(var(--toolbox-buttons-size) + 10px) * -1);\\r\\n }\\r\\n.ce-toolbar__plus--hidden {\\r\\n display: none;\\r\\n }\\r\\n/**\\r\\n * Block actions Zone\\r\\n * -------------------------\\r\\n */\\r\\n.ce-toolbar__actions {\\r\\n position: absolute;\\r\\n right: 0;\\r\\n top: 0;\\r\\n padding-right: 16px;\\r\\n }\\r\\n.ce-toolbar__actions-buttons {\\r\\n text-align: right;\\r\\n }\\r\\n.ce-toolbar__settings-btn {\\r\\n display: inline-block;\\r\\n width: 24px;\\r\\n height: 24px;\\r\\n color: #707684;\\r\\n color: var(--grayText);\\r\\n cursor: pointer;\\r\\n }\\r\\n.ce-toolbox {\\r\\n position: absolute;\\r\\n visibility: hidden;\\r\\n transition: opacity 100ms ease;\\r\\n will-change: opacity;\\r\\n}\\r\\n.ce-toolbox--opened {\\r\\n opacity: 1;\\r\\n visibility: visible;\\r\\n }\\r\\n.ce-toolbox__button {\\r\\n color: #707684;\\r\\n color: var(--grayText);\\r\\n cursor: pointer;\\r\\n display: inline-block;\\r\\n width: 20px;\\r\\n width: var(--toolbox-buttons-size);\\r\\n height: 20px;\\r\\n height: var(--toolbox-buttons-size);\\r\\n line-height: 20px;\\r\\n line-height: var(--toolbox-buttons-size);\\r\\n }\\r\\n.ce-toolbox__button:not(:last-of-type){\\r\\n margin-right: 3px;\\r\\n }\\r\\n.ce-toolbox__button:hover {\\r\\n color: #388AE5;\\r\\n color: var(--color-active-icon);\\r\\n }\\r\\n.ce-inline-toolbar {\\r\\n position: absolute;\\r\\n background-color: #FFFFFF;\\r\\n box-shadow: 0 8px 23px -6px rgba(21,40,54,0.31), 22px -14px 34px -18px rgba(33,48,73,0.26);\\r\\n border-radius: 4px;\\r\\n z-index: 2\\r\\n}\\r\\n.ce-inline-toolbar::before {\\r\\n content: '';\\r\\n width: 15px;\\r\\n height: 15px;\\r\\n position: absolute;\\r\\n top: -7px;\\r\\n left: 50%;\\r\\n margin-left: -7px;\\r\\n transform: rotate(-45deg);\\r\\n background-color: #fff;\\r\\n z-index: -1;\\r\\n }\\r\\n.ce-inline-toolbar {\\r\\n padding: 6px;\\r\\n transform: translateX(-50%);\\r\\n display: none;\\r\\n box-shadow: 0 6px 12px -6px rgba(131, 147, 173, 0.46),\\r\\n 5px -12px 34px -13px rgba(97, 105, 134, 0.6),\\r\\n 0 26px 52px 3px rgba(147, 165, 186, 0.24);\\r\\n}\\r\\n.ce-inline-toolbar--showed {\\r\\n display: block;\\r\\n }\\r\\n.ce-inline-tool {\\r\\n display: inline-block;\\r\\n width: 34px;\\r\\n height: 34px;\\r\\n line-height: 34px;\\r\\n text-align: center;\\r\\n border-radius: 3px;\\r\\n cursor: pointer;\\r\\n border: 0;\\r\\n outline: none;\\r\\n background-color: transparent;\\r\\n vertical-align: bottom;\\r\\n color: #707684;\\r\\n color: var(--grayText)\\r\\n}\\r\\n.ce-inline-tool:not(:last-of-type){\\r\\n margin-right: 5px;\\r\\n }\\r\\n.ce-inline-tool:hover {\\r\\n background-color: #eff2f5;\\r\\n background-color: var(--bg-light);\\r\\n }\\r\\n.ce-inline-tool {\\r\\n line-height: normal;\\r\\n}\\r\\n.ce-inline-tool--active {\\r\\n color: #388AE5;\\r\\n color: var(--color-active-icon);\\r\\n }\\r\\n.ce-inline-tool--link .icon {\\r\\n margin-top: -2px;\\r\\n }\\r\\n.ce-inline-tool--link .icon--unlink {\\r\\n display: none;\\r\\n }\\r\\n.ce-inline-tool--unlink .icon--link {\\r\\n display: none;\\r\\n }\\r\\n.ce-inline-tool--unlink .icon--unlink {\\r\\n display: inline-block;\\r\\n }\\r\\n.ce-inline-tool-input {\\r\\n background-color: #eff2f5;\\r\\n background-color: var(--bg-light);\\r\\n outline: none;\\r\\n border: 0;\\r\\n border-radius: 3px;\\r\\n margin: 6px 0 0;\\r\\n font-size: 13px;\\r\\n padding: 8px;\\r\\n width: 100%;\\r\\n box-sizing: border-box;\\r\\n display: none\\r\\n }\\r\\n.ce-inline-tool-input::-webkit-input-placeholder {\\r\\n color: #707684;\\r\\n color: var(--grayText);\\r\\n }\\r\\n.ce-inline-tool-input:-ms-input-placeholder {\\r\\n color: #707684;\\r\\n color: var(--grayText);\\r\\n }\\r\\n.ce-inline-tool-input::placeholder {\\r\\n color: #707684;\\r\\n color: var(--grayText);\\r\\n }\\r\\n.ce-inline-tool-input--showed {\\r\\n display: block;\\r\\n }\\r\\n.ce-settings {\\r\\n position: absolute;\\r\\n background-color: #FFFFFF;\\r\\n box-shadow: 0 8px 23px -6px rgba(21,40,54,0.31), 22px -14px 34px -18px rgba(33,48,73,0.26);\\r\\n border-radius: 4px;\\r\\n z-index: 2\\r\\n}\\r\\n.ce-settings::before {\\r\\n content: '';\\r\\n width: 15px;\\r\\n height: 15px;\\r\\n position: absolute;\\r\\n top: -7px;\\r\\n left: 50%;\\r\\n margin-left: -7px;\\r\\n transform: rotate(-45deg);\\r\\n background-color: #fff;\\r\\n z-index: -1;\\r\\n }\\r\\n.ce-settings {\\r\\n right: 5px;\\r\\n top: 35px;\\r\\n min-width: 124px\\r\\n}\\r\\n.ce-settings::before{\\r\\n left: auto;\\r\\n right: 12px;\\r\\n }\\r\\n.ce-settings {\\r\\n\\r\\n display: none;\\r\\n}\\r\\n.ce-settings--opened {\\r\\n display: block;\\r\\n }\\r\\n.ce-settings__plugin-zone:not(:empty){\\r\\n padding: 6px 6px 0;\\r\\n }\\r\\n.ce-settings__default-zone:not(:empty){\\r\\n padding: 6px;\\r\\n }\\r\\n.ce-settings__button {\\r\\n display: inline-block;\\r\\n width: 34px;\\r\\n height: 34px;\\r\\n line-height: 34px;\\r\\n text-align: center;\\r\\n border-radius: 3px;\\r\\n cursor: pointer;\\r\\n border: 0;\\r\\n outline: none;\\r\\n background-color: transparent;\\r\\n vertical-align: bottom;\\r\\n color: #707684;\\r\\n color: var(--grayText)\\r\\n }\\r\\n.ce-settings__button:not(:last-of-type){\\r\\n margin-right: 5px;\\r\\n }\\r\\n.ce-settings__button:hover {\\r\\n background-color: #eff2f5;\\r\\n background-color: var(--bg-light);\\r\\n }\\r\\n.ce-settings__button--active {\\r\\n color: #388AE5;\\r\\n color: var(--color-active-icon);\\r\\n }\\r\\n.ce-settings__button--disabled {\\r\\n cursor: not-allowed !important;\\r\\n opacity: .3;\\r\\n }\\r\\n.ce-settings__button--selected {\\r\\n color: #388AE5;\\r\\n color: var(--color-active-icon);\\r\\n }\\r\\n.ce-settings__button--delete {\\r\\n transition: background-color 300ms ease;\\r\\n will-change: background-color;\\r\\n }\\r\\n.ce-settings__button--delete .icon {\\r\\n transition: transform 200ms ease-out;\\r\\n will-change: transform;\\r\\n }\\r\\n.ce-settings__button--confirm {\\r\\n background-color: #E24A4A;\\r\\n background-color: var(--color-confirm);\\r\\n color: #fff\\r\\n }\\r\\n.ce-settings__button--confirm:hover {\\r\\n background-color: rgb(213, 74, 74) !important;\\r\\n background-color: rgb(213, 74, 74) !important;\\r\\n }\\r\\n.ce-settings__button--confirm .icon {\\r\\n transform: rotate(90deg);\\r\\n }\\r\\n.ce-block:first-of-type {\\r\\n margin-top: 0;\\r\\n }\\r\\n.ce-block--selected {\\r\\n background-image: linear-gradient(17deg, rgba(243, 248, 255, 0.03) 63.45%, rgba(207, 214, 229, 0.27) 98%);\\r\\n border-radius: 3px;\\r\\n }\\r\\n.ce-block__content {\\r\\n max-width: 650px;\\r\\n max-width: var(--content-width);\\r\\n margin: 0 auto;\\r\\n }\\r\\n.wobble {\\r\\n animation-name: wobble;\\r\\n animation-duration: 400ms;\\r\\n}\\r\\n/**\\r\\n * @author Nick Pettit - https://github.com/nickpettit/glide\\r\\n */\\r\\n@keyframes wobble {\\r\\n from {\\r\\n transform: translate3d(0, 0, 0);\\r\\n }\\r\\n\\r\\n 15% {\\r\\n transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -5deg);\\r\\n }\\r\\n\\r\\n 30% {\\r\\n transform: translate3d(2%, 0, 0) rotate3d(0, 0, 1, 3deg);\\r\\n }\\r\\n\\r\\n 45% {\\r\\n transform: translate3d(-3%, 0, 0) rotate3d(0, 0, 1, -3deg);\\r\\n }\\r\\n\\r\\n 60% {\\r\\n transform: translate3d(2%, 0, 0) rotate3d(0, 0, 1, 2deg);\\r\\n }\\r\\n\\r\\n 75% {\\r\\n transform: translate3d(-1%, 0, 0) rotate3d(0, 0, 1, -1deg);\\r\\n }\\r\\n\\r\\n to {\\r\\n transform: translate3d(0, 0, 0);\\r\\n }\\r\\n}\\r\\n\", \"\"]);\n\n// exports\n"],"sourceRoot":""} \ No newline at end of file diff --git a/src/components/block.js b/src/components/block.js index 483ebfec..afd72be0 100644 --- a/src/components/block.js +++ b/src/components/block.js @@ -34,6 +34,7 @@ export default class Block { this.settings = settings; this.api = apiMethods; this.holder = this.compose(); + this.inputIndex = 0; /** * @type {IBlockTune[]} @@ -106,6 +107,26 @@ export default class Block { return this.save(); } + get inputs() { + const collection = this.holder.querySelectorAll('[contenteditable], input, textarea'); + + return _.array(collection); + } + + get nextInput() { + const inputs = this.inputs; + + this.inputIndex = Math.min(inputs.length - 1, this.inputIndex + 1); + + return inputs[this.inputIndex]; + } + + get previousInput() { + this.inputIndex = Math.max(0, this.inputIndex - 1); + + return this.inputs[this.inputIndex]; + } + /** * is block mergeable * We plugin have merge function then we call it mergable