From 3d03461dc0a8e8d4c957046d7fb16fd0fa1880f6 Mon Sep 17 00:00:00 2001 From: Taly Date: Mon, 16 Jul 2018 18:51:41 +0300 Subject: [PATCH] Header plugin (#281) * header initial * fix styles * eslint fix * add appendCallback * add comments * update styles * add svgs * highlight settings buttons * do not show text plugin in the toolbar * remove svg * Fixing caret behaviour. (#282) Plugins can change their state so that affect on Block's pluginsContent property which is in memory. * remove useless code * fix merge --- build/codex-editor.js | 3777 +----------------------- build/codex-editor.js.map | 2 +- example/example.html | 257 +- example/plugins/header/header.css | 49 +- example/plugins/header/header.js | 430 ++- example/plugins/header/icon.svg | 1 + example/plugins/text/text.js | 16 +- src/components/modules/blockManager.js | 6 +- src/components/modules/caret.js | 6 +- src/styles/settings.css | 4 + src/styles/toolbox.css | 24 +- 11 files changed, 397 insertions(+), 4175 deletions(-) create mode 100644 example/plugins/header/icon.svg diff --git a/build/codex-editor.js b/build/codex-editor.js index c3350f77..4e837c65 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\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" +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" /***/ }), @@ -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 recursive ^\\.\\/.*$")("./" + 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); }); /** @@ -2420,83 +2420,35 @@ module.exports = exports['default']; /***/ }), -/***/ "./src/components/modules sync recursive ^\\.\\/.*$": -/*!**********************************************!*\ - !*** ./src/components/modules sync ^\.\/.*$ ***! - \**********************************************/ +/***/ "./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)$ ***! + \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/ /*! 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" }; @@ -2519,2765 +2471,7 @@ webpackContext.keys = function webpackContextKeys() { }; webpackContext.resolve = webpackContextResolve; module.exports = webpackContext; -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; -}({}); +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)$"; /***/ }), @@ -6406,13 +3600,13 @@ var BlockManager = function (_Module) { value: function bindEvents(block) { var _this3 = this; - this.Editor.Listeners.on(block.pluginsContent, 'keydown', function (event) { + this.Editor.Listeners.on(block.html, 'keydown', function (event) { return _this3.Editor.BlockEvents.keydown(event); }); - this.Editor.Listeners.on(block.pluginsContent, 'mouseup', function (event) { + this.Editor.Listeners.on(block.html, 'mouseup', function (event) { return _this3.Editor.BlockEvents.mouseUp(event); }); - this.Editor.Listeners.on(block.pluginsContent, 'keyup', function (event) { + this.Editor.Listeners.on(block.html, 'keyup', function (event) { return _this3.Editor.BlockEvents.keyup(event); }); } @@ -7083,7 +4277,7 @@ var Caret = function (_Module) { var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var atEnd = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - var element = block.pluginsContent; + var element = block.html; /** If Element is INPUT */ if ($.isNativeInput(element)) { @@ -7301,7 +4495,7 @@ var Caret = function (_Module) { var selection = _selection2.default.get(), anchorNode = selection.anchorNode, - firstNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent); + firstNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.html); /** * Workaround case when caret in the text like " |Hello!" @@ -7357,7 +4551,7 @@ var Caret = function (_Module) { var selection = _selection2.default.get(), anchorNode = selection.anchorNode, - lastNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent, true); + lastNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.html, true); /** * In case of @@ -9477,947 +6671,6 @@ 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].makeSettings) { - return; - } - - /** - * Draw settings block - */ - var settingsBlock = editor.tools[toolType].makeSettings(); - - 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].makeSettings) { - 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 ***! @@ -11032,7 +7285,7 @@ var UI = function (_Module) { /** * - /** Update current input index in memory when caret focused into existed input */ + /** Update current input index in memory when caret focused into existed input */ // if (event.target.contentEditable == 'true') { // // editor.caret.saveCurrentInputIndex(); @@ -11965,7 +8218,7 @@ exports = module.exports = __webpack_require__(/*! ../../node_modules/css-loader // module -exports.push([module.i, ":root {\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 Plus Button and Toolbox buttons height and width\r\n */\r\n --toolbar-buttons-size: 34px;\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\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::-moz-selection{\r\n background-color: rgba(61,166,239,0.63);\r\n}\r\n::selection{\r\n background-color: rgba(61,166,239,0.63);\r\n}\r\n.ce-tune-moveup{}\r\n.ce-settings-delete:hover {\r\n cursor: pointer;\r\n }\r\n.ce-settings-delete::before {\r\n content: 'delete'\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 position: absolute;\r\n left: calc(calc(34px + 10px) * -1);\r\n left: calc(calc(var(--toolbar-buttons-size) + 10px) * -1);\r\n display: inline-block;\r\n background-color: #eff2f5;\r\n background-color: var(--bg-light);\r\n width: 34px;\r\n width: var(--toolbar-buttons-size);\r\n height: 34px;\r\n height: var(--toolbar-buttons-size);\r\n line-height: 34px;\r\n text-align: center;\r\n border-radius: 50%;\r\n cursor: pointer;\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 display: inline-block;\r\n list-style: none;\r\n margin: 0;\r\n background: #eff2f5;\r\n background: var(--bg-light);\r\n width: 34px;\r\n width: var(--toolbar-buttons-size);\r\n height: 34px;\r\n height: var(--toolbar-buttons-size);\r\n border-radius: 30px;\r\n overflow: hidden;\r\n text-align: center;\r\n line-height: 34px;\r\n line-height: var(--toolbar-buttons-size)\r\n }\r\n.ce-toolbox__button::before {\r\n content: attr(title);\r\n font-size: 22px;\r\n font-weight: 500;\r\n letter-spacing: 1em;\r\n -webkit-font-feature-settings: \"smcp\", \"c2sc\";\r\n font-feature-settings: \"smcp\", \"c2sc\";\r\n font-variant-caps: all-small-caps;\r\n padding-left: 11.5px;\r\n margin-top: -1px;\r\n display: inline-block;\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;\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--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-settings-move-up:hover {\r\n cursor: pointer;\r\n }\r\n.ce-settings-move-up--disabled {\r\n cursor: not-allowed !important;\r\n opacity: .3;\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", ""]); +exports.push([module.i, ":root {\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 Plus Button and Toolbox buttons height and width\n */\n --toolbar-buttons-size: 34px;\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\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::-moz-selection{\n background-color: rgba(61,166,239,0.63);\n}\n::selection{\n background-color: rgba(61,166,239,0.63);\n}\n.ce-tune-moveup{}\n.ce-settings-delete:hover {\n cursor: pointer;\n }\n.ce-settings-delete::before {\n content: 'delete'\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 position: absolute;\n left: calc(calc(34px + 10px) * -1);\n left: calc(calc(var(--toolbar-buttons-size) + 10px) * -1);\n display: inline-block;\n background-color: #eff2f5;\n background-color: var(--bg-light);\n width: 34px;\n width: var(--toolbar-buttons-size);\n height: 34px;\n height: var(--toolbar-buttons-size);\n line-height: 34px;\n text-align: center;\n border-radius: 50%;\n cursor: pointer;\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 display: inline-block;\n list-style: none;\n margin: 0;\n background-color: #eff2f5;\n background-color: var(--bg-light);\n width: 34px;\n width: var(--toolbar-buttons-size);\n height: 34px;\n height: var(--toolbar-buttons-size);\n border-radius: 30px;\n overflow: hidden;\n text-align: center;\n line-height: 34px;\n line-height: var(--toolbar-buttons-size);\n\n /*&::before {*/\n /*content: attr(title);*/\n /*font-size: 22px;*/\n /*font-weight: 500;*/\n /*letter-spacing: 1em;*/\n /*font-variant-caps: all-small-caps;*/\n /*padding-left: 11.5px;*/\n /*margin-top: -1px;*/\n /*display: inline-block;*/\n /*}*/\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;\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--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-settings-move-up:hover {\n cursor: pointer;\n }\n.ce-settings-move-up--disabled {\n cursor: not-allowed !important;\n opacity: .3;\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", ""]); // exports diff --git a/build/codex-editor.js.map b/build/codex-editor.js.map index aef6f48a..c7acafbe 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-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","Editor","new","target","TypeError","DeleteTune","api","CSS","wrapper","button","buttonDelete","buttonConfirm","nodes","resetConfirmation","setConfirmation","$","make","appendChild","svg","listener","on","event","handleClick","needConfirmation","events","off","blocks","delete","classList","add","MoveUpTune","btnDisabled","moveUpButton","getCurrentBlockIndex","currentBlockIndex","currentBlockElement","getBlockByIndex","html","previousBlockElement","currentBlockCoords","getBoundingClientRect","previousBlockCoords","scrollUpOffset","top","Math","abs","window","innerHeight","scrollBy","swap","Block","toolName","toolInstance","settings","apiMethods","tool","_html","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","contentless","emptyText","emptyMedia","hasMedia","mediaTags","querySelector","join","selected","remove","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","childNodes","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","inputIndex","enterPressedOnBlock_","NEW_BLOCK_TYPE","initialBlockPlugin","insertBlock","block","move","contentEditable","saveCurrentInputIndex","currentInputIndex","getCurrentInputIndex","workingNode","isEnterPressedOnToolbar","current","inputs","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","setTimeout","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","holder","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","keyCodes","backspace","enter","arrowRightAndDownPressed","arrowLeftAndUpPressed","InlineToolbar","handleShowingEvent","apiSettings","IS_ENABLED_LINE_BREAKS","newCurrent","isInitial","plusButton","show","BM","isFirstBlock","canMergeBlocks","isAtStart","targetBlock","blockToMerge","mergeable","setCaretToTheEnd","navigateNext","_blocks","Blocks","Proxy","get","construct","bindEvents","keydown","mouseUp","keyup","composeBlock","blockToMergeIndex","blockToMergeInfo","mergeWith","extractedFragment","extractFragmentFromCaretPosition","blockInserted","closest","childNode","parentFirstLevelBlock","Error","needAddInitialBlock","isLastBlock","array","workingArea","first","second","secondBlock","deleteCount","previousBlock","nextBlock","isNaN","children","instance","Number","atEnd","delay","lastBlock","selectRange","blockElem","cloneRange","selectNodeContents","endContainer","extractContents","from","direction","siblings","force","isAtEnd","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","makeSettings","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","offsetHeight","scrollY","closeButtons","closeAction","createLinkAction","defaultToolAction","hightlight","getOffset","_x","_y","offsetLeft","clientLeft","clientTop","offsetParent","sel","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","documentClicked","clickedOnInlineToolbarButton","clickedNode","setCurrentBlockByChildNode","setToTheLastBlock","isInitialBlock","isEmptyBlock","spriteHolder","sprite","Element","prototype","matches","msMatchesSelector","webkitMatchesSelector","s","documentElement","parentElement","savedSelectionRange","searchDepth","parentTag","focusNode","boundNodes","searchDepthIterable","boundingWidth","boundingHeight","span","spanParent","normalize","Util","msg","chains","previousValue","currentValue","iteration","waitNextBlock","successCallback","fallbackCallback","collection","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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AKjC,MAAL,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;;;;;;;kBAjHkBD,W;AA4MpB;;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;;;;;;;;;;;;;;;;;;;;;;;;;ACjZA;;;;;;;;;IASqBmB,M;AACjB;;;;;AAKA,wBAAwB;AAAA,QAAVlB,MAAU,QAAVA,MAAU;;AAAA;;AACpB;;;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IAAP;AACD;AACF;AAxGH;AAAA;;;AA0GE;;;;;;;;AA1GF,gCAkHclE,IAlHd,EAkHoB;AAChB,UAAIoU,WAAW,KAAKC,aAAL,CAAmBrU,IAAnB,CAAf;;AAEA,UAAI,KAAK2J,WAAT,EAAsB;AACpB,aAAKA,WAAL,CAAiB2K,qBAAjB,CAAuC,UAAvC,EAAmDF,QAAnD;AACD,OAFD,MAEO;AACL;;;AAGA,aAAK1X,MAAL,CAAYyN,EAAZ,CAAe9M,KAAf,CAAqBsU,QAArB,CAA8BjU,WAA9B,CAA0C0W,QAA1C;AACD;;AAED;;;AAGA,WAAKzK,WAAL,GAAmByK,QAAnB;;AAEA,aAAOA,SAAStK,OAAT,CAAiBqK,MAAxB;AACD;AApIH;AAAA;AAAA,sBAiCYzX,MAjCZ,EAiCoB;AAChB,WAAKA,MAAL,GAAcA,MAAd;AACD;;AAED;;;;;;AArCF;AAAA;AAAA,wBA0CoB;AAChB,aAAO,KAAKoX,YAAZ;AACD;;AAED;;;;;AA9CF;AAAA,sBAmDkB5P,IAnDlB,EAmDwB;AACpB,UAAIiL,kBAAkB,KAAKE,kBAAL,CAAwBnL,IAAxB,CAAtB;;AAEA,WAAK4P,YAAL,GAAoB3E,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;;;;;;;AAOA5V,OAAOgQ,OAAP,GAAiB,UAAUgL,SAAV,EAAqB;AACpC,MAAI9K,SAASC,MAAMD,MAAnB;;AAEA8K,YAAUC,WAAV,GAAwB,YAAY;AAClC/K,WAAOpM,KAAP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T3J,gBAAMioB,WAAW9jB,IADR;AAETtE,gBAAMooB,WAAWpoB;AAFR,SAAX;AAID,OARD;;AAUAtB,cAAQC,GAAR,CAAY,OAAZ,EAAqBupB,SAArB;AACAxpB,cAAQ2pB,QAAR;;AAEA,aAAO;AACL3iB,cAAU,CAAC,IAAI4iB,IAAJ,EADN;AAELroB,eAAUA,KAFL;AAGLsoB,iBAAU,OAAAC;AAHL,OAAP;AAKD;;;;EA5DgCvpB,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;;;;kBA5NqBmhB,K;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtBrB;;;;;;;;;;;IAWqBqI,a;;;AACnB;;;AAGA,+BAAsB;AAAA,QAAT1qB,MAAS,QAATA,MAAS;;AAAA;;AAAA,8HACd,EAACA,cAAD,EADc;;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oBoC,UAApB,CAA+BC,IAA/B;AACD;AACF;;AAED;;;;;;sCAGkB;AAChB,UAAI6R,eAAepxB,EAAEC,IAAF,CAAO,KAAP,CAAnB;;AAEAmxB,mBAAarrB,SAAb,GAAyBsrB,gBAAzB;;AAEArxB,QAAEoE,MAAF,CAAS,KAAKvE,KAAL,CAAWJ,OAApB,EAA6B2xB,YAA7B;AACD;;;wBA/NS;AACR,aAAO;AACLX,uBAAgB,cADX;AAELC,oBAAgB;AAFX,OAAP;AAID;;;;EAtE6BvzB,M;;AAmShC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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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","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 delete this.moduleInstances; // todo Is it necessary?\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 {Object} Editor - List of Editor modules\r\n */\r\nexport default class Module {\r\n /**\r\n * @constructor\r\n *\r\n * @param {EditorConfig} config\r\n */\r\n constructor({ config }) {\r\n /**\r\n * Editor modules list\r\n * @type {EditorComponents}\r\n */\r\n this.Editor = null;\r\n /**\r\n * Editor configuration object\r\n * @type {EditorConfig}\r\n */\r\n this.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 *\r\n * @param Editor\r\n * @param Editor.modules {@link CodexEditor#moduleInstances}\r\n * @param Editor.config {@link CodexEditor#configuration}\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 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-settings-move-up',\r\n btnDisabled: 'ce-settings-move-up--disabled',\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 if (this.api.blocks.getCurrentBlockIndex() === 0) {\r\n moveUpButton.classList.add(this.CSS.btnDisabled);\r\n }\r\n else {\r\n this.api.listener.on(moveUpButton, 'click', (event) => this.handleClick(event), false);\r\n }\r\n return moveUpButton;\r\n }\r\n /**\r\n * Move current block up\r\n * @param {MouseEvent} event\r\n */\r\n handleClick(event) {\r\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\r\n if (currentBlockIndex === 0) {\r\n return;\r\n }\r\n const currentBlockElement = this.api.blocks.getBlockByIndex(currentBlockIndex).html, previousBlockElement = this.api.blocks.getBlockByIndex(currentBlockIndex - 1).html;\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","/**\r\n * @class Block\r\n * @classdesc This class describes editor`s block, including block`s HTMLElement, data and tool\r\n *\r\n * @property {Tool} tool — current block tool (Paragraph, for example)\r\n * @property {Object} CSS — block`s css classes\r\n *\r\n */\r\n\r\n/** Import default tunes */\r\nimport MoveUpTune from './block-tunes/block-tune-move-up';\r\nimport DeleteTune from './block-tunes/block-tune-delete';\r\n\r\n/**\r\n * @classdesc Abstract Block class that contains Block information, Tool name and Tool class instance\r\n *\r\n * @property tool - Tool instance\r\n * @property html - Returns HTML content of plugin\r\n * @property wrapper - Div element that wraps block content with Tool's content. Has `ce-block` CSS class\r\n * @property contentNode - Div element that wraps Tool's content. Has `ce-block__content` CSS class\r\n * @property pluginsContent - HTML content that returns by Tool's render function\r\n */\r\nexport default class Block {\r\n /**\r\n * @constructor\r\n * @param {String} toolName - Tool name that passed on initialization\r\n * @param {Object} toolInstance — passed Tool`s instance that rendered the Block\r\n * @param {Object} settings - default settings\r\n * @param {Object} apiMethods - Editor API\r\n */\r\n constructor(toolName, toolInstance, settings, apiMethods) {\r\n this.name = toolName;\r\n this.tool = toolInstance;\r\n this.settings = settings;\r\n this.api = apiMethods;\r\n this._html = this.compose();\r\n\r\n /**\r\n * @type {IBlockTune[]}\r\n */\r\n this.tunes = this.makeTunes();\r\n }\r\n\r\n /**\r\n * CSS classes for the Block\r\n * @return {{wrapper: string, content: string}}\r\n */\r\n static get CSS() {\r\n return {\r\n wrapper: 'ce-block',\r\n content: 'ce-block__content',\r\n selected: 'ce-block--selected'\r\n };\r\n }\r\n\r\n /**\r\n * Make default Block wrappers and put Tool`s content there\r\n * @returns {HTMLDivElement}\r\n */\r\n compose() {\r\n this.wrapper = $.make('div', Block.CSS.wrapper);\r\n this.contentNode = $.make('div', Block.CSS.content);\r\n this.pluginsContent = this.tool.render();\r\n\r\n this.contentNode.appendChild(this.pluginsContent);\r\n this.wrapper.appendChild(this.contentNode);\r\n\r\n return this.wrapper;\r\n }\r\n\r\n /**\r\n * Calls Tool's method\r\n *\r\n * Method checks tool property {MethodName}. Fires method with passes params If it is instance of Function\r\n *\r\n * @param {String} methodName\r\n * @param {Object} params\r\n */\r\n call(methodName, params) {\r\n /**\r\n * call Tool's method with the instance context\r\n */\r\n if (this.tool[methodName] && this.tool[methodName] instanceof Function) {\r\n this.tool[methodName].call(this.tool, params);\r\n }\r\n }\r\n\r\n /**\r\n * Get Block`s HTML\r\n * @returns {HTMLElement}\r\n */\r\n get html() {\r\n return this._html;\r\n }\r\n\r\n /**\r\n * Get Block's JSON data\r\n * @return {Object}\r\n */\r\n get data() {\r\n return this.save();\r\n }\r\n\r\n /**\r\n * is block mergeable\r\n * We plugin have merge function then we call it mergable\r\n * @return {boolean}\r\n */\r\n get mergeable() {\r\n return typeof this.tool.merge === 'function';\r\n }\r\n\r\n /**\r\n * Call plugins merge method\r\n * @param {Object} data\r\n */\r\n mergeWith(data) {\r\n return Promise.resolve()\r\n .then(() => {\r\n this.tool.merge(data);\r\n });\r\n }\r\n /**\r\n * Extracts data from Block\r\n * Groups Tool's save processing time\r\n * @return {Object}\r\n */\r\n save() {\r\n let extractedBlock = this.tool.save(this.pluginsContent);\r\n\r\n /** Measuring execution time*/\r\n let measuringStart = window.performance.now(),\r\n measuringEnd;\r\n\r\n return Promise.resolve(extractedBlock)\r\n .then((finishedExtraction) => {\r\n /** measure promise execution */\r\n measuringEnd = window.performance.now();\r\n\r\n return {\r\n tool: this.name,\r\n data: finishedExtraction,\r\n time : measuringEnd - measuringStart\r\n };\r\n })\r\n .catch(function (error) {\r\n _.log(`Saving proccess for ${this.tool.name} tool failed due to the ${error}`, 'log', 'red');\r\n });\r\n }\r\n\r\n /**\r\n * Uses Tool's validation method to check the correctness of output data\r\n * Tool's validation method is optional\r\n *\r\n * @description Method also can return data if it passed the validation\r\n *\r\n * @param {Object} data\r\n * @returns {Boolean|Object} valid\r\n */\r\n validateData(data) {\r\n let isValid = true;\r\n\r\n if (this.tool.validate instanceof Function) {\r\n isValid = this.tool.validate(data);\r\n }\r\n\r\n if (!isValid) {\r\n return false;\r\n }\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Make an array with default settings\r\n * Each block has default tune instance that have states\r\n * @return {IBlockTune[]}\r\n */\r\n makeTunes() {\r\n let tunesList = [MoveUpTune, DeleteTune];\r\n\r\n // Pluck tunes list and return tune instances with passed Editor API and settings\r\n return tunesList.map( (tune) => {\r\n return new tune({\r\n api: this.api,\r\n settings: this.settings,\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Enumerates initialized tunes and returns fragment that can be appended to the toolbars area\r\n * @return {DocumentFragment}\r\n */\r\n renderTunes() {\r\n let tunesElement = document.createDocumentFragment();\r\n\r\n this.tunes.forEach( tune => {\r\n $.append(tunesElement, tune.render());\r\n });\r\n\r\n return tunesElement;\r\n }\r\n\r\n /**\r\n * Check block for emptiness\r\n * @return {Boolean}\r\n */\r\n get isEmpty() {\r\n /**\r\n * Allow Tool to represent decorative contentless blocks: for example \"* * *\"-tool\r\n * That Tools are not empty\r\n */\r\n if (this.tool.contentless) {\r\n return false;\r\n }\r\n\r\n let emptyText = $.isEmpty(this.pluginsContent),\r\n emptyMedia = !this.hasMedia;\r\n\r\n return emptyText && emptyMedia;\r\n }\r\n\r\n /**\r\n * Check if block has a media content such as images, iframes and other\r\n * @return {Boolean}\r\n */\r\n get hasMedia() {\r\n /**\r\n * This tags represents media-content\r\n * @type {string[]}\r\n */\r\n const mediaTags = [\r\n 'img',\r\n 'iframe',\r\n 'video',\r\n 'audio',\r\n 'source',\r\n 'input',\r\n 'textarea',\r\n 'twitterwidget'\r\n ];\r\n\r\n return !!this._html.querySelector(mediaTags.join(','));\r\n }\r\n\r\n /**\r\n * Set selected state\r\n * @param {Boolean} state - 'true' to select, 'false' to remove selection\r\n */\r\n set selected(state) {\r\n /**\r\n * We don't need to mark Block as Selected when it is not empty\r\n */\r\n if (state === true && !this.isEmpty) {\r\n this._html.classList.add(Block.CSS.selected);\r\n } else {\r\n this._html.classList.remove(Block.CSS.selected);\r\n }\r\n }\r\n}\r\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} 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) {\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) {\n anchors.currentNode = currentBlock;\r\n anchors.input.value = anchors.currentNode.dataset.anchor || '';\n };\r\n\r\n anchors.anchorChanged = function (e) {\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() !== '') {\n anchors.currentNode.classList.add(editor.ui.className.BLOCK_WITH_ANCHOR);\n } else {\n anchors.currentNode.classList.remove(editor.ui.className.BLOCK_WITH_ANCHOR);\n }\n };\r\n\r\n anchors.keyDownOnAnchorInput = function (e) {\n if (e.keyCode == editor.core.keys.ENTER) {\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n e.target.blur();\r\n editor.toolbar.settings.close();\n }\n };\r\n\r\n anchors.keyUpOnAnchorInput = function (e) {\n if (e.keyCode >= editor.core.keys.LEFT && e.keyCode <= editor.core.keys.DOWN) {\n e.stopPropagation();\n }\n };\r\n\r\n anchors.rusToTranslit = function (string) {\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++) {\n string = string.split(ru[i]).join(en[i]);\r\n string = string.split(ru[i].toLowerCase()).join(en[i].toLowerCase());\n }\r\n\r\n string = string.replace(/[^0-9a-zA-Z_]+/g, '-');\r\n\r\n return string;\n };\r\n\r\n return anchors;\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) {\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) {\n switch (event.keyCode) {\n case editor.core.keys.ENTER : enterKeyPressed_(event); break;\n }\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) {\n switch (event.keyCode) {\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;\n }\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) {\n switch (event.keyCode) {\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;\n }\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) {\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)) {\n return;\n }\r\n\r\n if ( !editor.toolbar.opened ) {\n editor.toolbar.open();\n }\r\n\r\n if (editor.toolbar.opened && !editor.toolbar.toolbox.opened) {\n editor.toolbar.toolbox.open();\n } else {\n editor.toolbar.toolbox.leaf();\n }\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 () {\n if (editor.content.editorAreaHightlighted) {\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_();\n }\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 () {\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();\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) {\n if (event.target.contentEditable == 'true') {\n /** Update input index */\r\n editor.caret.saveCurrentInputIndex();\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 ) {\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;\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 ) {\n event.stopPropagation();\r\n event.stopImmediatePropagation();\r\n return;\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 ) {\n editor.callback.enterPressedOnBlock(editor.content.currentBlock, event);\r\n event.preventDefault();\r\n return;\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 ) {\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()) {\n editor.toolbar.showPlusButton();\n }\n } else {\n var islastNode = editor.content.isLastNode(currentSelectedNode);\r\n\r\n if ( islastNode && caretAtTheEndOfText ) {\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();\n }\n }\r\n\r\n /** get all inputs after new appending block */\r\n editor.ui.saveInputs();\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) {\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();\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) {\n editor.content.workingNodeChanged();\r\n\r\n /* Closing toolbar */\r\n editor.toolbar.close();\r\n editor.toolbar.move();\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 () {\n editor.toolbar.close();\r\n\r\n if (!editor.toolbar.inline.actionsOpened) {\n editor.toolbar.inline.close();\r\n editor.content.clearMark();\n }\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) {\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) {\n editor.toolbar.inline.close();\n }\r\n\r\n /** Update current input index in memory when caret focused into existed input */\r\n if (event.target.contentEditable == 'true') {\n editor.caret.saveCurrentInputIndex();\n }\r\n\r\n if (editor.content.currentNode === null) {\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) {\n /** getting firstlevel parent of input */\r\n firstLevelBlock = editor.content.getFirstLevelBlock(editor.state.inputs[indexOfLastInput]);\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) {\n editor.caret.setToBlock(indexOfLastInput);\n } else {\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) {\n editor.caret.setToBlock(indexOfLastInput);\n } else {\n /** Set caret to this appended input */\r\n editor.caret.setToNextBlock(indexOfLastInput);\n }\n }\n } else {\n /** Close all panels */\r\n editor.toolbar.settings.close();\r\n editor.toolbar.toolbox.close();\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) {\n /** Mark current block */\r\n editor.content.markBlock();\n }\r\n\r\n if ( isInitialType && inputIsEmpty ) {\n /** Show plus button */\r\n editor.toolbar.showPlusButton();\n }\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 () {\n var selection = window.getSelection(),\r\n anchorNode = selection.anchorNode,\r\n flag = false;\r\n\r\n if (selection.rangeCount === 0) {\n editor.content.editorAreaHightlighted = true;\n } else {\n if (!editor.core.isDomNode(anchorNode)) {\n anchorNode = anchorNode.parentNode;\n }\r\n\r\n /** Already founded, without loop */\r\n if (anchorNode.contentEditable == 'true') {\n flag = true;\n }\r\n\r\n while (anchorNode.contentEditable != 'true') {\n anchorNode = anchorNode.parentNode;\r\n\r\n if (anchorNode.contentEditable == 'true') {\n flag = true;\n }\r\n\r\n if (anchorNode == document.body) {\n break;\n }\n }\r\n\r\n /** If editable element founded, flag is \"TRUE\", Therefore we return \"FALSE\" */\r\n editor.content.editorAreaHightlighted = !flag;\n }\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) {\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();\n };\r\n\r\n /**\r\n * Show or Hide toolbox when plus button is clicked\r\n */\r\n callbacks.plusButtonClicked = function () {\n if (!editor.nodes.toolbox.classList.contains('opened')) {\n editor.toolbar.toolbox.open();\n } else {\n editor.toolbar.toolbox.close();\n }\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) {\n let block = event.target; // event.target is input\r\n\r\n switch (event.keyCode) {\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;\n }\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) {\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) {\n return false;\n }\r\n\r\n /** Looking for closest (parent) contentEditable element of focused node */\r\n while (focusedNode.contentEditable != 'true') {\n focusedNodeHolder = focusedNode.parentNode;\r\n focusedNode = focusedNodeHolder;\n }\r\n\r\n /** Input index in DOM level */\r\n var editableElementIndex = 0;\r\n\r\n while (focusedNode != inputs[editableElementIndex]) {\n editableElementIndex ++;\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) {\n editor.caret.setToNextBlock(editableElementIndex);\r\n return;\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)) {\n deepestTextnode = editor.content.getDeepestTextNodeFromPosition(lastChild, lastChild.childNodes.length);\n } else {\n deepestTextnode = lastChild;\n }\r\n\r\n caretInLastChild = selection.anchorNode == deepestTextnode;\r\n caretAtTheEndOfText = deepestTextnode.length == selection.anchorOffset;\r\n\r\n if ( !caretInLastChild || !caretAtTheEndOfText ) {\n editor.core.log('arrow [down|right] : caret does not reached the end');\r\n return false;\n }\r\n\r\n editor.caret.setToNextBlock(editableElementIndex);\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) {\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) {\n return false;\n }\r\n\r\n /**\r\n * LEFT or UP not at the beginning\r\n */\r\n if ( selection.anchorOffset !== 0) {\n return false;\n }\r\n\r\n /** Looking for parent contentEditable block */\r\n while (focusedNode.contentEditable != 'true') {\n focusedNodeHolder = focusedNode.parentNode;\r\n focusedNode = focusedNodeHolder;\n }\r\n\r\n /** Input index in DOM level */\r\n var editableElementIndex = 0;\r\n\r\n while (focusedNode != inputs[editableElementIndex]) {\n editableElementIndex ++;\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) {\n editor.caret.setToPreviousBlock(editableElementIndex);\r\n return;\n }\r\n\r\n firstChild = focusedNode.childNodes[0];\r\n\r\n if (editor.core.isDomNode(firstChild)) {\n deepestTextnode = editor.content.getDeepestTextNodeFromPosition(firstChild, 0);\n } else {\n deepestTextnode = firstChild;\n }\r\n\r\n caretInFirstChild = selection.anchorNode == deepestTextnode;\r\n caretAtTheBeginning = selection.anchorOffset === 0;\r\n\r\n if ( caretInFirstChild && caretAtTheBeginning ) {\n editor.caret.setToPreviousBlock(editableElementIndex);\n }\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) {\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)) {\n /** If input value is empty - remove block */\r\n if (event.target.value.trim() == '') {\n block.remove();\n } else {\n return;\n }\n }\r\n\r\n if (block.textContent.trim()) {\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]) {\n editor.content.mergeBlocks(currentInputIndex);\n } else {\n return;\n }\n }\r\n\r\n if (!selectionLength) {\n block.remove();\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) {\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 () {\n editor.caret.setToPreviousBlock(1);\n }, 10);\n } else {\n if (editor.caret.inputIndex !== 0) {\n /** Target block is not first */\r\n editor.caret.setToPreviousBlock(editor.caret.inputIndex);\n } else {\n /** If we try to delete first block */\r\n editor.caret.setToNextBlock(editor.caret.inputIndex);\n }\n }\r\n\r\n editor.toolbar.move();\r\n\r\n if (!editor.toolbar.opened) {\n editor.toolbar.open();\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();\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) {\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();\n };\r\n\r\n return callbacks;\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) {\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) {\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 ) {\n nodeToSet = el;\n } else {\n nodeToSet = childs[index];\n }\r\n\r\n /** If Element is INPUT */\r\n if (el.contentEditable != 'true') {\n el.focus();\r\n return;\n }\r\n\r\n if (editor.core.isDomNode(nodeToSet)) {\n nodeToSet = editor.content.getDeepestTextNodeFromPosition(nodeToSet, nodeToSet.childNodes.length);\n }\r\n\r\n var range = document.createRange(),\r\n selection = window.getSelection();\r\n\r\n window.setTimeout(function () {\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();\n }, 20);\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 () {\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) {\n return;\n }\r\n\r\n /** Looking for parent contentEditable block */\r\n while (focusedNode.contentEditable != 'true') {\n focusedNodeHolder = focusedNode.parentNode;\r\n focusedNode = focusedNodeHolder;\n }\r\n\r\n /** Input index in DOM level */\r\n var editableElementIndex = 0;\r\n\r\n while (focusedNode != inputs[editableElementIndex]) {\n editableElementIndex ++;\n }\r\n\r\n caret.inputIndex = editableElementIndex;\n };\r\n\r\n /**\r\n * Returns current input index (caret object)\r\n */\r\n caret.getCurrentInputIndex = function () {\n return caret.inputIndex;\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) {\n var inputs = editor.state.inputs,\r\n nextInput = inputs[index + 1];\r\n\r\n if (!nextInput) {\n editor.core.log('We are reached the end');\r\n return;\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) {\n var emptyTextElement = document.createTextNode('');\r\n\r\n nextInput.appendChild(emptyTextElement);\n }\r\n\r\n editor.caret.inputIndex = index + 1;\r\n editor.caret.set(nextInput, 0, 0);\r\n editor.content.workingNodeChanged(nextInput);\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) {\n var inputs = editor.state.inputs,\r\n targetInput = inputs[index];\r\n\r\n if ( !targetInput ) {\n return;\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) {\n var emptyTextElement = document.createTextNode('');\r\n\r\n targetInput.appendChild(emptyTextElement);\n }\r\n\r\n editor.caret.inputIndex = index;\r\n editor.caret.set(targetInput, 0, 0);\r\n editor.content.workingNodeChanged(targetInput);\n };\r\n\r\n /**\r\n * @param {int} index - index of input\r\n */\r\n caret.setToPreviousBlock = function (index) {\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) {\n editor.core.log('We are reached first node');\r\n return;\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) {\n emptyTextElement = document.createTextNode('');\r\n previousInput.appendChild(emptyTextElement);\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]);\n };\r\n\r\n caret.position = {\r\n\r\n atStart : function () {\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)) {\n anchorNode = anchorNode.parentNode;\n }\r\n\r\n var isFirstNode = anchorNode === pluginsRender.childNodes[0],\r\n isOffsetZero = anchorOffset === 0;\r\n\r\n return isFirstNode && isOffsetZero;\n },\r\n\r\n atTheEnd : function () {\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;\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) {\n var selection, range,\r\n lastNode = node;\r\n\r\n if (node.nodeType == editor.core.nodeTypes.DOCUMENT_FRAGMENT) {\n lastNode = node.lastChild;\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);\n };\r\n\r\n return caret;\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 {\n /**\r\n * Module key name\r\n * @returns {string}\r\n */\r\n static get name() {\n return 'Content';\n }\r\n\r\n /**\r\n * @constructor\r\n *\r\n * @param {EditorConfig} config\r\n */\r\n constructor(config) {\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;\n }\r\n\r\n /**\r\n * Editor modules setter\r\n * @param {object} Editor\r\n */\r\n set state(Editor) {\n this.Editor = Editor;\n }\r\n\r\n /**\r\n * Get current working node\r\n *\r\n * @returns {null|HTMLElement}\r\n */\r\n get currentNode() {\n return this._currentNode;\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) {\n let firstLevelBlock = this.getFirstLevelBlock(node);\r\n\r\n this._currentNode = firstLevelBlock;\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) {\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) {\n blockContent.classList.add(this.CSS.stretched);\n }\r\n\r\n block.dataset.toolId = this._currentIndex++;\r\n\r\n return block;\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) {\n if (!$.isElement(node)) {\n node = node.parentNode;\n }\r\n\r\n if (node === this.Editor.ui.nodes.redactor || node === document.body) {\n return null;\n } else {\n while(node.classList && !node.classList.contains(this.CSS.block)) {\n node = node.parentNode;\n }\r\n\r\n return node;\n }\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) {\n let newBlock = this.composeBlock_(tool);\r\n\r\n if (this.currentNode) {\n this.currentNode.insertAdjacentElement('afterend', newBlock);\n } else {\n /**\r\n * If redactor is empty, append as first child\r\n */\r\n this.Editor.ui.nodes.redactor.appendChild(newBlock);\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;\n }\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) {\n let editor = codex.editor;\r\n\r\n destroyer.removeNodes = function () {\n editor.nodes.wrapper.remove();\r\n editor.nodes.notifications.remove();\n };\r\n\r\n destroyer.destroyPlugins = function () {\n for (var tool in editor.tools) {\n if (typeof editor.tools[tool].destroy === 'function') {\n editor.tools[tool].destroy();\n }\n }\n };\r\n\r\n destroyer.destroyScripts = function () {\n var scripts = document.getElementsByTagName('SCRIPT');\r\n\r\n for (var i = 0; i < scripts.length; i++) {\n if (scripts[i].id.indexOf(editor.scriptPrefix) + 1) {\n scripts[i].remove();\r\n i--;\n }\n }\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) {\n if (!settings || typeof settings !== 'object') {\n return;\n }\r\n\r\n if (settings.ui) {\n destroyer.removeNodes();\r\n editor.listeners.removeAll();\n }\r\n\r\n if (settings.scripts) {\n destroyer.destroyScripts();\n }\r\n\r\n if (settings.plugins) {\n destroyer.destroyPlugins();\n }\r\n\r\n if (settings.ui && settings.scripts && settings.core) {\n delete codex.editor;\n }\n };\r\n\r\n return destroyer;\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) {\n let editor = codex.editor;\r\n\r\n var queue = [];\r\n\r\n var addToQueue = function (settings) {\n queue.push(settings);\r\n\r\n var index = 0;\r\n\r\n while ( index < queue.length && queue.length > 5) {\n if (queue[index].type == 'confirm' || queue[index].type == 'prompt') {\n index++;\r\n continue;\n }\r\n\r\n queue[index].close();\r\n queue.splice(index, 1);\n }\n };\r\n\r\n notifications.createHolder = function () {\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;\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) {\n editor.notifications.notification({message: 'This action is not available currently', type: event.type});\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) {\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 () {\n close();\r\n\r\n if (typeof confirm !== 'function' ) {\n return;\n }\r\n\r\n if (type == 'prompt') {\n confirm(inputField.value);\r\n return;\n }\r\n\r\n confirm();\n };\r\n\r\n var cancelHandler = function () {\n close();\r\n\r\n if (typeof cancel !== 'function' ) {\n return;\n }\r\n\r\n cancel();\n };\r\n\r\n\r\n /** Public methods */\r\n function create(settings) {\n if (!(settings && settings.message)) {\n editor.core.log('Can\\'t create notification. Message is missed');\r\n return;\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') {\n wrapper.appendChild(input);\n }\r\n\r\n wrapper.appendChild(okBtn);\r\n\r\n if (settings.type == 'prompt' || settings.type == 'confirm') {\n wrapper.appendChild(cancelBtn);\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') {\n window.setTimeout(close, settings.time);\n }\n };\r\n\r\n /**\r\n * Show notification block\r\n */\r\n function send() {\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 () {\n editor.nodes.notifications.classList.remove('cdx-notification__notification-appending');\n }, 100);\r\n\r\n addToQueue({type: type, close: close});\n };\r\n\r\n /**\r\n * Remove notification block\r\n */\r\n function close() {\n notification.remove();\n };\r\n\r\n\r\n if (constructorSettings) {\n create(constructorSettings);\r\n send();\n }\r\n\r\n return {\r\n create: create,\r\n send: send,\r\n close: close\r\n };\n };\r\n\r\n notifications.clear = function () {\n editor.nodes.notifications.innerHTML = '';\r\n queue = [];\n };\r\n\r\n return notifications;\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) {\n let editor = codex.editor;\r\n\r\n /** inserting text */\r\n parser.insertPastedContent = function (blockType, tag) {\n editor.content.insertBlock({\r\n type : blockType.type,\r\n block : blockType.render({\r\n text : tag.innerHTML\r\n })\r\n });\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) {\n return node.nodeType == editor.core.nodeTypes.TAG &&\r\n node.classList.contains(editor.ui.className.BLOCK_CLASSNAME);\n };\r\n\r\n return parser;\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) {\n let editor = codex.editor;\r\n\r\n var patterns = [];\r\n\r\n paste.prepare = function () {\n var tools = editor.tools;\r\n\r\n for (var tool in tools) {\n if (!tools[tool].renderOnPastePatterns || !Array.isArray(tools[tool].renderOnPastePatterns)) {\n continue;\n }\r\n\r\n tools[tool].renderOnPastePatterns.map(function (pattern) {\n patterns.push(pattern);\n });\n }\r\n\r\n return Promise.resolve();\n };\r\n\r\n /**\r\n * Saves data\r\n * @param event\r\n */\r\n paste.pasted = function (event) {\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) {\n event.preventDefault();\r\n event.stopImmediatePropagation();\n }\r\n\r\n return result;\n };\r\n\r\n /**\r\n * Analizes pated string and calls necessary method\r\n */\r\n\r\n var analize = function (string) {\n var result = false,\r\n content = editor.content.currentNode,\r\n plugin = content.dataset.tool;\r\n\r\n patterns.map( function (pattern) {\n var execArray = pattern.regex.exec(string),\r\n match = execArray && execArray[0];\r\n\r\n if ( match && match === string.trim()) {\n /** current block is not empty */\r\n if ( content.textContent.trim() && plugin == editor.settings.initialBlockPlugin ) {\n pasteToNewBlock_();\n }\r\n\r\n pattern.callback(string, pattern);\r\n result = true;\n }\n });\r\n\r\n return result;\n };\r\n\r\n var pasteToNewBlock_ = function () {\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);\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) {\n if (!needsToHandlePasteEvent(event.target)) {\n return;\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) {\n emulateUserAgentBehaviour(paragraphs.firstChild);\r\n return;\n }\r\n\r\n insertPastedParagraphs(paragraphs.childNodes);\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) {\n /** If area is input or textarea then allow default behaviour */\r\n if ( editor.core.isNativeInput(block) ) {\n return false;\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) {\n return false;\n }\r\n\r\n return true;\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) {\n var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin,\r\n currentNode = editor.content.currentNode;\r\n\r\n\r\n paragraphs.forEach(function (paragraph) {\n /** Don't allow empty paragraphs */\r\n if (editor.core.isBlockEmpty(paragraph)) {\n return;\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++;\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)) {\n currentNode.remove();\r\n editor.ui.saveInputs();\n }\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) {\n var newNode;\r\n\r\n if (node.childElementCount) {\n newNode = document.createDocumentFragment();\r\n\r\n node.childNodes.forEach(function (current) {\n if (!editor.core.isDomNode(current) && current.data.trim() === '') {\n return;\n }\r\n\r\n newNode.appendChild(current.cloneNode(true));\n });\n } else {\n newNode = document.createTextNode(node.textContent);\n }\r\n\r\n editor.caret.insertNode(newNode);\n };\r\n\r\n\r\n return paste;\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) {\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 () {\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;\n };\r\n\r\n /** Clear input when files is uploaded */\r\n transport.clearInput = function () {\n /** Remove old input */\r\n transport.input = null;\r\n\r\n /** Prepare new one */\r\n transport.prepare();\n };\r\n\r\n /**\r\n * Callback for file selection\r\n * @param {Event} event\r\n */\r\n transport.fileSelected = function () {\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) {\n for ( i = 0; i < files.length; i++) {\n formData.append('files[]', files[i], files[i].name);\n }\n } else {\n formData.append('files', files[0], files[0].name);\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();\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) {\n transport.arguments = args;\r\n\r\n if ( args.multiple === true) {\n transport.input.setAttribute('multiple', 'multiple');\n }\r\n\r\n if ( args.accept ) {\n transport.input.setAttribute('accept', args.accept);\n }\r\n\r\n transport.input.click();\n };\r\n\r\n transport.abort = function () {\n currentRequest.abort();\r\n\r\n currentRequest = null;\n };\r\n\r\n return transport;\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 * @param {EditorsConfig} config\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 };\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 if (this.Editor.Caret.navigatePrevious(true)) {\r\n this.Editor.Toolbar.close();\r\n }\r\n }\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 * @param {EditorsConfig} config\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 * @param {EditorsConfig} config\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 * @param {EditorsConfig} config\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 * @param {EditorsConfig} config\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 * @param {EditorsConfig} config\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 * @param {EditorsConfig} config\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 sanitizer: this.Editor.SanitizerAPI.methods,\r\n saver: this.Editor.SaverAPI.methods,\r\n selection: this.Editor.SelectionAPI.methods,\r\n listener: this.Editor.ListenerAPI.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 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.arrowRightAndDownPressed();\r\n break;\r\n case _.keyCodes.UP:\r\n case _.keyCodes.LEFT:\r\n this.arrowLeftAndUpPressed();\r\n break;\r\n default:\r\n break;\r\n }\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 this.Editor.Toolbar.open();\r\n if (this.Editor.Tools.isInitial(newCurrent.tool) && newCurrent.isEmpty) {\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 (!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 }\r\n const setCaretToTheEnd = !targetBlock.isEmpty;\r\n BM.mergeBlocks(targetBlock, blockToMerge)\r\n .then(() => {\r\n // @todo figure out without timeout\r\n window.setTimeout(() => {\r\n // set caret to the block without offset at the end\r\n this.Editor.Caret.setToBlock(BM.currentBlock, 0, setCaretToTheEnd);\r\n this.Editor.Toolbar.close();\r\n }, 10);\r\n });\r\n }\r\n /**\r\n * Handle right and down keyboard keys\r\n */\r\n arrowRightAndDownPressed() {\r\n this.Editor.Caret.navigateNext();\r\n this.Editor.Toolbar.close();\r\n }\r\n /**\r\n * Handle left and up keyboard keys\r\n */\r\n arrowLeftAndUpPressed() {\r\n this.Editor.Caret.navigatePrevious();\r\n this.Editor.Toolbar.close();\r\n }\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.pluginsContent, 'keydown', (event) => this.Editor.BlockEvents.keydown(event));\r\n this.Editor.Listeners.on(block.pluginsContent, 'mouseup', (event) => this.Editor.BlockEvents.mouseUp(event));\r\n this.Editor.Listeners.on(block.pluginsContent, '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 * 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 {HTMLElement} 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 * Remove previous selected Block's state\r\n */\r\n this.blocks.forEach( block => block.selected = false);\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 * 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 * 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.currentBlockIndex = -1;\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.html);\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].html, secondBlock.html);\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].html.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.html.insertAdjacentElement('afterend', block.html);\r\n } else {\r\n let nextBlock = this.blocks[index + 1];\r\n\r\n if (nextBlock) {\r\n nextBlock.html.insertAdjacentElement('beforebegin', block.html);\r\n } else {\r\n this.workingArea.appendChild(block.html);\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].html.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 * 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.wrapper;\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.insert(this.config.initialBlock);\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 * @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.makeSettings === 'function') {\r\n $.append(this.nodes.toolSettings, this.Editor.BlockManager.currentBlock.tool.makeSettings());\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) {\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 () {\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) {\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();\n }\n };\r\n\r\n /**\r\n * @protected\r\n *\r\n * Closes inline toolbar\r\n */\r\n inline.close = function () {\n var toolbar = editor.nodes.inlineToolbar.wrapper;\r\n\r\n toolbar.classList.remove('opened');\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Moving toolbar\r\n */\r\n inline.move = function () {\n if (!this.wrappersOffset) {\n this.wrappersOffset = this.getWrappersOffset();\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) {\n defaultOffset = 40;\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();\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) {\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) {\n case 'createLink' : editor.toolbar.inline.createLinkAction(event, type); break;\r\n default : editor.toolbar.inline.defaultToolAction(type); break;\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);\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Saving wrappers offset in DOM\r\n */\r\n inline.getWrappersOffset = function () {\n var wrapper = editor.nodes.wrapper,\r\n offset = this.getOffset(wrapper);\r\n\r\n this.wrappersOffset = offset;\r\n return offset;\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 ) {\n var _x = 0;\r\n var _y = 0;\r\n\r\n while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {\n _x += (el.offsetLeft + el.clientLeft);\r\n _y += (el.offsetTop + el.clientTop);\r\n el = el.offsetParent;\n }\r\n return { top: _y, left: _x };\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 () {\n var sel = document.selection, range;\r\n var x = 0, y = 0;\r\n\r\n if (sel) {\n if (sel.type != 'Control') {\n range = sel.createRange();\r\n range.collapse(true);\r\n x = range.boundingLeft;\r\n y = range.boundingTop;\n }\n } else if (window.getSelection) {\n sel = window.getSelection();\r\n\r\n if (sel.rangeCount) {\n range = sel.getRangeAt(0).cloneRange();\r\n if (range.getClientRects) {\n range.collapse(true);\r\n var rect = range.getClientRects()[0];\r\n\r\n if (!rect) {\n return;\n }\r\n\r\n x = rect.left;\r\n y = rect.top;\n }\n }\n }\r\n return { x: x, y: y };\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 () {\n var selectedText = '';\r\n\r\n // all modern browsers and IE9+\r\n if (window.getSelection) {\n selectedText = window.getSelection().toString();\n }\r\n\r\n return selectedText;\n };\r\n\r\n /** Opens buttons block */\r\n inline.showButtons = function () {\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);\n };\r\n\r\n /** Makes buttons disappear */\r\n inline.closeButtons = function () {\n var buttons = editor.nodes.inlineToolbar.buttons;\r\n\r\n buttons.classList.remove('opened');\r\n\r\n editor.toolbar.inline.buttonsOpened = false;\n };\r\n\r\n /** Open buttons defined action if exist */\r\n inline.showActions = function () {\n var action = editor.nodes.inlineToolbar.actions;\r\n\r\n action.classList.add('opened');\r\n\r\n editor.toolbar.inline.actionsOpened = true;\n };\r\n\r\n /** Close actions block */\r\n inline.closeAction = function () {\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;\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) {\n if (event.keyCode != editor.core.keys.ENTER) {\n return;\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();\n };\r\n\r\n /** Action for link creation or for setting anchor */\r\n inline.createLinkAction = function (event) {\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) {\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');\n } else {\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);\n }\n };\r\n\r\n inline.isLinkActive = function () {\n var isActive = false;\r\n\r\n editor.nodes.inlineToolbar.buttons.childNodes.forEach(function (tool) {\n var dataType = tool.dataset.type;\r\n\r\n if (dataType == 'link' && tool.classList.contains('hightlighted')) {\n isActive = true;\n }\n });\r\n\r\n return isActive;\n };\r\n\r\n /** default action behavior of tool */\r\n inline.defaultToolAction = function (type) {\n document.execCommand(type, false, null);\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) {\n document.execCommand('createLink', false, url);\r\n\r\n /** Close after URL inserting */\r\n editor.toolbar.inline.closeAction();\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Saves selection\r\n */\r\n inline.saveSelection = function (containerEl) {\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 };\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) {\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())) {\n if (node.nodeType == 3) {\n nextCharIndex = charIndex + node.length;\r\n\r\n if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {\n range.setStart(node, savedSel.start - charIndex);\r\n foundStart = true;\n }\r\n if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {\n range.setEnd(node, savedSel.end - charIndex);\r\n stop = true;\n }\r\n charIndex = nextCharIndex;\n } else {\n var i = node.childNodes.length;\r\n\r\n while (i--) {\n nodeStack.push(node.childNodes[i]);\n }\n }\n }\r\n\r\n var sel = window.getSelection();\r\n\r\n sel.removeAllRanges();\r\n sel.addRange(range);\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 () {\n var selection = window.getSelection();\r\n\r\n selection.removeAllRanges();\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * sets or removes hightlight\r\n */\r\n inline.hightlight = function (tool) {\n var dataType = tool.dataset.type;\r\n\r\n if (document.queryCommandState(dataType)) {\n editor.toolbar.inline.setButtonHighlighted(tool);\n } else {\n editor.toolbar.inline.removeButtonsHighLight(tool);\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') {\n editor.toolbar.inline.setButtonHighlighted(tool);\n }\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) {\n button.classList.add('hightlighted');\r\n\r\n /** At link tool we also change icon */\r\n if (button.dataset.type == 'link') {\n var icon = button.childNodes[0];\r\n\r\n icon.classList.remove('ce-icon-link');\r\n icon.classList.add('ce-icon-unlink');\n }\n };\r\n\r\n /**\r\n * @private\r\n *\r\n * Removes hightlight\r\n */\r\n inline.removeButtonsHighLight = function (button) {\n button.classList.remove('hightlighted');\r\n\r\n /** At link tool we also change icon */\r\n if (button.dataset.type == 'link') {\n var icon = button.childNodes[0];\r\n\r\n icon.classList.remove('ce-icon-unlink');\r\n icon.classList.add('ce-icon-link');\n }\n };\r\n\r\n\r\n return inline;\n})({});","/**\r\n * Toolbar settings\r\n *\r\n * @version 1.0.5\r\n */\r\n\r\nmodule.exports = (function (settings) {\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) {\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].makeSettings ) {\n return;\n }\r\n\r\n /**\r\n * Draw settings block\r\n */\r\n var settingsBlock = editor.tools[toolType].makeSettings();\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;\n };\r\n\r\n /**\r\n * Close and clear settings\r\n */\r\n settings.close = function () {\n editor.nodes.blockSettings.classList.remove('opened');\r\n editor.nodes.pluginSettings.innerHTML = '';\r\n\r\n this.opened = false;\n };\r\n\r\n /**\r\n * @param {string} toolType - plugin type\r\n */\r\n settings.toggle = function ( toolType ) {\n if ( !this.opened ) {\n this.open(toolType);\n } else {\n this.close();\n }\n };\r\n\r\n /**\r\n * Here we will draw buttons and add listeners to components\r\n */\r\n settings.makeRemoveBlockButton = function () {\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;\n };\r\n\r\n settings.removeButtonClicked = function () {\n var action = editor.toolbar.settings.actions;\r\n\r\n if (action.classList.contains('opened')) {\n editor.toolbar.settings.hideRemoveActions();\n } else {\n editor.toolbar.settings.showRemoveActions();\n }\r\n\r\n editor.toolbar.toolbox.close();\r\n editor.toolbar.settings.close();\n };\r\n\r\n settings.cancelRemovingRequest = function () {\n editor.toolbar.settings.actions.classList.remove('opened');\n };\r\n\r\n settings.confirmRemovingRequest = function () {\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) {\n /** update currentNode variable */\r\n editor.content.currentNode = null;\r\n\r\n /** Inserting new empty initial block */\r\n editor.ui.addInitialBlock();\n }\r\n\r\n editor.ui.saveInputs();\r\n\r\n editor.toolbar.close();\n };\r\n\r\n settings.showRemoveActions = function () {\n editor.toolbar.settings.actions.classList.add('opened');\n };\r\n\r\n settings.hideRemoveActions = function () {\n editor.toolbar.settings.actions.classList.remove('opened');\n };\r\n\r\n return settings;\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) {\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 () {\n if (editor.hideToolbar) {\n return;\n }\r\n\r\n let toolType = editor.content.currentNode.dataset.tool;\r\n\r\n if (!editor.tools[toolType] || !editor.tools[toolType].makeSettings ) {\n editor.nodes.showSettingsButton.classList.add('hide');\n } else {\n editor.nodes.showSettingsButton.classList.remove('hide');\n }\r\n\r\n editor.nodes.toolbar.classList.add('opened');\r\n this.opened = true;\n };\r\n\r\n /**\r\n * @protected\r\n */\r\n toolbar.close = function () {\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) {\n editor.nodes.toolbarButtons[button].classList.remove('selected');\n }\r\n\r\n /** Close toolbox when toolbar is not displayed */\r\n editor.toolbar.toolbox.close();\r\n editor.toolbar.settings.close();\n };\r\n\r\n toolbar.toggle = function () {\n if ( !this.opened ) {\n this.open();\n } else {\n this.close();\n }\n };\r\n\r\n toolbar.hidePlusButton = function () {\n editor.nodes.plusButton.classList.add('hide');\n };\r\n\r\n toolbar.showPlusButton = function () {\n editor.nodes.plusButton.classList.remove('hide');\n };\r\n\r\n /**\r\n * Moving toolbar to the specified node\r\n */\r\n toolbar.move = function () {\n /** Close Toolbox when we move toolbar */\r\n editor.toolbar.toolbox.close();\r\n\r\n if (!editor.content.currentNode) {\n return;\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();\n };\r\n\r\n return toolbar;\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) {\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 () {\n /** Close setting if toolbox is opened */\r\n if (editor.toolbar.settings.opened) {\n editor.toolbar.settings.close();\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;\n };\r\n\r\n /** Closes toolbox */\r\n toolbox.close = function () {\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;\n };\r\n\r\n toolbox.leaf = function () {\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 ) {\n /** Get first tool from object*/\r\n for(tool in editor.tools) {\n if (editor.tools[tool].displayInToolbox) {\n break;\n }\r\n\r\n nextToolIndex ++;\n }\n } else {\n nextToolIndex = (tools.indexOf(currentTool) + 1) % tools.length;\r\n visibleTool = tools[nextToolIndex];\r\n\r\n while (!editor.tools[visibleTool].displayInToolbox) {\n nextToolIndex = (nextToolIndex + 1) % tools.length;\r\n visibleTool = tools[nextToolIndex];\n }\n }\r\n\r\n toolToSelect = tools[nextToolIndex];\r\n\r\n for ( var button in barButtons ) {\n barButtons[button].classList.remove('selected');\n }\r\n\r\n barButtons[toolToSelect].classList.add('selected');\r\n editor.toolbar.current = toolToSelect;\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) {\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 ) {\n /** Replace current block */\r\n editor.content.switchBlock(workingNode, newBlockContent, tool.type);\n } else {\n /** Insert new Block from plugin */\r\n editor.content.insertBlock(blockData);\r\n\r\n /** increase input index */\r\n currentInputIndex++;\n }\r\n\r\n /** Fire tool append callback */\r\n appendCallback = tool.appendCallback;\r\n\r\n if (appendCallback && typeof appendCallback == 'function') {\n appendCallback.call(event);\n }\r\n\r\n window.setTimeout(function () {\n /** Set caret to current block */\r\n editor.caret.setToBlock(currentInputIndex);\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();\n };\r\n\r\n return toolbox;\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\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, 'click', event => this.documentClicked(event), false );\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\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 this.Editor.BlockManager.setCurrentBlockByChildNode(clickedNode);\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 *\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 //\r\n // editor.caret.saveCurrentInputIndex();\r\n //\r\n // }\r\n\r\n // if (editor.content.currentNode === null) {\r\n //\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 //\r\n // /** getting firstlevel parent of input */\r\n // firstLevelBlock = editor.content.getFirstLevelBlock(editor.state.inputs[indexOfLastInput]);\r\n //\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 //\r\n // editor.caret.setToBlock(indexOfLastInput);\r\n //\r\n // } else {\r\n //\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 //\r\n // editor.caret.setToBlock(indexOfLastInput);\r\n //\r\n // } else {\r\n //\r\n // /** Set caret to this appended input */\r\n // editor.caret.setToNextBlock(indexOfLastInput);\r\n //\r\n // }\r\n //\r\n // }\r\n //\r\n // } else {\r\n //\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 /**\r\n * Move toolbar and open\r\n */\r\n this.Editor.Toolbar.move();\r\n this.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\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 * 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 * 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 * 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 Plus Button and Toolbox buttons height and width\\r\\n */\\r\\n --toolbar-buttons-size: 34px;\\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\\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::-moz-selection{\\r\\n background-color: rgba(61,166,239,0.63);\\r\\n}\\r\\n::selection{\\r\\n background-color: rgba(61,166,239,0.63);\\r\\n}\\r\\n.ce-tune-moveup{}\\r\\n.ce-settings-delete:hover {\\r\\n cursor: pointer;\\r\\n }\\r\\n.ce-settings-delete::before {\\r\\n content: 'delete'\\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 position: absolute;\\r\\n left: calc(calc(34px + 10px) * -1);\\r\\n left: calc(calc(var(--toolbar-buttons-size) + 10px) * -1);\\r\\n display: inline-block;\\r\\n background-color: #eff2f5;\\r\\n background-color: var(--bg-light);\\r\\n width: 34px;\\r\\n width: var(--toolbar-buttons-size);\\r\\n height: 34px;\\r\\n height: var(--toolbar-buttons-size);\\r\\n line-height: 34px;\\r\\n text-align: center;\\r\\n border-radius: 50%;\\r\\n cursor: pointer;\\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 display: inline-block;\\r\\n list-style: none;\\r\\n margin: 0;\\r\\n background: #eff2f5;\\r\\n background: var(--bg-light);\\r\\n width: 34px;\\r\\n width: var(--toolbar-buttons-size);\\r\\n height: 34px;\\r\\n height: var(--toolbar-buttons-size);\\r\\n border-radius: 30px;\\r\\n overflow: hidden;\\r\\n text-align: center;\\r\\n line-height: 34px;\\r\\n line-height: var(--toolbar-buttons-size)\\r\\n }\\r\\n.ce-toolbox__button::before {\\r\\n content: attr(title);\\r\\n font-size: 22px;\\r\\n font-weight: 500;\\r\\n letter-spacing: 1em;\\r\\n -webkit-font-feature-settings: \\\"smcp\\\", \\\"c2sc\\\";\\r\\n font-feature-settings: \\\"smcp\\\", \\\"c2sc\\\";\\r\\n font-variant-caps: all-small-caps;\\r\\n padding-left: 11.5px;\\r\\n margin-top: -1px;\\r\\n display: inline-block;\\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;\\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--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-settings-move-up:hover {\\r\\n cursor: pointer;\\r\\n }\\r\\n.ce-settings-move-up--disabled {\\r\\n cursor: not-allowed !important;\\r\\n opacity: .3;\\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\", \"\"]);\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-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","Editor","new","target","TypeError","DeleteTune","api","CSS","wrapper","button","buttonDelete","buttonConfirm","nodes","resetConfirmation","setConfirmation","$","make","appendChild","svg","listener","on","event","handleClick","needConfirmation","events","off","blocks","delete","classList","add","MoveUpTune","btnDisabled","moveUpButton","getCurrentBlockIndex","currentBlockIndex","currentBlockElement","getBlockByIndex","html","previousBlockElement","currentBlockCoords","getBoundingClientRect","previousBlockCoords","scrollUpOffset","top","Math","abs","window","innerHeight","scrollBy","swap","Block","toolName","toolInstance","settings","apiMethods","tool","_html","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","contentless","emptyText","emptyMedia","hasMedia","mediaTags","querySelector","join","selected","remove","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","childNodes","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","keyCodes","BACKSPACE","backspace","ENTER","enter","DOWN","RIGHT","arrowRightAndDownPressed","UP","LEFT","arrowLeftAndUpPressed","InlineToolbar","handleShowingEvent","apiSettings","IS_ENABLED_LINE_BREAKS","shiftKey","split","newCurrent","isInitial","plusButton","show","BM","isFirstBlock","canMergeBlocks","isAtStart","targetBlock","blockToMerge","mergeable","setCaretToTheEnd","mergeBlocks","setTimeout","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","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","rangeCount","selectRange","getRangeAt","blockElem","deleteContents","cloneRange","selectNodeContents","endContainer","endOffset","extractContents","from","direction","current","siblings","contentEditable","force","isAtEnd","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","makeSettings","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","holder","appendSVGSprite","loadStyles","getElementById","editorWrapper","editorZone","styles","toString","head","redactorClicked","documentClicked","clickedOnInlineToolbarButton","clickedNode","setCurrentBlockByChildNode","setToTheLastBlock","isInitialBlock","isEmptyBlock","spriteHolder","sprite","Element","prototype","matches","msMatchesSelector","webkitMatchesSelector","s","documentElement","parentElement","savedSelectionRange","sel","getSelection","searchDepth","parentTag","focusNode","boundNodes","searchDepthIterable","boundingLeft","boundingTop","boundingWidth","boundingHeight","span","insertNode","spanParent","normalize","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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AKjC,MAAL,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;;;;;;;kBAjHkBD,W;AA4MpB;;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;;;;;;;;;;;;;;;;;;;;;;;;;ACjZA;;;;;;;;;IASqBmB,M;AACjB;;;;;AAKA,wBAAwB;AAAA,QAAVlB,MAAU,QAAVA,MAAU;;AAAA;;AACpB;;;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A,KAFL;AAGLua,iBAAU,OAAAC;AAHL,OAAP;AAKD;;;;EA5DgCxb,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;;;;kBA5NqB0Q,K;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtBrB;;;;;;;;;;;IAWqB+K,a;;;AACnB;;;AAGA,+BAAsB;AAAA,QAAT3c,MAAS,QAATA,MAAS;;AAAA;;AAAA,8HACd,EAACA,cAAD,EADc;;AAGpB,UAAK4D,KAAL,GAAa;AACXJ,eAAS,IADE;AAEXoZ,oBAAc,IAFH;AAGXC,uBAAiB;AAHN,KAAb;AAHoB;AAQrB;;AAED;;;;;;;;;;AA2BA;;;;;;;2BAOO;AACL,WAAKjZ,KAAL,CAAWJ,OAAX,GAAqBO,EAAEC,IAAF,CAAO,KAAP,EAAc2Y,cAAcpZ,GAA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ACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;kBAxfqBW,E;;;;;;;;;;;;;;;;AC7BrB;;;;;AAKA,IAAI,CAACqhB,QAAQC,SAAR,CAAkBC,OAAvB,EACEF,QAAQC,SAAR,CAAkBC,OAAlB,GAA4BF,QAAQC,SAAR,CAAkBE,iBAAlB,IACtBH,QAAQC,SAAR,CAAkBG,qBADxB;;AAGF,IAAI,CAACJ,QAAQC,SAAR,CAAkBxN,OAAvB,EACEuN,QAAQC,SAAR,CAAkBxN,OAAlB,GAA4B,UAAU4N,CAAV,EAAa;AACvC,MAAIpa,KAAK,IAAT;;AAEA,MAAI,CAAClB,SAASub,eAAT,CAAyBnG,QAAzB,CAAkClU,EAAlC,CAAL,EAA4C,OAAO,IAAP;AAC5C,KAAG;AACD,QAAIA,GAAGia,OAAH,CAAWG,CAAX,CAAJ,EAAmB,OAAOpa,EAAP;AACnBA,SAAKA,GAAGsa,aAAH,IAAoBta,GAAGiB,UAA5B;AACD,GAHD,QAGSjB,OAAO,IAHhB;AAIA,SAAO,IAAP;AACD,CATD,C;;;;;;;;;;;;;;;;;;;;;;ACVF;;;;IAIqBwE,S;AAC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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 delete this.moduleInstances; // todo Is it necessary?\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 {Object} Editor - List of Editor modules\n */\nexport default class Module {\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor({ config }) {\n /**\n * Editor modules list\n * @type {EditorComponents}\n */\n this.Editor = null;\n /**\n * Editor configuration object\n * @type {EditorConfig}\n */\n this.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 *\n * @param Editor\n * @param Editor.modules {@link CodexEditor#moduleInstances}\n * @param Editor.config {@link CodexEditor#configuration}\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 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-settings-move-up',\n btnDisabled: 'ce-settings-move-up--disabled',\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 if (this.api.blocks.getCurrentBlockIndex() === 0) {\n moveUpButton.classList.add(this.CSS.btnDisabled);\n }\n else {\n this.api.listener.on(moveUpButton, 'click', (event) => this.handleClick(event), false);\n }\n return moveUpButton;\n }\n /**\n * Move current block up\n * @param {MouseEvent} event\n */\n handleClick(event) {\n const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();\n if (currentBlockIndex === 0) {\n return;\n }\n const currentBlockElement = this.api.blocks.getBlockByIndex(currentBlockIndex).html, previousBlockElement = this.api.blocks.getBlockByIndex(currentBlockIndex - 1).html;\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';\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 wrapper - Div element that wraps block content with Tool's content. Has `ce-block` CSS class\n * @property contentNode - Div element that wraps Tool's content. Has `ce-block__content` 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._html = 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 this.wrapper = $.make('div', Block.CSS.wrapper);\n this.contentNode = $.make('div', Block.CSS.content);\n this.pluginsContent = this.tool.render();\n\n this.contentNode.appendChild(this.pluginsContent);\n this.wrapper.appendChild(this.contentNode);\n\n return this.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 * Get Block`s HTML\n * @returns {HTMLElement}\n */\n get html() {\n return this._html;\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];\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._html.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._html.classList.add(Block.CSS.selected);\n } else {\n this._html.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} 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 * @param {EditorsConfig} config\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 };\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 if (this.Editor.Caret.navigatePrevious(true)) {\n this.Editor.Toolbar.close();\n }\n }\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 * @param {EditorsConfig} config\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 * @param {EditorsConfig} config\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 * @param {EditorsConfig} config\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 * @param {EditorsConfig} config\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 * @param {EditorsConfig} config\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 * @param {EditorsConfig} config\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 sanitizer: this.Editor.SanitizerAPI.methods,\n saver: this.Editor.SaverAPI.methods,\n selection: this.Editor.SelectionAPI.methods,\n listener: this.Editor.ListenerAPI.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 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.arrowRightAndDownPressed();\n break;\n case _.keyCodes.UP:\n case _.keyCodes.LEFT:\n this.arrowLeftAndUpPressed();\n break;\n default:\n break;\n }\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 this.Editor.Toolbar.open();\n if (this.Editor.Tools.isInitial(newCurrent.tool) && newCurrent.isEmpty) {\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 (!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 }\n const setCaretToTheEnd = !targetBlock.isEmpty;\n BM.mergeBlocks(targetBlock, blockToMerge)\n .then(() => {\n // @todo figure out without timeout\n window.setTimeout(() => {\n // set caret to the block without offset at the end\n this.Editor.Caret.setToBlock(BM.currentBlock, 0, setCaretToTheEnd);\n this.Editor.Toolbar.close();\n }, 10);\n });\n }\n /**\n * Handle right and down keyboard keys\n */\n arrowRightAndDownPressed() {\n this.Editor.Caret.navigateNext();\n this.Editor.Toolbar.close();\n }\n /**\n * Handle left and up keyboard keys\n */\n arrowLeftAndUpPressed() {\n this.Editor.Caret.navigatePrevious();\n this.Editor.Toolbar.close();\n }\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.html, 'keydown', (event) => this.Editor.BlockEvents.keydown(event));\n this.Editor.Listeners.on(block.html, 'mouseup', (event) => this.Editor.BlockEvents.mouseUp(event));\n this.Editor.Listeners.on(block.html, '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 * 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 {HTMLElement} 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 * Remove previous selected Block's state\n */\n this.blocks.forEach( block => block.selected = false);\n\n /**\n * Mark current Block as selected\n * @type {boolean}\n */\n this.currentBlock.selected = true;\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 * 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.currentBlockIndex = -1;\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.html);\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].html, secondBlock.html);\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].html.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.html.insertAdjacentElement('afterend', block.html);\n } else {\n let nextBlock = this.blocks[index + 1];\n\n if (nextBlock) {\n nextBlock.html.insertAdjacentElement('beforebegin', block.html);\n } else {\n this.workingArea.appendChild(block.html);\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].html.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 * 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.html;\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.wrapper;\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.insert(this.config.initialBlock);\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.html);\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.html, 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 * @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.makeSettings === 'function') {\n $.append(this.nodes.toolSettings, this.Editor.BlockManager.currentBlock.tool.makeSettings());\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';\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, 'click', event => this.documentClicked(event), false );\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\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 this.Editor.BlockManager.setCurrentBlockByChildNode(clickedNode);\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 *\n\n /** Update current input index in memory when caret focused into existed input */\n // if (event.target.contentEditable == 'true') {\n //\n // editor.caret.saveCurrentInputIndex();\n //\n // }\n\n // if (editor.content.currentNode === null) {\n //\n // /**\n // * If inputs in redactor does not exits, then we put input index 0 not -1\n // */\n // var indexOfLastInput = editor.state.inputs.length > 0 ? editor.state.inputs.length - 1 : 0;\n //\n // /** If we have any inputs */\n // if (editor.state.inputs.length) {\n //\n // /** getting firstlevel parent of input */\n // firstLevelBlock = editor.content.getFirstLevelBlock(editor.state.inputs[indexOfLastInput]);\n //\n // }\n //\n // /** If input is empty, then we set caret to the last input */\n // if (editor.state.inputs.length && editor.state.inputs[indexOfLastInput].textContent === '' && firstLevelBlock.dataset.tool == editor.settings.initialBlockPlugin) {\n //\n // editor.caret.setToBlock(indexOfLastInput);\n //\n // } else {\n //\n // /** Create new input when caret clicked in redactors area */\n // var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;\n //\n // editor.content.insertBlock({\n // type : NEW_BLOCK_TYPE,\n // block : editor.tools[NEW_BLOCK_TYPE].render()\n // });\n //\n // /** If there is no inputs except inserted */\n // if (editor.state.inputs.length === 1) {\n //\n // editor.caret.setToBlock(indexOfLastInput);\n //\n // } else {\n //\n // /** Set caret to this appended input */\n // editor.caret.setToNextBlock(indexOfLastInput);\n //\n // }\n //\n // }\n //\n // } else {\n //\n // /** Close all panels */\n // editor.toolbar.settings.close();\n // editor.toolbar.toolbox.close();\n //\n // }\n //\n /**\n * Move toolbar and open\n */\n this.Editor.Toolbar.move();\n this.Editor.Toolbar.open();\n //\n // var inputIsEmpty = !editor.content.currentNode.textContent.trim(),\n // currentNodeType = editor.content.currentNode.dataset.tool,\n // isInitialType = currentNodeType == editor.settings.initialBlockPlugin;\n //\n //\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 * 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 * 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 * 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 Plus Button and Toolbox buttons height and width\\n */\\n --toolbar-buttons-size: 34px;\\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\\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::-moz-selection{\\n background-color: rgba(61,166,239,0.63);\\n}\\n::selection{\\n background-color: rgba(61,166,239,0.63);\\n}\\n.ce-tune-moveup{}\\n.ce-settings-delete:hover {\\n cursor: pointer;\\n }\\n.ce-settings-delete::before {\\n content: 'delete'\\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 position: absolute;\\n left: calc(calc(34px + 10px) * -1);\\n left: calc(calc(var(--toolbar-buttons-size) + 10px) * -1);\\n display: inline-block;\\n background-color: #eff2f5;\\n background-color: var(--bg-light);\\n width: 34px;\\n width: var(--toolbar-buttons-size);\\n height: 34px;\\n height: var(--toolbar-buttons-size);\\n line-height: 34px;\\n text-align: center;\\n border-radius: 50%;\\n cursor: pointer;\\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 display: inline-block;\\n list-style: none;\\n margin: 0;\\n background-color: #eff2f5;\\n background-color: var(--bg-light);\\n width: 34px;\\n width: var(--toolbar-buttons-size);\\n height: 34px;\\n height: var(--toolbar-buttons-size);\\n border-radius: 30px;\\n overflow: hidden;\\n text-align: center;\\n line-height: 34px;\\n line-height: var(--toolbar-buttons-size);\\n\\n /*&::before {*/\\n /*content: attr(title);*/\\n /*font-size: 22px;*/\\n /*font-weight: 500;*/\\n /*letter-spacing: 1em;*/\\n /*font-variant-caps: all-small-caps;*/\\n /*padding-left: 11.5px;*/\\n /*margin-top: -1px;*/\\n /*display: inline-block;*/\\n /*}*/\\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;\\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--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-settings-move-up:hover {\\n cursor: pointer;\\n }\\n.ce-settings-move-up--disabled {\\n cursor: not-allowed !important;\\n opacity: .3;\\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\", \"\"]);\n\n// exports\n"],"sourceRoot":""} \ No newline at end of file diff --git a/example/example.html b/example/example.html index 02e096ee..b6535caf 100644 --- a/example/example.html +++ b/example/example.html @@ -25,38 +25,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -68,15 +38,13 @@ initialBlock : 'text', tools: { text: Text, - term: Term + header: Header, + term: Term, }, toolsConfig: { text: { inlineToolbar : true, }, - quote: { - enableLineBreaks : true - } }, data: { items: [ @@ -92,12 +60,40 @@ text : 'В JavaScript
    нет возможности назначить свойства при объявлении класса — все необходимые значения нужно определять в конструкторе или других методах. При таком подходе объявление свойств неявное, не всегда ясно какие свойства имеет класс. TS решает эту проблему: здесь можно не только объявить свойства класса, но и назначить им начальные значения' } }, + { + type: "header", + data: { + text: "ES6 тебя сожрет", + level: 4 + } + }, { type : 'text', data : { text : 'Одним из недостатков ES6 классов является невозможность сделать методы и свойства приватными. В TS есть привычные модификаторы: public, private и protected, которые можно использовать как для методов, так и для свойств. По умолчанию, как и в других языках, все свойства имеют модификатор public.' } - } + }, + { + type: "header", + data: { + text: "Header 2", + level: 2 + } + }, + { + type: "header", + data: { + text: "Header 3", + level: 3 + } + }, + { + type: "header", + data: { + text: "Header 4", + level: 4 + } + }, ] } }); @@ -106,192 +102,5 @@ window.editor = editor; -// var editor2 = new CodexEditor({ -// holderId : 'cdx', -// initialBlock: 'header' -// }); -// codex.editor.start({ -// holderId : "codex-editor", -// initialBlockPlugin : 'text', -// // placeholder: 'Прошлой ночью мне приснилось...', -// hideToolbar: false, -// tools : { -// text: { -// type: 'text', -// iconClassname: 'ce-icon-text', -// render: text.render, -// validate: text.validate, -// save: text.save, -// destroy: text.destroy, -// allowedToPaste: true, -// showInlineToolbar: true, -// allowRenderOnPaste: true -// }, -// header: { -// type: 'header', -// iconClassname: 'ce-icon-header', -// appendCallback: header.appendCallback, -// makeSettings: header.makeSettings, -// render: header.render, -// validate: header.validate, -// save: header.save, -// destroy: header.destroy, -// displayInToolbox: true -// }, -// code: { -// type: 'code', -// iconClassname: 'ce-icon-code', -// make: code.make, -// appendCallback: null, -// settings: null, -// render: code.render, -// validate: code.validate, -// save: code.save, -// destroy: code.destroy, -// displayInToolbox: true, -// enableLineBreaks: true -// }, -// link: { -// type: 'link', -// iconClassname: 'ce-icon-link', -// prepare: link.prepare, -// make: link.makeNewBlock, -// appendCallback: link.appendCallback, -// render: link.render, -// validate: link.validate, -// save: link.save, -// destroy: link.destroy, -// displayInToolbox: true, -// enableLineBreaks: true -// }, -// list: { -// type: 'list', -// iconClassname: 'ce-icon-list-bullet', -// make: list.make, -// appendCallback: null, -// makeSettings: list.makeSettings, -// render: list.render, -// validate: list.validate, -// save: list.save, -// destroy: list.destroy, -// displayInToolbox: true, -// showInlineToolbar: true, -// enableLineBreaks: true, -// allowedToPaste: true, -// }, -// quote: { -// type: 'quote', -// iconClassname: 'ce-icon-quote', -// makeSettings: quote.makeSettings, -// prepare: quote.prepare, -// render: quote.render, -// validate: quote.validate, -// save: quote.save, -// destroy: quote.destroy, -// displayInToolbox: true, -// enableLineBreaks: true, -// showInlineToolbar: true, -// allowedToPaste: true, -// config : { -// defaultStyle : 'withPhoto' -// } -// }, -// image_extended: { -// type: 'image_extended', -// iconClassname: 'ce-icon-picture', -// appendCallback: image.appendCallback, -// prepare: image.prepare, -// makeSettings: image.makeSettings, -// render: image.render, -// save: image.save, -// destroy: image.destroy, -// isStretched: true, -// showInlineToolbar: true, -// displayInToolbox: true, -// renderOnPastePatterns: image.pastePatterns, -// config: { -// uploadImage : '/writing/uploadImage', -// uploadFromUrl : '/club/fetch' -// } -// }, -// instagram: { -// type: 'instagram', -// iconClassname: 'ce-icon-instagram', -// prepare: instagram.prepare, -// render: instagram.render, -// validate: instagram.validate, -// save: instagram.save, -// destroy: instagram.destroy, -// renderOnPastePatterns: instagram.pastePatterns, -// }, -// tweet: { -// type: 'tweet', -// iconClassname: 'ce-icon-twitter', -// prepare: twitter.prepare, -// render: twitter.render, -// validate: twitter.validate, -// save: twitter.save, -// destroy: twitter.destroy, -// showInlineToolbar : true, -// renderOnPastePatterns: twitter.pastePatterns, -// config : { -// fetchUrl : '' -// } -// }, -// video_extended: { -// type: 'video_extended', -// make: embed.make, -// render: embed.render, -// save: embed.save, -// destroy: embed.destroy, -// validate: embed.validate, -// renderOnPastePatterns: embed.pastePatterns, -// }, -// raw: { -// type: 'raw', -// displayInToolbox: true, -// iconClassname: 'raw-plugin-icon', -// render: rawPlugin.render, -// save: rawPlugin.save, -// validate: rawPlugin.validate, -// destroy: rawPlugin.destroy, -// enableLineBreaks: true, -// allowPasteHTML: true -// }, -// attaches: { -// type: 'attaches', -// displayInToolbox: true, -// iconClassname: 'cdx-attaches__icon', -// prepare: cdxAttaches.prepare, -// render: cdxAttaches.render, -// save: cdxAttaches.save, -// validate: cdxAttaches.validate, -// destroy: cdxAttaches.destroy, -// appendCallback: cdxAttaches.appendCallback, -// config: { -// fetchUrl: '/test', -// maxSize: 50000, -// } -// }, -// }, -// data : { -// id: +new Date(), -// items: [ -// { -// type : 'header', -// data : { -// text : 'Привет от CodeX' -// } -// }, -// { -// type : 'text', -// data : { -// text : 'Пишите нам на team@ifmo.su' -// } -// }, -// ], -// count: 3 -// } -// }); diff --git a/example/plugins/header/header.css b/example/plugins/header/header.css index 42a1c0ce..c1c40283 100644 --- a/example/plugins/header/header.css +++ b/example/plugins/header/header.css @@ -1,41 +1,24 @@ /** -* Plugin styles -*/ + * Plugin styles + */ .ce-header { - padding: .7em 0; - margin: 0; - line-height: 1.4em; + padding: .7em 0; + margin: 0; + line-height: 1.4em; + outline: none; } -.ce-header p, -.ce-header div{ + + .ce-header p, + .ce-header div{ padding: 0 !important; margin: 0 !important; -} - -/** H e a d e r - settings */ -.ce_plugin_header--select_button{ - display: block; - color: #306ac7; - cursor: pointer; - line-height: 1.3em; -} - .ce_plugin_header--select_button:not(:last-of-type){ - margin-bottom: 1.5em; - } - .ce_plugin_header--select_button:hover{ - color: #a1b4ec; - } - + } /** -* Empty header placeholder -*/ -.ce-header:empty::before{ - content : attr(data-placeholder); - color: #818BA1; - opacity: .7; - transition: opacity 200ms ease; -} -.ce-header:focus::before{ - opacity: .1; + * Styles for Plugin icon in Toolbar + */ +.cdx-header-icon { + background-image: url('icon.svg'); + background-position: center center; + background-repeat: no-repeat; } diff --git a/example/plugins/header/header.js b/example/plugins/header/header.js index 42dfc00a..5db3a637 100644 --- a/example/plugins/header/header.js +++ b/example/plugins/header/header.js @@ -1,150 +1,324 @@ /** -* Example of making plugin -* H e a d e r -*/ + * @typedef {Object} HeaderData + * @description Tool's input and output data format + * @property {String} text — Header's content + * @property {number} level - Header's level from 1 to 3 + */ -var header = (function (header_plugin) { +/** + * Header block for the CodeX Editor. + * + * @author CodeX Team (team@ifmo.su) + * @copyright CodeX Team 2018 + * @license The MIT License (MIT) + * @version 2.0.0 + */ +class Header { /** - * @private - */ - var methods_ = { - - /** - * Binds click event to passed button - */ - addSelectTypeClickListener : function (el, type) { - el.addEventListener('click', function () { - methods_.selectTypeClicked(type); - }, false); - }, - - /** - * Replaces old header with new type - * @params {string} type - new header tagName: H1—H6 - */ - selectTypeClicked : function (type) { - var old_header, new_header; - - /** Now current header stored as a currentNode */ - old_header = codex.editor.content.currentNode.querySelector('[contentEditable]'); - - /** Making new header */ - new_header = codex.editor.draw.node(type, [ 'ce-header' ], { innerHTML : old_header.innerHTML }); - new_header.contentEditable = true; - new_header.setAttribute('data-placeholder', 'Заголовок'); - new_header.dataset.headerData = type; - - codex.editor.content.switchBlock(old_header, new_header, 'header'); - - /** Close settings after replacing */ - codex.editor.toolbar.settings.close(); - } - - }; - - /** - * @private - * - * Make initial header block - * @param {object} JSON with block data - * @return {Element} element to append - */ - var make_ = function (data) { - var availableTypes = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'], - tag, - headerType = 'h2'; - - - if ( data && data['heading-styles'] && availableTypes.includes(data['heading-styles']) ) { - headerType = data['heading-styles']; - } - - tag = document.createElement(headerType); - - /** - * Save header type in data-attr. - * We need it in save method to extract type from HTML to JSON - */ - tag.dataset.headerData = headerType; - - - if (data && data.text) { - tag.textContent = data.text; - } - - if (!tag.dataset.headerData) { - tag.dataset.headerData = 'h2'; - } - - tag.classList.add('ce-header'); - tag.setAttribute('data-placeholder', 'Заголовок'); - tag.contentEditable = true; - - return tag; - }; - - header_plugin.prepareDataForSave = function (data) { - - }; + * Should this tools be displayed at the Editor's Toolbox + * @returns {boolean} + * @public + */ + static get displayInToolbox() { + return true; + } /** - * Method to render HTML block from JSON - */ - header_plugin.render = function (data) { - return make_(data); - }; + * Class for the Toolbox icon + * @returns {string} + * @public + */ + static get iconClassName() { + return 'cdx-header-icon'; + } /** - * Method to extract JSON data from HTML block + * Render plugin`s main Element and fill it with saved data + * @param {HeaderData} savedData — previously saved data + */ + constructor(savedData = {}) { + /** + * Styles + * @type {Object} */ - header_plugin.save = function (blockContent) { - var data = { - 'heading-styles': blockContent.dataset.headerData, - 'format': 'html', - 'text': blockContent.textContent || '' + this._CSS = { + wrapper: 'ce-header', + settingsButton: 'ce-settings__button', + settingsSelected: 'ce-settings__button--selected', }; - return data; - }; + /** + * Block's data + * @type {Object} + */ + this._data = savedData || {}; + + /** + * List of settings buttons + * @type {HTMLElement[]} + */ + this.settingsButtons = []; + + /** + * Main Block wrapper + * @type {HTMLElement} + */ + this._element = this.getTag(); + } /** - * Settings panel content - * - - - - - - - - - - - - - - * | настройки H1 H2 H3 | - * - - - - - - - - - - - - - - * @return {Element} element contains all settings - */ - header_plugin.makeSettings = function () { - var holder = codex.editor.draw.node('DIV', [ 'cdx-plugin-settings--horisontal' ], {} ), - types = { - h2: 'H2', - h3: 'H3', - h4: 'H4' - }, - selectTypeButton; + * Return Tool's view + * @returns {HTMLHeadingElement} + * @public + */ + render() { + return this._element; + } - /** Now add type selectors */ - for (var type in types) { - selectTypeButton = codex.editor.draw.node('SPAN', [ 'cdx-plugin-settings__item' ], { textContent : types[type] }); - methods_.addSelectTypeClickListener(selectTypeButton, type); + /** + * Create Block's settings block + * + * @return {HTMLElement} + */ + makeSettings() { + let holder = document.createElement('DIV'); + + /** Add type selectors */ + this.levels.forEach( level => { + let selectTypeButton = document.createElement('SPAN'); + + selectTypeButton.classList.add(this._CSS.settingsButton); + + /** + * Highlight current level button + */ + if (this.currentLevel.number === level.number) { + selectTypeButton.classList.add(this._CSS.settingsSelected); + } + + /** + * Add SVG icon + */ + selectTypeButton.innerHTML = level.svg; + + /** + * Save level to its button + */ + selectTypeButton.dataset.level = level.number; + + /** + * Set up click handler + */ + selectTypeButton.addEventListener('click', () => { + this.setLevel(level.number); + }); + + /** + * Append settings button to holder + */ holder.appendChild(selectTypeButton); - } + + /** + * Save settings buttons + */ + this.settingsButtons.push(selectTypeButton); + }); return holder; - }; + } - header_plugin.validate = function (data) { - if (data.text.trim() === '' || data['heading-styles'].trim() === '') { - return false; + /** + * Callback for Block's settings buttons + * @param level + */ + setLevel(level) { + this.data = { + level: level + }; + + /** + * Highlight button by selected level + */ + this.settingsButtons.forEach(button => { + button.classList.toggle(this._CSS.settingsSelected, parseInt(button.dataset.level) === level); + }); + } + + /** + * Method that specified how to merge two Text blocks. + * Called by CodeX Editor by backspace at the beginning of the Block + * @param {TextData} data + * @public + */ + merge(data) { + let newData = { + text: this._data.text + data.text, + level: this._data.level + }; + + this.data = newData; + } + + /** + * Validate Text block data: + * - check for emptiness + * + * @param {TextData} savedData — data received after saving + * @returns {boolean} false if saved data is not correct, otherwise true + * @public + */ + validate(savedData) { + return savedData.text.trim() !== ''; + } + + /** + * Extract Tool's data from the view + * @param {HTMLHeadingElement} toolsContent - Text tools rendered view + * @returns {TextData} - saved data + * @public + */ + save(toolsContent) { + /** + * @todo sanitize data + */ + + return { + text: toolsContent.innerHTML, + level: this.currentLevel.number + }; + } + + /** + * Get current Tools`s data + * @returns {TextData} Current data + * @private + */ + get data() { + this._data.text = this._element.innerHTML; + this._data.level = this.currentLevel.number; + + return this._data; + } + + /** + * Store data in plugin: + * - at the this._data property + * - at the HTML + * + * @param {HeaderData} data — data to set + * @private + */ + set data(data) { + this._data = data || {}; + + /** + * If level is set and block in DOM + * then replace it to a new block + */ + if (data.level !== undefined && this._element.parentNode) { + /** + * Create a new tag + * @type {HTMLHeadingElement} + */ + let newHeader = this.getTag(); + + /** + * Save Block's content + */ + newHeader.innerHTML = this._element.innerHTML; + + /** + * Replace blocks + */ + this._element.parentNode.replaceChild(newHeader, this._element); + + /** + * Save new block to private variable + * @type {HTMLHeadingElement} + * @private + */ + this._element = newHeader; } - return true; - }; + /** + * If data.text was passed then update block's content + */ + if (data.text !== undefined) { + this._element.innerHTML = this._data.text || ''; + } + } - header_plugin.destroy = function () { - header = null; - }; + /** + * Get tag for target level + * By default returns second-leveled header + * @return {HTMLElement} + */ + getTag() { + /** + * Create element for current Block's level + */ + let tag = document.createElement(this.currentLevel.tag); - return header_plugin; -})({}); + /** + * Add text to block + */ + tag.innerHTML = this._data.text || ''; + /** + * Add styles class + */ + tag.classList.add(this._CSS.wrapper); + + /** + * Make tag editable + */ + tag.contentEditable = 'true'; + + return tag; + } + + /** + * Get current level + * @return {level} + */ + get currentLevel() { + let level = this.levels.find( level => level.number === this._data.level); + + if (!level) { + level = this.levels[0]; + } + + return level; + } + + /** + * @typedef {object} level + * @property {number} number - level number + * @property {string} tag - tag correspondes with level number + * @property {string} svg - icon + */ + + /** + * Available header levels + * @return {level[]} + */ + get levels() { + return [ + { + number: 2, + tag: 'H2', + svg: '' + }, + { + number: 3, + tag: 'H3', + svg: '' + }, + { + number: 4, + tag: 'H4', + svg: '' + } + ]; + } +} diff --git a/example/plugins/header/icon.svg b/example/plugins/header/icon.svg new file mode 100644 index 00000000..db5fa50c --- /dev/null +++ b/example/plugins/header/icon.svg @@ -0,0 +1 @@ + diff --git a/example/plugins/text/text.js b/example/plugins/text/text.js index f0c3f35f..4186ea84 100644 --- a/example/plugins/text/text.js +++ b/example/plugins/text/text.js @@ -8,7 +8,7 @@ * @version 2.0.1 */ -/** + /** * @typedef {Object} TextData * @description Tool's input and output data format * @property {String} text — Paragraph's content. Can include HTML tags: @@ -20,7 +20,7 @@ class Text { * @public */ static get displayInToolbox() { - return true; + return false; } /** @@ -107,11 +107,13 @@ class Text { * @public */ save(toolsContent) { - let toolData = { + /** + * @todo sanitize data + */ + + return { text: toolsContent.innerHTML }; - - return toolData; } /** @@ -122,10 +124,6 @@ class Text { get data() { let text = this._element.innerHTML; - /** - * @todo sanitize data - */ - this._data.text = text; return this._data; diff --git a/src/components/modules/blockManager.js b/src/components/modules/blockManager.js index 93168671..6b0d6234 100644 --- a/src/components/modules/blockManager.js +++ b/src/components/modules/blockManager.js @@ -99,9 +99,9 @@ export default class BlockManager extends Module { * @param {Object} block */ bindEvents(block) { - this.Editor.Listeners.on(block.pluginsContent, 'keydown', (event) => this.Editor.BlockEvents.keydown(event)); - this.Editor.Listeners.on(block.pluginsContent, 'mouseup', (event) => this.Editor.BlockEvents.mouseUp(event)); - this.Editor.Listeners.on(block.pluginsContent, 'keyup', (event) => this.Editor.BlockEvents.keyup(event)); + this.Editor.Listeners.on(block.html, 'keydown', (event) => this.Editor.BlockEvents.keydown(event)); + this.Editor.Listeners.on(block.html, 'mouseup', (event) => this.Editor.BlockEvents.mouseUp(event)); + this.Editor.Listeners.on(block.html, 'keyup', (event) => this.Editor.BlockEvents.keyup(event)); } /** diff --git a/src/components/modules/caret.js b/src/components/modules/caret.js index 0e203bca..c4ebc90b 100644 --- a/src/components/modules/caret.js +++ b/src/components/modules/caret.js @@ -33,7 +33,7 @@ export default class Caret extends Module { * @param {Boolean} atEnd - put caret at the end of the text node or not */ setToBlock(block, offset = 0, atEnd = false) { - let element = block.pluginsContent; + let element = block.html; /** If Element is INPUT */ if ($.isNativeInput(element)) { @@ -224,7 +224,7 @@ export default class Caret extends Module { let selection = Selection.get(), anchorNode = selection.anchorNode, - firstNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent); + firstNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.html); /** * Workaround case when caret in the text like " |Hello!" @@ -276,7 +276,7 @@ export default class Caret extends Module { let selection = Selection.get(), anchorNode = selection.anchorNode, - lastNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent, true); + lastNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.html, true); /** * In case of diff --git a/src/styles/settings.css b/src/styles/settings.css index ffb4f7d8..d346aaa0 100644 --- a/src/styles/settings.css +++ b/src/styles/settings.css @@ -30,6 +30,10 @@ &__button { @apply --toolbar-button; + &--selected { + color: var(--color-active-icon); + } + &--delete { transition: background-color 300ms ease; will-change: background-color; diff --git a/src/styles/toolbox.css b/src/styles/toolbox.css index e0df6015..15ba1399 100644 --- a/src/styles/toolbox.css +++ b/src/styles/toolbox.css @@ -13,7 +13,7 @@ display: inline-block; list-style: none; margin: 0; - background: var(--bg-light); + background-color: var(--bg-light); width: var(--toolbar-buttons-size); height: var(--toolbar-buttons-size); border-radius: 30px; @@ -21,15 +21,15 @@ text-align: center; line-height: var(--toolbar-buttons-size); - &::before { - content: attr(title); - font-size: 22px; - font-weight: 500; - letter-spacing: 1em; - font-variant-caps: all-small-caps; - padding-left: 11.5px; - margin-top: -1px; - display: inline-block; - } + /*&::before {*/ + /*content: attr(title);*/ + /*font-size: 22px;*/ + /*font-weight: 500;*/ + /*letter-spacing: 1em;*/ + /*font-variant-caps: all-small-caps;*/ + /*padding-left: 11.5px;*/ + /*margin-top: -1px;*/ + /*display: inline-block;*/ + /*}*/ } -} \ No newline at end of file +}