From 5f670c3985c3f56ced0e592585ed084e3a1e554d Mon Sep 17 00:00:00 2001 From: Peter Savchenko Date: Sat, 2 Dec 2017 15:35:55 +0300 Subject: [PATCH] Autoloading improved, utilities now global (#225) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Autoloading improved, utilities now global # Autoloading Webpack специально не дает использовать переменные в реквайрах типа: let moduleName = 'toolbar.js'; let module = require(moduleName); У нас в автолоадинге было так: let modules = editorModules.map( module => require('./components/modules/' + module )); и это работало, но не так как нужно. Он подключал не только нужные модули из массива editorModules, а вообще все модули из папки components/modules. Я заметил, что они попадают в сборку, хоть и не указаны в реквайрах. Оказывается это так и задумано: Webpack на этапе компиляции не знает что будет в переменной, то есть какой там будет модуль. А ему нужно высчитать время компиляции, поэтому он вкладывет в сброрку тупо все файлы из этой папки, и для каждого высчитывает время. Так что по сути это было то же самое что просто написать require('./components/modules/') и подключить все файлы. Но наш автолоадер должен был подключать только указанные файлы, не заходить в подпапки и не включать файлы, начинающиеся с подчеркивания. Теперь автолоадинг работает так, как и задумывалось. # Global visible modules Теперь не нужно в каждом файле писать import $ from '../dom'; и тд. Они автоматически будут доступны внутри модулей * Update util.Dom * Remove duplicated Babel helpers. Now it will be defined at once --- .eslintrc | 4 +- .gitignore | 4 + .jshintrc | 5 +- build/codex-editor.css | 636 --- build/codex-editor.js | 6195 ++++---------------------- build/codex-editor.js.map | 2 +- example/example.html | 1 - package.json | 3 +- src/codex.js | 6 +- src/components/dom.js | 2 +- src/components/modules/toolbar.js | 5 - src/components/modules/tools.js | 5 +- src/components/modules/ui.js | 4 - src/components/{util.js => utils.js} | 16 +- webpack.config.js | 47 +- 15 files changed, 890 insertions(+), 6045 deletions(-) delete mode 100644 build/codex-editor.css rename src/components/{util.js => utils.js} (80%) diff --git a/.eslintrc b/.eslintrc index 2cf801fd..a4c548b9 100644 --- a/.eslintrc +++ b/.eslintrc @@ -72,7 +72,9 @@ "FormData": true, "XMLHttpRequest": true, "ActiveXObject": true, - "RegExp": true + "RegExp": true, + "$": true, + "_": true } } \ No newline at end of file diff --git a/.gitignore b/.gitignore index 93782c6f..07ebf98e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ node_modules/* /uploads/ plugins/personality/ + +npm-debug.log + +build/__tmp_babel_helpers.js diff --git a/.jshintrc b/.jshintrc index 49d68f10..2227bde3 100644 --- a/.jshintrc +++ b/.jshintrc @@ -12,7 +12,10 @@ // Define globals exposed by CodeX Team "predef": [ - "codex" + "codex", + "_", + "$", + "editorModules" ], // Allow ES6. diff --git a/build/codex-editor.css b/build/codex-editor.css deleted file mode 100644 index 1fb54f95..00000000 --- a/build/codex-editor.css +++ /dev/null @@ -1,636 +0,0 @@ -/** -* CodeX Editor stylesheets -* @author CodeX Team https://ifmo.su -* -* https://github.com/codex-team/codex.editor -*/ - - -@import url('icons.css'); - - -/** -* Editor wrapper -*/ -.codex-editor{ - position: relative; -} - - .codex-editor .hide { - display: none; - } - -/** -* Working zone - redactor -*/ -.ce-redactor{ - position: relative; - padding-bottom: 120px; - min-height: 350px; -} - -.ce-block__content a { - color: #186baa; -} - -/*.ce-redactor * { - box-sizing: border-box; -}*/ - -/** -* Remove outlines from inputs -*/ -.ce-redactor [contenteditable]{ - outline: none !important; -} - -/** -* Toolbar -*/ -.ce-toolbar{ - position: absolute; - z-index: 2; - width: 100%; - - /* hidden by default */ - display: none; -} -.ce-toolbar.opened{ - display: block; -} - - .ce-toolbar__content { - position: relative; - max-width: 600px; - margin: 0 auto; - } -/** -* Plus button -*/ -.ce-toolbar__plus{ - position: absolute; - background-image: url('fonts/codex_editor/icon-plus.svg'); - background-position: center center; - background-repeat: no-repeat; - text-align: center; - transition: transform 100ms ease; - will-change: transform; - - margin-left: -50px; -} -.ce-toolbar__plus.clicked{ - transform: rotate(45deg); -} - -/** -* Tools list -*/ -.ce-toolbar__tools{ - position: absolute; - top: 0; - left: 0; - - /* hidden by default */ - opacity: 0; - visibility: hidden; - transform: translateX(-100px); - transition: all 150ms cubic-bezier(0.600, -0.280, 0.735, 0.045); -} -.ce-toolbar__tools.opened{ - opacity: 1; - visibility: visible; - transform: none; -} - -.ce-toolbar__plus, -.ce-toolbar__tools li { - display: inline-block; - width: 32px; - height: 32px; - background-color: #eff2f5; - /*box-shadow: 0 0 0 1px #6d748c;*/ - margin-right: 17px; - border-radius: 16px; - text-align: center; - vertical-align: top; - cursor: pointer; - font-size: 14px; - - will-change: transform, margin-right; - transition: transform 200ms cubic-bezier(0.600, -0.280, 0.735, 0.045), margin 200ms ease-out; -} -.ce-toolbar__tools li i{ - line-height: 32px; -} -.ce-toolbar__tools li:hover, -.ce-toolbar__tools .selected{ - background: #383b5d; - box-shadow: none; - color: #fff; -} - -/* animation for tools opening */ -.ce-toolbar__tools li{ - transform: rotate(-180deg) scale(.7); - margin-right: -15px; -} -.ce-toolbar__tools.opened li{ - transform: none; - margin-right: 17px; -} - -/** -* Toolbar right zone with SETTINGS and DELETE -*/ -.ce-toolbar__actions{ - position: absolute; - right: 15px; - border-radius: 2px; - padding: 6px 5px; - line-height: 1em; - font-size: 14px; - background: #fff; -} - - -/** -* Settings button -*/ -.ce-toolbar__settings-btn{ - margin-right: .3em; - cursor: pointer; -} -.ce-toolbar__settings-btn, -.ce-toolbar__remove-btn{ - color: #5e6475; -} -.ce-toolbar__settings-btn:hover, -.ce-toolbar__remove-btn:hover{ - color: #272b35 -} - -/** -* Settigns panel -*/ -.ce-settings, -.ce-toolbar__remove-confirmation{ - position: absolute; - right: 0; - margin-top: 10px; - min-width: 200px; - background: #FFFFFF; - border: 1px solid #e7e9f1; - box-shadow: 0px 2px 5px 0px rgba(16, 23, 49, 0.05); - border-radius: 3px; - white-space: nowrap; - color: #2b2d31; - font-size: 13.4px; - - /* hidden by default */ - display: none; -} - -/** -* Settings and remove-confirmation corner -*/ -.ce-settings:before, -.ce-toolbar__remove-confirmation:before, -.ce-settings:after, -.ce-toolbar__remove-confirmation:after{ - content: ""; - position: absolute; - top: -14px; - right: 10px; - border-style: solid; -} - -.ce-settings:before, -.ce-toolbar__remove-confirmation:before { - margin: -2px -1px 0; - border-width: 8px; - border-color: transparent transparent #e7e9f1 transparent; -} -.ce-settings:after, -.ce-toolbar__remove-confirmation:after { - border-width: 7px; - border-color: transparent transparent #fff transparent; -} -.ce-settings:before, -.ce-settings:after{ - right: 31px; -} -.ce-toolbar__remove-confirmation:before, -.ce-toolbar__remove-confirmation:after{ - right: 10px; -} -.ce-toolbar__remove-confirmation{ - right: -3px; -} - - -/** -* Plugins settings style helper -*/ -.cdx-plugin-settings--horisontal { - display: -webkit-flex; - display: -moz-flex; - display: -ms-flex; - display: -o-flex; - display: flex; -} - -.cdx-plugin-settings--horisontal .cdx-plugin-settings__item { - flex: 1 0 auto; - text-align: center; -} - -.ce-settings__item, -.ce-toolbar__remove-confirm, -.ce-toolbar__remove-cancel, -.cdx-plugin-settings__item { - padding: 15px; - cursor: pointer; - line-height: 1em; -} - -.ce-settings__item:hover, -.ce-toolbar__remove-cancel:hover, -.cdx-plugin-settings__item:hover { - background: #edf0f5; -} - -.ce-settings.opened, -.ce-toolbar__remove-confirmation.opened{ - display: block; -} - -.ce-settings_plugin{ - border-bottom: 1px solid #e7e9f1; -} - -.ce-settings_plugin:empty{ - display: none; -} - -.ce-settings__item:not(:last-of-type) { - border-bottom: 1px solid #e7e9f1; -} - -.ce-settings__item i, -.cdx-plugin-settings__item i { - min-width: 16px; - margin-right: 1.3em; -} - -.ce-settings__item i::before { - min-width: 16px; - margin: 0; -} - - -/** - * Trash button - */ -.ce-toolbar__remove-btn { - cursor: pointer; -} - -.ce-toolbar__remove-confirm{ - color: #ea5c5c; -} - -.ce-toolbar__remove-confirm:hover{ - background: #e23d3d; - color: #fff; -} - -/** Anchor input */ -.ce-settings__anchor-wrapper:hover { - background: none; -} - -.ce-settings__anchor-input { - max-width: 100%; - border: 0; - outline: none; - padding: 14px 0; - margin: -15px 0; - font-size: inherit; - color: #000; - height: 1em; -} - -.ce-settings__anchor-input::-webkit-input-placeholder {color: rgba(112, 118, 132, 0.5);} -.ce-settings__anchor-input::-moz-placeholder {color: rgba(112, 118, 132, 0.5);} -.ce-settings__anchor-input:-moz-placeholder {color: rgba(112, 118, 132, 0.5);} -.ce-settings__anchor-input:-ms-input-placeholder {color: rgba(112, 118, 132, 0.5);} - -.ce-settings__anchor-hash { - display: inline-block; - background: url('fonts/codex_editor/icon-hash.svg') no-repeat center center; - background-size: contain; - height: 11px; - width: 10px; - vertical-align: middle; -} - -/** -* Overlayed inline toolbar -*/ -.ce-toolbar-inline{ - position: absolute; - left: 0; - top: 0; - z-index: 3; - background: #242533; - border-radius: 3px; - padding: 0 5px; - margin-top: -.5em; - - will-change: transform; - transition: transform .2s cubic-bezier(0.600, -0.280, 0.735, 0.045); - - color: #fff; - - /* hidden by default */ - display: none; -} -.ce-toolbar-inline.opened { - display: block; -} -.ce-toolbar-inline__buttons{ -} -.ce-toolbar-inline__buttons button{ - background: none; - border: 0; - margin: 0 !important; - height: auto !important; - padding: 13px 9px; - line-height: 1em; - color: inherit; - font-size: 12px; - cursor: pointer; -} -.ce-toolbar-inline__buttons button:hover{ - background: #171827; - color: #428bff; -} -.ce-toolbar-inline__actions{ - position: absolute; - left: 0; - top: 0; - bottom: 0; - right: 0; - border-radius: 3px; - background: #242533; - display: none; -} - .ce-toolbar-inline__actions.opened{ - display: block; - } - .ce-toolbar-inline__actions input{ - background: transparent !important; - border : 0 !important; - box-sizing: border-box !important; - padding: 12px; - font-size: 13px; - width: 100%; - color: #fff; - outline: none; - } - - .ce-toolbar-inline__actions input::-moz-placeholder{ color: #afb4c3 !important;} - .ce-toolbar-inline__actions input::-webkit-input-placeholder{ color: #afb4c3 !important;} - - - - -/** -* Base blocks -*/ -.ce-block { - margin: 0 5px; - border-radius: 3px; -} - -.ce-block--focused { - background: #f9f9fb; -} - -.ce-block--feed-mode { - position: relative; -} - -.ce-block--feed-mode:before { - content: '\e81b'; - font-family: "codex_editor"; - display: inline-block; - position: absolute; - left: 17px; - top: 13px; - font-size: 16px; - color: #7d6060; -} - -.ce-block--anchor { - position: relative; -} - -.ce-block--anchor::after { - display: inline-block; - content: "#" attr(data-anchor); - color: #868896; - position: absolute; - left: 17px; - top: 13px; - max-width: 100px; - word-wrap: break-word; - font-size: 12px; - line-height: 1.4em; -} - - - -/** -* Block content holder -*/ -.ce-block__content{ - max-width: 600px; - margin: 0 auto; - padding: 1px; -} -.ce-block--stretched{ - max-width: none; - padding: 0; -} - -.cdx-unavailable-block { - display: block; - margin: 10px 0; - padding: 80px; - background-color: #fff7f7; - text-align: center; - border-radius: 3px; - color: #ce5f5f; -} - -/** -* Typographycs -*/ -.ce-redactor p{ - margin: 0; -} - -/** -* Loading bar class -*/ -.ce-redactor__loader { - background-image: repeating-linear-gradient(-45deg, transparent, transparent 4px, #f5f9ff 4px, #eaedef 8px) !important; - background-size: 56px 56px; - animation: loading-bar 600ms infinite linear; -} - -@keyframes loading-bar { - 100% { background-position: -56% 0 } -} - -/** -* Notifications -*/ - -.cdx-notifications-block { - position: fixed; - bottom: 0; - left: 0; - padding: 15px; -} - - -.cdx-notification__notification-appending div { - animation: notification 100ms infinite ease-in; -} - -@keyframes notification { - - 0% { transform: translateY(20px); } - 100% { transform: translateY(0px); } - -} - - -.cdx-notification { - width: 250px; - margin-top: 15px; - padding: 15px; - background: #fff; - border: 1px solid #e7e9f1; - box-shadow: 0px 2px 5px 0px rgba(16, 23, 49, 0.05); - border-radius: 3px; - font-size: 14px; -} - -.cdx-notification__message { - margin-bottom: 15px; -} - -.cdx-notification__ok-btn, -.cdx-notification__cancel-btn { - padding: 4px 7px; - cursor: pointer; - background: #4584d8; - color: #fff; - min-width: 50px; - display: inline-block; - text-align: center; - border-radius: 2px; -} - -.cdx-notification__cancel-btn { - margin-left: 10px; - background: #dae0e8; - color: inherit; -} - -.cdx-notification__cancel-btn { - background: #cad5e2; -} - -.cdx-notification__ok-btn:hover { - background: #3d77c3; -} - -.cdx-notification__input { - display: block; - width: 100%; - margin-bottom: 15px; - border: none; - outline: none; - padding: 2px 0; - font-size: inherit; - border-bottom: 2px solid #d1d3da; -} - -.cdx-notification-error { - border-left: 4px solid rgb(255, 112, 112); -} - -.cdx-notification-warn { - border-left: 4px solid rgb(79, 146, 247); -} - - -/** -* Mobile viewport styles -* ================================= -*/ -@media all and (max-width: 1000px){ - - .ce-block{ - margin: 0; - } - .ce-block__content, - .ce-toolbar__content - { - padding: 0 25px; - } - - .ce-toolbar { - margin-top: 5px; - } - - .ce-toolbar__actions { - right: 0; - top: -10px; - font-size: 14px; - line-height: 18px; - } - - .ce-toolbar__settings-btn { - display: block; - margin-bottom: 3px; - } - - .ce-toolbar__plus { - margin-left: -25px; - } - - .ce-toolbar__plus, - .ce-toolbar__tools li { - width: 22px; - height: 22px; - } - - .ce-toolbar__tools li i { - line-height: 22px; - } - - .ce-toolbar__tools { - left: 30px; - font-size: 13px; - } - - .ce-block--anchor::after { - display: none; - } - -} \ No newline at end of file diff --git a/build/codex-editor.js b/build/codex-editor.js index c9dbaae4..1f261562 100644 --- a/build/codex-editor.js +++ b/build/codex-editor.js @@ -61,7 +61,7 @@ var CodexEditor = /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 22); +/******/ return __webpack_require__(__webpack_require__.s = 2); /******/ }) /************************************************************************/ /******/ ([ @@ -71,550 +71,27 @@ var CodexEditor = "use strict"; -/** - * Inline toolbar - * - * Contains from tools: - * Bold, Italic, Underline and Anchor - * - * @author Codex Team - * @version 1.0 - */ +exports.createClass = function () { -module.exports = function (inline) { + function defineProperties(target, props) { - var editor = codex.editor; + for (var i = 0; i < props.length; i++) { - inline.buttonsOpened = null; - inline.actionsOpened = null; - inline.wrappersOffset = null; + var descriptor = props[i]; - /** - * 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(); + 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; }; +}();exports.classCallCheck = function (instance, Constructor) { - /** - * @protected - * - * Closes inline toolbar - */ - inline.close = function () { + if (!(instance instanceof Constructor)) { - 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; -}({}); + throw new TypeError('Cannot call a class as a function'); + } +}; /***/ }), /* 1 */ @@ -623,3976 +100,15 @@ module.exports = function (inline) { "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; -}({}); - -/***/ }), -/* 2 */ -/***/ (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; -}({}); - -/***/ }), -/* 3 */ -/***/ (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; -}({}); - -/***/ }), -/* 4 */ -/***/ (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; -}({}); - -/***/ }), -/* 5 */ -/***/ (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; -}({}); - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Codex Editor Content Module - * Works with DOM - * - * @module Codex Editor content module - * - * @author Codex Team - * @version 1.3.13 - * - * @description Module works with Elements that have been appended to the main DOM - */ - -module.exports = function (content) { - - var 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 composeNewBlock_(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 allSiblingsEmpty_(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 wrapPlainTextWithParagraphs(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; -}({}); - -/***/ }), -/* 7 */ -/***/ (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; -}({}); - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Codex Editor Listeners module - * - * @author Codex Team - * @version 1.0 - */ - -/** - * Module-decorator for event listeners assignment - */ -module.exports = function (listeners) { - - var allListeners = []; - - /** - * Search methods - * - * byElement, byType and byHandler returns array of suitable listeners - * one and all takes element, eventType, and handler and returns first (all) suitable listener - * - */ - listeners.search = function () { - - var byElement = function byElement(element, context) { - - var listenersOnElement = []; - - context = context || allListeners; - - for (var i = 0; i < context.length; i++) { - - var listener = context[i]; - - if (listener.element === element) { - - listenersOnElement.push(listener); - } - } - - return listenersOnElement; - }; - - var byType = function byType(eventType, context) { - - var listenersWithType = []; - - context = context || allListeners; - - for (var i = 0; i < context.length; i++) { - - var listener = context[i]; - - if (listener.type === eventType) { - - listenersWithType.push(listener); - } - } - - return listenersWithType; - }; - - var byHandler = function byHandler(handler, context) { - - var listenersWithHandler = []; - - context = context || allListeners; - - for (var i = 0; i < context.length; i++) { - - var listener = context[i]; - - if (listener.handler === handler) { - - listenersWithHandler.push(listener); - } - } - - return listenersWithHandler; - }; - - var one = function one(element, eventType, handler) { - - var result = allListeners; - - if (element) result = byElement(element, result); - - if (eventType) result = byType(eventType, result); - - if (handler) result = byHandler(handler, result); - - return result[0]; - }; - - var all = function all(element, eventType, handler) { - - var result = allListeners; - - if (element) result = byElement(element, result); - - if (eventType) result = byType(eventType, result); - - if (handler) result = byHandler(handler, result); - - return result; - }; - - return { - byElement: byElement, - byType: byType, - byHandler: byHandler, - one: one, - all: all - }; - }(); - - listeners.add = function (element, eventType, handler, isCapture) { - - element.addEventListener(eventType, handler, isCapture); - - var data = { - element: element, - type: eventType, - handler: handler - }; - - var alreadyAddedListener = listeners.search.one(element, eventType, handler); - - if (!alreadyAddedListener) { - - allListeners.push(data); - } - }; - - listeners.remove = function (element, eventType, handler) { - - element.removeEventListener(eventType, handler); - - var existingListeners = listeners.search.all(element, eventType, handler); - - for (var i = 0; i < existingListeners.length; i++) { - - var index = allListeners.indexOf(existingListeners[i]); - - if (index > 0) { - - allListeners.splice(index, 1); - } - } - }; - - listeners.removeAll = function () { - - allListeners.map(function (current) { - - listeners.remove(current.element, current.type, current.handler); - }); - }; - - listeners.get = function (element, eventType, handler) { - - return listeners.search.all(element, eventType, handler); - }; - - return listeners; -}({}); - -/***/ }), -/* 9 */ -/***/ (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; -}({}); - -/***/ }), -/* 10 */ -/***/ (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; -}({}); - -/***/ }), -/* 11 */ -/***/ (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; -}({}); - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Codex Editor Renderer Module - * - * @author Codex Team - * @version 1.0 - */ - -module.exports = function (renderer) { - - var editor = codex.editor; - - /** - * Asyncronously parses input JSON to redactor blocks - */ - renderer.makeBlocksFromData = function () { - - /** - * If redactor is empty, add first paragraph to start writing - */ - if (editor.core.isEmpty(editor.state.blocks) || !editor.state.blocks.items.length) { - - editor.ui.addInitialBlock(); - return; - } - - Promise.resolve() - - /** First, get JSON from state */ - .then(function () { - - return editor.state.blocks; - }) - - /** Then, start to iterate they */ - .then(editor.renderer.appendBlocks) - - /** Write log if something goes wrong */ - .catch(function (error) { - - editor.core.log('Error while parsing JSON: %o', 'error', error); - }); - }; - - /** - * Parses JSON to blocks - * @param {object} data - * @return Primise -> nodeList - */ - renderer.appendBlocks = function (data) { - - var blocks = data.items; - - /** - * Sequence of one-by-one blocks appending - * Uses to save blocks order after async-handler - */ - var nodeSequence = Promise.resolve(); - - for (var index = 0; index < blocks.length; index++) { - - /** Add node to sequence at specified index */ - editor.renderer.appendNodeAtIndex(nodeSequence, blocks, index); - } - }; - - /** - * Append node at specified index - */ - renderer.appendNodeAtIndex = function (nodeSequence, blocks, index) { - - /** We need to append node to sequence */ - nodeSequence - - /** first, get node async-aware */ - .then(function () { - - return editor.renderer.getNodeAsync(blocks, index); - }) - - /** - * second, compose editor-block from JSON object - */ - .then(editor.renderer.createBlockFromData) - - /** - * now insert block to redactor - */ - .then(function (blockData) { - - /** - * blockData has 'block', 'type' and 'stretched' information - */ - editor.content.insertBlock(blockData); - - /** Pass created block to next step */ - return blockData.block; - }) - - /** Log if something wrong with node */ - .catch(function (error) { - - editor.core.log('Node skipped while parsing because %o', 'error', error); - }); - }; - - /** - * Asynchronously returns block data from blocksList by index - * @return Promise to node - */ - renderer.getNodeAsync = function (blocksList, index) { - - return Promise.resolve().then(function () { - - return { - tool: blocksList[index], - position: index - }; - }); - }; - - /** - * Creates editor block by JSON-data - * - * @uses render method of each plugin - * - * @param {Object} toolData.tool - * { header : { - * text: '', - * type: 'H3', ... - * } - * } - * @param {Number} toolData.position - index in input-blocks array - * @return {Object} with type and Element - */ - renderer.createBlockFromData = function (toolData) { - - /** New parser */ - var block, - tool = toolData.tool, - pluginName = tool.type; - - /** Get first key of object that stores plugin name */ - // for (var pluginName in blockData) break; - - /** Check for plugin existance */ - if (!editor.tools[pluginName]) { - - throw Error('Plugin \xAB' + pluginName + '\xBB not found'); - } - - /** Check for plugin having render method */ - if (typeof editor.tools[pluginName].render != 'function') { - - throw Error('Plugin \xAB' + pluginName + '\xBB must have \xABrender\xBB method'); - } - - if (editor.tools[pluginName].available === false) { - - block = editor.draw.unavailableBlock(); - - block.innerHTML = editor.tools[pluginName].loadingMessage; - - /** - * Saver will extract data from initial block data by position in array - */ - block.dataset.inputPosition = toolData.position; - } else { - - /** New Parser */ - block = editor.tools[pluginName].render(tool.data); - } - - /** is first-level block stretched */ - var stretched = editor.tools[pluginName].isStretched || false; - - /** Retrun type and block */ - return { - type: pluginName, - block: block, - stretched: stretched - }; - }; - - return renderer; -}({}); - -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Codex Sanitizer - */ - -module.exports = function (sanitizer) { - - /** HTML Janitor library */ - var janitor = __webpack_require__(24); - - /** Codex Editor */ - var editor = codex.editor; - - sanitizer.prepare = function () { - - if (editor.settings.sanitizer && !editor.core.isEmpty(editor.settings.sanitizer)) { - - Config.CUSTOM = editor.settings.sanitizer; - } - }; - - /** - * Basic config - */ - var Config = { - - /** User configuration */ - CUSTOM: null, - - BASIC: { - - tags: { - p: {}, - a: { - href: true, - target: '_blank', - rel: 'nofollow' - } - } - } - }; - - sanitizer.Config = Config; - - /** - * - * @param userCustomConfig - * @returns {*} - * @private - * - * @description If developer uses editor's API, then he can customize sane restrictions. - * Or, sane config can be defined globally in editors initialization. That config will be used everywhere - * At least, if there is no config overrides, that API uses BASIC Default configation - */ - var init_ = function init_(userCustomConfig) { - - var configuration = userCustomConfig || Config.CUSTOM || Config.BASIC; - - return new janitor(configuration); - }; - - /** - * Cleans string from unwanted tags - * @protected - * @param {String} dirtyString - taint string - * @param {Object} customConfig - allowed tags - */ - sanitizer.clean = function (dirtyString, customConfig) { - - var janitorInstance = init_(customConfig); - - return janitorInstance.clean(dirtyString); - }; - - return sanitizer; -}({}); - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Codex Editor Saver - * - * @author Codex Team - * @version 1.1.0 - */ - -module.exports = function (saver) { - - var editor = codex.editor; - - /** - * @public - * Save blocks - */ - saver.save = function () { - - /** Save html content of redactor to memory */ - editor.state.html = editor.nodes.redactor.innerHTML; - - /** Clean jsonOutput state */ - editor.state.jsonOutput = []; - - return saveBlocks(editor.nodes.redactor.childNodes); - }; - - /** - * @private - * Save each block data - * - * @param blocks - * @returns {Promise.} - */ - var saveBlocks = function saveBlocks(blocks) { - - var data = []; - - for (var index = 0; index < blocks.length; index++) { - - data.push(getBlockData(blocks[index])); - } - - return Promise.all(data).then(makeOutput).catch(editor.core.log); - }; - - /** Save and validate block data */ - var getBlockData = function getBlockData(block) { - - return saveBlockData(block).then(validateBlockData).catch(editor.core.log); - }; - - /** - * @private - * Call block`s plugin save method and return saved data - * - * @param block - * @returns {Object} - */ - var saveBlockData = function saveBlockData(block) { - - var pluginName = block.dataset.tool; - - /** Check for plugin existence */ - if (!editor.tools[pluginName]) { - - editor.core.log('Plugin \xAB' + pluginName + '\xBB not found', 'error'); - return { data: null, pluginName: null }; - } - - /** Check for plugin having save method */ - if (typeof editor.tools[pluginName].save !== 'function') { - - editor.core.log('Plugin \xAB' + pluginName + '\xBB must have save method', 'error'); - return { data: null, pluginName: null }; - } - - /** Result saver */ - var blockContent = block.childNodes[0], - pluginsContent = blockContent.childNodes[0], - position = pluginsContent.dataset.inputPosition; - - /** If plugin wasn't available then return data from cache */ - if (editor.tools[pluginName].available === false) { - - return Promise.resolve({ data: codex.editor.state.blocks.items[position].data, pluginName: pluginName }); - } - - return Promise.resolve(pluginsContent).then(editor.tools[pluginName].save).then(function (data) { - return Object({ data: data, pluginName: pluginName }); - }); - }; - - /** - * Call plugin`s validate method. Return false if validation failed - * - * @param data - * @param pluginName - * @returns {Object|Boolean} - */ - var validateBlockData = function validateBlockData(_ref) { - var data = _ref.data, - pluginName = _ref.pluginName; - - - if (!data || !pluginName) { - - return false; - } - - if (editor.tools[pluginName].validate) { - - var result = editor.tools[pluginName].validate(data); - - /** - * Do not allow invalid data - */ - if (!result) { - - return false; - } - } - - return { data: data, pluginName: pluginName }; - }; - - /** - * Compile article output - * - * @param savedData - * @returns {{time: number, version, items: (*|Array)}} - */ - var makeOutput = function makeOutput(savedData) { - - savedData = savedData.filter(function (blockData) { - return blockData; - }); - - var items = savedData.map(function (blockData) { - return Object({ type: blockData.pluginName, data: blockData.data }); - }); - - editor.state.jsonOutput = items; - - return { - id: editor.state.blocks.id || null, - time: +new Date(), - version: editor.version, - items: items - }; - }; - - return saver; -}({}); - -/***/ }), -/* 15 */ -/***/ (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; -}({}); - -/***/ }), -/* 16 */ -/***/ (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; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * @module eventDispatcher - * - * Has two important methods: - * - {Function} on - appends subscriber to the event. If event doesn't exist - creates new one - * - {Function} emit - fires all subscribers with data - * - * @version 1.0.0 - */ -var Events = function () { - _createClass(Events, [{ - key: "state", - - - /** - * @param Editor - * @param Editor.modules {@link CodexEditor#moduleInstances} - * @param Editor.config {@link CodexEditor#configuration} - */ - set: function set(Editor) { - - this.Editor = Editor; - } - - /** - * @constructor - * - * @property {Object} subscribers - all subscribers grouped by event name - */ - - }]); - - function Events() { - _classCallCheck(this, Events); - - this.subscribers = {}; - this.Editor = null; - } - - /** - * @param {String} eventName - event name - * @param {Function} callback - subscriber - */ - - - _createClass(Events, [{ - key: "on", - value: function on(eventName, callback) { - - if (!(eventName in this.subscribers)) { - - this.subscribers[eventName] = []; - } - - // group by events - this.subscribers[eventName].push(callback); - } - - /** - * @param {String} eventName - event name - * @param {Object} data - subscribers get this data when they were fired - */ - - }, { - key: "emit", - value: function emit(eventName, data) { - - this.subscribers[eventName].reduce(function (previousData, currentHandler) { - - var newData = currentHandler(previousData); - - return newData ? newData : previousData; - }, data); - } - - /** - * Destroyer - */ - - }, { - key: "destroy", - value: function destroy() { - - this.Editor = null; - this.subscribers = null; - } - }]); - - return Events; -}(); - -Events.displayName = "Events"; - - -module.exports = Events; - -/***/ }), -/* 17 */ -/***/ (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; }; }(); /** - * DOM manipulations - */ - - -var _dom = __webpack_require__(18); - -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"); } } - -/** - * - * «Toolbar» is the node that moves up/down over current block - * - * ______________________________________ Toolbar ____________________________________________ - * | | - * | ..................... Content .................... ......... Block Actions .......... | - * | . . . . | - * | . . . [Open Settings] [Remove Block] . | - * | . [Plus Button] [Toolbox: {Tool1}, {Tool2}] . . . | - * | . . . [Settings Panel] . | - * | .................................................. .................................. | - * | | - * |___________________________________________________________________________________________| - * - * - * Toolbox — its an Element contains tools buttons. Can be shown by Plus Button. - * - * _______________ Toolbox _______________ - * | | - * | [Header] [Image] [List] [Quote] ... | - * |_______________________________________| - * - * - * Settings Panel — is an Element with block settings: - * - * ____ Settings Panel ____ - * | ...................... | - * | . Tool Settings . | - * | ...................... | - * | . Default Settings . | - * | ...................... | - * |________________________| - * - * - * @class - * @classdesc Toolbar module - * - * @property {Object} nodes - * @property {Element} nodes.wrapper - Toolbar main element - * @property {Element} nodes.content - Zone with Plus button and toolbox. - * @property {Element} nodes.actions - Zone with Block Settings and Remove Button - * @property {Element} nodes.plusButton - Button that opens or closes Toolbox - * @property {Element} nodes.toolbox - Container for tools - * @property {Element} nodes.settingsToggler - open/close Settings Panel button - * @property {Element} nodes.removeBlockButton - Remove Block button - * @property {Element} nodes.settings - Settings Panel - * @property {Element} nodes.pluginSettings - Plugin Settings section of Settings Panel - * @property {Element} nodes.defaultSettings - Default Settings section of Settings Panel - */ -var Toolbar = function () { - - /** - * @constructor - */ - function Toolbar() { - _classCallCheck(this, Toolbar); - - this.Editor = null; - - this.nodes = { - wrapper: null, - content: null, - actions: null, - - // Content Zone - plusButton: null, - toolbox: null, - - // Actions Zone - settingsToggler: null, - removeBlockButton: null, - settings: null, - - // Settings Zone: Plugin Settings and Default Settings - pluginSettings: null, - defaultSettings: null - }; - - this.CSS = { - toolbar: 'ce-toolbar', - content: 'ce-toolbar__content', - actions: 'ce-toolbar__actions', - - // Content Zone - toolbox: 'ce-toolbar__toolbox', - plusButton: 'ce-toolbar__plus', - - // Actions Zone - settingsToggler: 'ce-toolbar__settings-btn', - removeBlockButton: 'ce-toolbar__remove-btn', - - // Settings Panel - settings: 'ce-settings', - defaultSettings: 'ce-settings_default', - pluginSettings: 'ce-settings_plugin' - }; - } - - /** - * Editor modules setter - * @param {object} Editor - available editor modules - */ - - - _createClass(Toolbar, [{ - key: 'make', - - - /** - * Makes toolbar - */ - value: function make() { - var _this = this; - - this.nodes.wrapper = _dom2.default.make('div', this.CSS.toolbar); - - /** - * Make Content Zone and Actions Zone - */ - ['content', 'actions'].forEach(function (el) { - - _this.nodes[el] = _dom2.default.make('div', _this.CSS[el]); - _dom2.default.append(_this.nodes.wrapper, _this.nodes[el]); - }); - - /** - * Fill Content Zone: - * - Plus Button - * - Toolbox - */ - ['plusButton', 'toolbox'].forEach(function (el) { - - _this.nodes[el] = _dom2.default.make('div', _this.CSS[el]); - _dom2.default.append(_this.nodes.content, _this.nodes[el]); - }); - - /** - * Fill Actions Zone: - * - Settings Toggler - * - Remove Block Button - * - Settings Panel - */ - this.nodes.settingsToggler = _dom2.default.make('span', this.CSS.settingsToggler); - this.nodes.removeBlockButton = this.makeRemoveBlockButton(); - - _dom2.default.append(this.nodes.actions, [this.nodes.settingsToggler, this.nodes.removeBlockButton]); - - /** - * Make and append Settings Panel - */ - this.makeBlockSettingsPanel(); - - /** - * Append toolbar to the Editor - */ - _dom2.default.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper); - } - - /** - * Panel with block settings with 2 sections: - * - * @return {Element} - */ - - }, { - key: 'makeBlockSettingsPanel', - value: function makeBlockSettingsPanel() { - - this.nodes.settings = _dom2.default.make('div', this.CSS.settings); - - this.nodes.pluginSettings = _dom2.default.make('div', this.CSS.pluginSettings); - this.nodes.defaultSettings = _dom2.default.make('div', this.CSS.defaultSettings); - - _dom2.default.append(this.nodes.settings, [this.nodes.pluginSettings, this.nodes.defaultSettings]); - _dom2.default.append(this.nodes.actions, this.nodes.settings); - } - - /** - * Makes Remove Block button, and confirmation panel - * @return {Element} wrapper with button and panel - */ - - }, { - key: 'makeRemoveBlockButton', - value: function makeRemoveBlockButton() { - - /** - * @todo add confirmation panel and handlers - * @see {@link settings#makeRemoveBlockButton} - */ - return _dom2.default.make('span', this.CSS.removeBlockButton); - } - }, { - key: 'state', - set: function set(Editor) { - - this.Editor = Editor; - } - }]); - - return Toolbar; -}(); - -Toolbar.displayName = 'Toolbar'; - - -module.exports = Toolbar; - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -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; }; }(); - -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - /** * DOM manupulations helper */ -var Dom = function () { +module.exports = function () { function Dom() { - _classCallCheck(this, Dom); + __webpack_require__(0).classCallCheck(this, Dom); } - _createClass(Dom, null, [{ + __webpack_require__(0).createClass(Dom, null, [{ key: "make", @@ -4611,7 +127,7 @@ var Dom = function () { if (Array.isArray(classNames)) { var _el$classList; - (_el$classList = el.classList).add.apply(_el$classList, _toConsumableArray(classNames)); + (_el$classList = el.classList).add.apply(_el$classList, __webpack_require__(0).toConsumableArray(classNames)); } else if (classNames) { el.classList.add(classNames); @@ -4692,147 +208,749 @@ var Dom = function () { return Dom; }(); -Dom.displayName = "Dom"; -exports.default = Dom; -; +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/** + * Codex Editor + * + * Short Description (눈_눈;) + * @version 2.0.0 + * + * How to start? + * Example: + * new CodexEditor({ + * holderId : 'codex-editor', + * initialBlock : 'paragraph', + * placeholder : 'Write your story....', + * tools: { + * quote: Quote, + * anotherTool : AnotherTool + * }, + * toolsConfig: { + * quote: { + * iconClassname : 'quote-icon', + * displayInToolbox : true, + * enableLineBreaks : true + * }, + * anotherTool: { + * iconClassname : 'tool-icon' + * } + * } + * }); + * + * - tools is an object: { + * pluginName: PluginClass, + * ..... + * } + * - toolsConfig is an additional configuration that uses Codex Editor API + * iconClassname - CSS classname of toolbox icon + * displayInToolbox - if you want to see your Tool in toolbox hided in "plus" button, than set "True". By default : "False" + * 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 + * + * @author CodeX-Team + * + */ + +/** + * @typedef {CodexEditor} CodexEditor - editor class + */ + +/** + * @typedef {Object} EditorConfig + * @property {String} holderId - Element to append Editor + * ... + */ + + + +/** + * Require Editor modules places in components/modules dir + */ +// eslint-disable-next-line + +var modules = ["events.js","toolbar.js","tools.js","ui.js"].map(function (module) { + return __webpack_require__(3)("./" + module); +}); + +/** + * @class + * + * @classdesc CodeX Editor base class + * + * @property this.config - all settings + * @property this.moduleInstances - constructed editor components + * + * @type {CodexEditor} + */ +module.exports = function () { + __webpack_require__(0).createClass(CodexEditor, null, [{ + key: 'version', + + + /** Editor version */ + get: function get() { + + return "2.0.0"; + } + + /** + * @param {EditorConfig} config - user configuration + * + */ + + }]); + + function CodexEditor(config) { + var _this = this; + + __webpack_require__(0).classCallCheck(this, CodexEditor); + + /** + * Configuration object + */ + this.config = {}; + + /** + * Editor Components + */ + this.moduleInstances = {}; + + Promise.resolve().then(function () { + + _this.configuration = config; + }).then(function () { + return _this.init(); + }).then(function () { + return _this.start(); + }).then(function () { + + console.log('CodeX Editor is ready'); + }).catch(function (error) { + + console.log('CodeX Editor does not ready beecause of %o', error); + }); + } + + /** + * Setting for configuration + * @param {Object} config + */ + + + __webpack_require__(0).createClass(CodexEditor, [{ + key: 'init', + + + /** + * Initializes modules: + * - make and save instances + * - configure + */ + value: function init() { + + /** + * Make modules instances and save it to the @property this.moduleInstances + */ + this.constructModules(); + + /** + * Modules configuration + */ + this.configureModules(); + } + + /** + * Make modules instances and save it to the @property this.moduleInstances + */ + + }, { + key: 'constructModules', + value: function constructModules() { + var _this2 = this; + + modules.forEach(function (Module) { + + try { + + /** + * We use class name provided by displayName property + * + * On build, Babel will transform all Classes to the Functions so, name will always be 'Function' + * To prevent this, we use 'babel-plugin-class-display-name' plugin + * @see https://www.npmjs.com/package/babel-plugin-class-display-name + */ + + _this2.moduleInstances[Module.displayName] = new Module({ + config: _this2.configuration + }); + } catch (e) { + + console.log('Module %o skipped because %o', Module, e); + } + }); + } + + /** + * Modules instances configuration: + * - pass other modules to the 'state' property + * - ... + */ + + }, { + key: 'configureModules', + value: function configureModules() { + + for (var name in this.moduleInstances) { + + /** + * Module does not need self-instance + */ + this.moduleInstances[name].state = this.getModulesDiff(name); + } + } + + /** + * Return modules without passed name + */ + + }, { + key: 'getModulesDiff', + value: function getModulesDiff(name) { + + var diff = {}; + + for (var moduleName in this.moduleInstances) { + + /** + * Skip module with passed name + */ + if (moduleName === name) { + + continue; + } + diff[moduleName] = this.moduleInstances[moduleName]; + } + + return diff; + } + + /** + * Start Editor! + * + * @return {Promise} + */ + + }, { + key: 'start', + value: function start() { + + var prepareDecorator = function prepareDecorator(module) { + return module.prepare(); + }; + + return Promise.resolve().then(prepareDecorator(this.moduleInstances.UI)).then(prepareDecorator(this.moduleInstances.Tools)).catch(function (error) { + + console.log('Error occured', error); + }); + } + }, { + key: 'configuration', + set: function set() { + var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + + this.config.holderId = config.holderId; + this.config.placeholder = config.placeholder || 'write your story...'; + this.config.sanitizer = config.sanitizer || { + p: true, + b: true, + a: true + }; + + this.config.hideToolbar = config.hideToolbar ? config.hideToolbar : false; + this.config.tools = config.tools || {}; + this.config.toolsConfig = config.toolsConfig || {}; + } + + /** + * Returns private property + * @returns {{}|*} + */ + , + get: function get() { + + return this.config; + } + }]); + + return CodexEditor; +}(); + +// module.exports = (function (editor) { +// +// 'use strict'; +// +// editor.version = VERSION; +// editor.scriptPrefix = 'cdx-script-'; +// +// var init = function () { +// +// editor.core = require('./modules/core'); +// editor.tools = require('./modules/tools'); +// editor.ui = require('./modules/ui'); +// editor.transport = require('./modules/transport'); +// editor.renderer = require('./modules/renderer'); +// editor.saver = require('./modules/saver'); +// editor.content = require('./modules/content'); +// editor.toolbar = require('./modules/toolbar/toolbar'); +// editor.callback = require('./modules/callbacks'); +// editor.draw = require('./modules/draw'); +// editor.caret = require('./modules/caret'); +// editor.notifications = require('./modules/notifications'); +// editor.parser = require('./modules/parser'); +// editor.sanitizer = require('./modules/sanitizer'); +// editor.listeners = require('./modules/listeners'); +// editor.destroyer = require('./modules/destroyer'); +// editor.paste = require('./modules/paste'); +// +// }; +// +// /** +// * @public +// * holds initial settings +// */ +// editor.settings = { +// tools : ['paragraph', 'header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'], +// holderId : 'codex-editor', +// +// // Type of block showing on empty editor +// initialBlockPlugin: 'paragraph' +// }; +// +// /** +// * public +// * +// * Static nodes +// */ +// editor.nodes = { +// holder : null, +// wrapper : null, +// toolbar : null, +// inlineToolbar : { +// wrapper : null, +// buttons : null, +// actions : null +// }, +// toolbox : null, +// notifications : null, +// plusButton : null, +// showSettingsButton: null, +// showTrashButton : null, +// blockSettings : null, +// pluginSettings : null, +// defaultSettings : null, +// toolbarButtons : {}, // { type : DomEl, ... } +// redactor : null +// }; +// +// /** +// * @public +// * +// * Output state +// */ +// editor.state = { +// jsonOutput : [], +// blocks : [], +// inputs : [] +// }; +// +// /** +// * @public +// * Editor plugins +// */ +// editor.tools = {}; +// +// editor.start = function (userSettings) { +// +// init(); +// +// editor.core.prepare(userSettings) +// +// // If all ok, make UI, bind events and parse initial-content +// .then(editor.ui.prepare) +// .then(editor.tools.prepare) +// .then(editor.sanitizer.prepare) +// .then(editor.paste.prepare) +// .then(editor.transport.prepare) +// .then(editor.renderer.makeBlocksFromData) +// .then(editor.ui.saveInputs) +// .catch(function (error) { +// +// editor.core.log('Initialization failed with error: %o', 'warn', error); +// +// }); +// +// }; +// +// return editor; +// +// })({}); /***/ }), -/* 19 */ +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +var map = { + "./events.js": 4, + "./toolbar.js": 5, + "./tools.js": 6, + "./ui.js": 8 +}; +function webpackContext(req) { + return __webpack_require__(webpackContextResolve(req)); +}; +function webpackContextResolve(req) { + var id = map[req]; + if(!(id + 1)) // check for number or string + throw new Error("Cannot find module '" + req + "'."); + return id; +}; +webpackContext.keys = function webpackContextKeys() { + return Object.keys(map); +}; +webpackContext.resolve = webpackContextResolve; +module.exports = webpackContext; +webpackContext.id = 3; + +/***/ }), +/* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** - * Codex Editor toolbar module + * @module eventDispatcher * - * Contains: - * - Inline toolbox - * - Toolbox within plus button - * - Settings section + * Has two important methods: + * - {Function} on - appends subscriber to the event. If event doesn't exist - creates new one + * - {Function} emit - fires all subscribers with data * - * @author Codex Team - * @version 1.0 + * @version 1.0.0 */ +var Events = function () { + __webpack_require__(0).createClass(Events, [{ + key: "state", -module.exports = function (toolbar) { - var editor = codex.editor; + /** + * @param Editor + * @param Editor.modules {@link CodexEditor#moduleInstances} + * @param Editor.config {@link CodexEditor#configuration} + */ + set: function set(Editor) { - toolbar.settings = __webpack_require__(1); - toolbar.inline = __webpack_require__(0); - toolbar.toolbox = __webpack_require__(2); + this.Editor = Editor; + } + + /** + * @constructor + * + * @property {Object} subscribers - all subscribers grouped by event name + */ + + }]); + + function Events() { + __webpack_require__(0).classCallCheck(this, Events); + + this.subscribers = {}; + this.Editor = null; + } /** - * Margin between focused node and toolbar + * @param {String} eventName - event name + * @param {Function} callback - subscriber */ - toolbar.defaultToolbarHeight = 49; - toolbar.defaultOffset = 34; - toolbar.opened = false; + __webpack_require__(0).createClass(Events, [{ + key: "on", + value: function on(eventName, callback) { - toolbar.current = null; + if (!(eventName in this.subscribers)) { - /** - * @protected - */ - toolbar.open = function () { + this.subscribers[eventName] = []; + } - if (editor.hideToolbar) { - - return; + // group by events + this.subscribers[eventName].push(callback); } - var toolType = editor.content.currentNode.dataset.tool; + /** + * @param {String} eventName - event name + * @param {Object} data - subscribers get this data when they were fired + */ - if (!editor.tools[toolType] || !editor.tools[toolType].makeSettings) { + }, { + key: "emit", + value: function emit(eventName, data) { - editor.nodes.showSettingsButton.classList.add('hide'); - } else { + this.subscribers[eventName].reduce(function (previousData, currentHandler) { - editor.nodes.showSettingsButton.classList.remove('hide'); + var newData = currentHandler(previousData); + + return newData ? newData : previousData; + }, data); } - editor.nodes.toolbar.classList.add('opened'); - this.opened = true; - }; + /** + * Destroyer + */ - /** - * @protected - */ - toolbar.close = function () { + }, { + key: "destroy", + value: function destroy() { - 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'); + this.Editor = null; + this.subscribers = null; } + }]); - /** Close toolbox when toolbar is not displayed */ - editor.toolbar.toolbox.close(); - editor.toolbar.settings.close(); - }; + return Events; +}(); - toolbar.toggle = function () { +Events.displayName = "Events"; - 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; -}({}); +module.exports = Events; /***/ }), -/* 20 */ +/* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +/* WEBPACK VAR INJECTION */(function($) { + +/** + * + * «Toolbar» is the node that moves up/down over current block + * + * ______________________________________ Toolbar ____________________________________________ + * | | + * | ..................... Content .................... ......... Block Actions .......... | + * | . . . . | + * | . . . [Open Settings] [Remove Block] . | + * | . [Plus Button] [Toolbox: {Tool1}, {Tool2}] . . . | + * | . . . [Settings Panel] . | + * | .................................................. .................................. | + * | | + * |___________________________________________________________________________________________| + * + * + * Toolbox — its an Element contains tools buttons. Can be shown by Plus Button. + * + * _______________ Toolbox _______________ + * | | + * | [Header] [Image] [List] [Quote] ... | + * |_______________________________________| + * + * + * Settings Panel — is an Element with block settings: + * + * ____ Settings Panel ____ + * | ...................... | + * | . Tool Settings . | + * | ...................... | + * | . Default Settings . | + * | ...................... | + * |________________________| + * + * + * @class + * @classdesc Toolbar module + * + * @property {Object} nodes + * @property {Element} nodes.wrapper - Toolbar main element + * @property {Element} nodes.content - Zone with Plus button and toolbox. + * @property {Element} nodes.actions - Zone with Block Settings and Remove Button + * @property {Element} nodes.plusButton - Button that opens or closes Toolbox + * @property {Element} nodes.toolbox - Container for tools + * @property {Element} nodes.settingsToggler - open/close Settings Panel button + * @property {Element} nodes.removeBlockButton - Remove Block button + * @property {Element} nodes.settings - Settings Panel + * @property {Element} nodes.pluginSettings - Plugin Settings section of Settings Panel + * @property {Element} nodes.defaultSettings - Default Settings section of Settings Panel + */ +var Toolbar = function () { + + /** + * @constructor + */ + function Toolbar() { + __webpack_require__(0).classCallCheck(this, Toolbar); + + this.Editor = null; + + this.nodes = { + wrapper: null, + content: null, + actions: null, + + // Content Zone + plusButton: null, + toolbox: null, + + // Actions Zone + settingsToggler: null, + removeBlockButton: null, + settings: null, + + // Settings Zone: Plugin Settings and Default Settings + pluginSettings: null, + defaultSettings: null + }; + + this.CSS = { + toolbar: 'ce-toolbar', + content: 'ce-toolbar__content', + actions: 'ce-toolbar__actions', + + // Content Zone + toolbox: 'ce-toolbar__toolbox', + plusButton: 'ce-toolbar__plus', + + // Actions Zone + settingsToggler: 'ce-toolbar__settings-btn', + removeBlockButton: 'ce-toolbar__remove-btn', + + // Settings Panel + settings: 'ce-settings', + defaultSettings: 'ce-settings_default', + pluginSettings: 'ce-settings_plugin' + }; + } + + /** + * Editor modules setter + * @param {object} Editor - available editor modules + */ -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; }; }(); + __webpack_require__(0).createClass(Toolbar, [{ + key: 'make', -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + /** + * Makes toolbar + */ + value: function make() { + var _this = this; + + this.nodes.wrapper = $.make('div', this.CSS.toolbar); + + /** + * Make Content Zone and Actions Zone + */ + ['content', 'actions'].forEach(function (el) { + + _this.nodes[el] = $.make('div', _this.CSS[el]); + $.append(_this.nodes.wrapper, _this.nodes[el]); + }); + + /** + * Fill Content Zone: + * - Plus Button + * - Toolbox + */ + ['plusButton', 'toolbox'].forEach(function (el) { + + _this.nodes[el] = $.make('div', _this.CSS[el]); + $.append(_this.nodes.content, _this.nodes[el]); + }); + + /** + * Fill Actions Zone: + * - Settings Toggler + * - Remove Block Button + * - Settings Panel + */ + this.nodes.settingsToggler = $.make('span', this.CSS.settingsToggler); + this.nodes.removeBlockButton = this.makeRemoveBlockButton(); + + $.append(this.nodes.actions, [this.nodes.settingsToggler, this.nodes.removeBlockButton]); + + /** + * Make and append Settings Panel + */ + this.makeBlockSettingsPanel(); + + /** + * Append toolbar to the Editor + */ + $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper); + } + + /** + * Panel with block settings with 2 sections: + * + * @return {Element} + */ + + }, { + key: 'makeBlockSettingsPanel', + value: function makeBlockSettingsPanel() { + + this.nodes.settings = $.make('div', this.CSS.settings); + + this.nodes.pluginSettings = $.make('div', this.CSS.pluginSettings); + this.nodes.defaultSettings = $.make('div', this.CSS.defaultSettings); + + $.append(this.nodes.settings, [this.nodes.pluginSettings, this.nodes.defaultSettings]); + $.append(this.nodes.actions, this.nodes.settings); + } + + /** + * Makes Remove Block button, and confirmation panel + * @return {Element} wrapper with button and panel + */ + + }, { + key: 'makeRemoveBlockButton', + value: function makeRemoveBlockButton() { + + /** + * @todo add confirmation panel and handlers + * @see {@link settings#makeRemoveBlockButton} + */ + return $.make('span', this.CSS.removeBlockButton); + } + }, { + key: 'state', + set: function set(Editor) { + + this.Editor = Editor; + } + }]); + + return Toolbar; +}(); + +Toolbar.displayName = 'Toolbar'; + + +module.exports = Toolbar; +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(_) { /** * @module Codex Editor Tools Submodule @@ -4868,10 +986,9 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons * @property {Object} toolsClasses - all classes * @property {EditorConfig} config - Editor config */ -var util = __webpack_require__(25); var Tools = function () { - _createClass(Tools, [{ + __webpack_require__(0).createClass(Tools, [{ key: 'available', @@ -4936,7 +1053,7 @@ var Tools = function () { function Tools(_ref) { var config = _ref.config; - _classCallCheck(this, Tools); + __webpack_require__(0).classCallCheck(this, Tools); this.config = config; @@ -4951,13 +1068,11 @@ var Tools = function () { */ - _createClass(Tools, [{ + __webpack_require__(0).createClass(Tools, [{ key: 'prepare', value: function prepare() { var _this = this; - var self = this; - if (!this.config.hasOwnProperty('tools')) { return Promise.reject("Can't start without tools"); @@ -4984,7 +1099,7 @@ var Tools = function () { /** * to see how it works {@link Util#sequence} */ - return util.sequence(sequenceData, function (data) { + return _.sequence(sequenceData, function (data) { _this.success(data); }, function (data) { @@ -5064,23 +1179,106 @@ Tools.displayName = 'Tools'; module.exports = Tools; +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(7))) /***/ }), -/* 21 */ +/* 7 */ /***/ (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 Util + */ +module.exports = function () { + function Util() { + __webpack_require__(0).classCallCheck(this, Util); + } -var _dom = __webpack_require__(18); + __webpack_require__(0).createClass(Util, null, [{ + key: "sequence", -var _dom2 = _interopRequireDefault(_dom); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** + * @typedef {Object} ChainData + * @property {Object} data - data that will be passed to the success or fallback + * @property {Function} function - function's that must be called asynchronically + */ -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + /** + * Fires a promise sequence asyncronically + * + * @param {Object[]} chains - list or ChainData's + * @param {Function} success - success callback + * @param {Function} fallback - callback that fires in case of errors + * + * @return {Promise} + */ + value: function sequence(chains, success, fallback) { + + return new Promise(function (resolve) { + + /** + * pluck each element from queue + * First, send resolved Promise as previous value + * Each plugins "prepare" method returns a Promise, that's why + * reduce current element will not be able to continue while can't get + * a resolved Promise + */ + chains.reduce(function (previousValue, currentValue, iteration) { + + return previousValue.then(function () { + return waitNextBlock(currentValue, success, fallback); + }).then(function () { + + // finished + if (iteration === chains.length - 1) { + + resolve(); + } + }); + }, Promise.resolve()); + }); + + /** + * Decorator + * + * @param {ChainData} chainData + * + * @param {Function} successCallback + * @param {Function} fallbackCallback + * + * @return {Promise} + */ + function waitNextBlock(chainData, successCallback, fallbackCallback) { + + return new Promise(function (resolve) { + + chainData.function().then(function () { + + successCallback(chainData.data); + }).then(resolve).catch(function () { + + fallbackCallback(chainData.data); + + // anyway, go ahead even it falls + resolve(); + }); + }); + } + } + }]); + + return Util; +}(); + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function($) { /** * Module UI @@ -5137,6 +1335,7 @@ var CSS = { * @property {Element} nodes.wrapper - * @property {Element} nodes.redactor - */ + var UI = function () { /** @@ -5147,7 +1346,7 @@ var UI = function () { function UI(_ref) { var config = _ref.config; - _classCallCheck(this, UI); + __webpack_require__(0).classCallCheck(this, UI); this.config = config; this.Editor = null; @@ -5165,7 +1364,7 @@ var UI = function () { */ - _createClass(UI, [{ + __webpack_require__(0).createClass(UI, [{ key: 'prepare', @@ -5194,8 +1393,8 @@ var UI = function () { /** * Create and save main UI elements */ - _this.nodes.wrapper = _dom2.default.make('div', CSS.editorWrapper); - _this.nodes.redactor = _dom2.default.make('div', CSS.editorZone); + _this.nodes.wrapper = $.make('div', CSS.editorWrapper); + _this.nodes.redactor = $.make('div', CSS.editorZone); _this.nodes.wrapper.appendChild(_this.nodes.redactor); _this.nodes.holder.appendChild(_this.nodes.wrapper); @@ -5242,19 +1441,19 @@ var UI = function () { /** * Load CSS */ - var styles = __webpack_require__(26); + var styles = __webpack_require__(9); /** * Make tag */ - var tag = _dom2.default.make('style', null, { + var tag = $.make('style', null, { textContent: styles.toString() }); /** * Append styles */ - _dom2.default.append(document.head, tag); + $.append(document.head, tag); } }, { key: 'state', @@ -5534,763 +1733,13 @@ module.exports = UI; // return ui; // // })({}); +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 22 */ +/* 9 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -/** - * Codex Editor - * - * Short Description (눈_눈;) - * @version 2.0.0 - * - * How to start? - * Example: - * new CodexEditor({ - * holderId : 'codex-editor', - * initialBlock : 'paragraph', - * placeholder : 'Write your story....', - * tools: { - * quote: Quote, - * anotherTool : AnotherTool - * }, - * toolsConfig: { - * quote: { - * iconClassname : 'quote-icon', - * displayInToolbox : true, - * enableLineBreaks : true - * }, - * anotherTool: { - * iconClassname : 'tool-icon' - * } - * } - * }); - * - * - tools is an object: { - * pluginName: PluginClass, - * ..... - * } - * - toolsConfig is an additional configuration that uses Codex Editor API - * iconClassname - CSS classname of toolbox icon - * displayInToolbox - if you want to see your Tool in toolbox hided in "plus" button, than set "True". By default : "False" - * 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 - * - * @author CodeX-Team - * - */ - -/** - * @typedef {CodexEditor} CodexEditor - editor class - */ - -/** - * @typedef {Object} EditorConfig - * @property {String} holderId - Element to append Editor - * ... - */ - - - -/** - * Require Editor modules places in components/modules dir - */ -// eslint-disable-next-line - -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; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var modules = ["events.js","toolbar.js","tools.js","ui.js"].map(function (module) { - - return __webpack_require__(23)("./" + module); -}); - -/** - * @class - * - * @classdesc CodeX Editor base class - * - * @property this.config - all settings - * @property this.moduleInstances - constructed editor components - * - * @type {CodexEditor} - */ -module.exports = function () { - _createClass(CodexEditor, null, [{ - key: 'version', - - - /** Editor version */ - get: function get() { - - return "2.0.0"; - } - - /** - * @param {EditorConfig} config - user configuration - * - */ - - }]); - - function CodexEditor(config) { - var _this = this; - - _classCallCheck(this, CodexEditor); - - /** - * Configuration object - */ - this.config = {}; - - /** - * Editor Components - */ - this.moduleInstances = {}; - - Promise.resolve().then(function () { - - _this.configuration = config; - }).then(function () { - return _this.init(); - }).then(function () { - return _this.start(); - }).then(function () { - - console.log('CodeX Editor is ready'); - }).catch(function (error) { - - console.log('CodeX Editor does not ready beecause of %o', error); - }); - } - - /** - * Setting for configuration - * @param {Object} config - */ - - - _createClass(CodexEditor, [{ - key: 'init', - - - /** - * Initializes modules: - * - make and save instances - * - configure - */ - value: function init() { - - /** - * Make modules instances and save it to the @property this.moduleInstances - */ - this.constructModules(); - - /** - * Modules configuration - */ - this.configureModules(); - } - - /** - * Make modules instances and save it to the @property this.moduleInstances - */ - - }, { - key: 'constructModules', - value: function constructModules() { - var _this2 = this; - - modules.forEach(function (Module) { - - try { - - /** - * We use class name provided by displayName property - * - * On build, Babel will transform all Classes to the Functions so, name will always be 'Function' - * To prevent this, we use 'babel-plugin-class-display-name' plugin - * @see https://www.npmjs.com/package/babel-plugin-class-display-name - */ - - _this2.moduleInstances[Module.displayName] = new Module({ - config: _this2.configuration - }); - } catch (e) { - - console.log('Module %o skipped because %o', Module, e); - } - }); - } - - /** - * Modules instances configuration: - * - pass other modules to the 'state' property - * - ... - */ - - }, { - key: 'configureModules', - value: function configureModules() { - - for (var name in this.moduleInstances) { - - /** - * Module does not need self-instance - */ - this.moduleInstances[name].state = this.getModulesDiff(name); - } - } - - /** - * Return modules without passed name - */ - - }, { - key: 'getModulesDiff', - value: function getModulesDiff(name) { - - var diff = {}; - - for (var moduleName in this.moduleInstances) { - - /** - * Skip module with passed name - */ - if (moduleName === name) { - - continue; - } - diff[moduleName] = this.moduleInstances[moduleName]; - } - - return diff; - } - - /** - * Start Editor! - * - * @return {Promise} - */ - - }, { - key: 'start', - value: function start() { - - var prepareDecorator = function prepareDecorator(module) { - return module.prepare(); - }; - - return Promise.resolve().then(prepareDecorator(this.moduleInstances.UI)).then(prepareDecorator(this.moduleInstances.Tools)).catch(function (error) { - - console.log('Error occured', error); - }); - } - }, { - key: 'configuration', - set: function set() { - var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - - - this.config.holderId = config.holderId; - this.config.placeholder = config.placeholder || 'write your story...'; - this.config.sanitizer = config.sanitizer || { - p: true, - b: true, - a: true - }; - - this.config.hideToolbar = config.hideToolbar ? config.hideToolbar : false; - this.config.tools = config.tools || {}; - this.config.toolsConfig = config.toolsConfig || {}; - } - - /** - * Returns private property - * @returns {{}|*} - */ - , - get: function get() { - - return this.config; - } - }]); - - return CodexEditor; -}(); - -// module.exports = (function (editor) { -// -// 'use strict'; -// -// editor.version = VERSION; -// editor.scriptPrefix = 'cdx-script-'; -// -// var init = function () { -// -// editor.core = require('./modules/core'); -// editor.tools = require('./modules/tools'); -// editor.ui = require('./modules/ui'); -// editor.transport = require('./modules/transport'); -// editor.renderer = require('./modules/renderer'); -// editor.saver = require('./modules/saver'); -// editor.content = require('./modules/content'); -// editor.toolbar = require('./modules/toolbar/toolbar'); -// editor.callback = require('./modules/callbacks'); -// editor.draw = require('./modules/draw'); -// editor.caret = require('./modules/caret'); -// editor.notifications = require('./modules/notifications'); -// editor.parser = require('./modules/parser'); -// editor.sanitizer = require('./modules/sanitizer'); -// editor.listeners = require('./modules/listeners'); -// editor.destroyer = require('./modules/destroyer'); -// editor.paste = require('./modules/paste'); -// -// }; -// -// /** -// * @public -// * holds initial settings -// */ -// editor.settings = { -// tools : ['paragraph', 'header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'], -// holderId : 'codex-editor', -// -// // Type of block showing on empty editor -// initialBlockPlugin: 'paragraph' -// }; -// -// /** -// * public -// * -// * Static nodes -// */ -// editor.nodes = { -// holder : null, -// wrapper : null, -// toolbar : null, -// inlineToolbar : { -// wrapper : null, -// buttons : null, -// actions : null -// }, -// toolbox : null, -// notifications : null, -// plusButton : null, -// showSettingsButton: null, -// showTrashButton : null, -// blockSettings : null, -// pluginSettings : null, -// defaultSettings : null, -// toolbarButtons : {}, // { type : DomEl, ... } -// redactor : null -// }; -// -// /** -// * @public -// * -// * Output state -// */ -// editor.state = { -// jsonOutput : [], -// blocks : [], -// inputs : [] -// }; -// -// /** -// * @public -// * Editor plugins -// */ -// editor.tools = {}; -// -// editor.start = function (userSettings) { -// -// init(); -// -// editor.core.prepare(userSettings) -// -// // If all ok, make UI, bind events and parse initial-content -// .then(editor.ui.prepare) -// .then(editor.tools.prepare) -// .then(editor.sanitizer.prepare) -// .then(editor.paste.prepare) -// .then(editor.transport.prepare) -// .then(editor.renderer.makeBlocksFromData) -// .then(editor.ui.saveInputs) -// .catch(function (error) { -// -// editor.core.log('Initialization failed with error: %o', 'warn', error); -// -// }); -// -// }; -// -// return editor; -// -// })({}); - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { - -var map = { - "./_anchors": 3, - "./_anchors.js": 3, - "./_callbacks": 4, - "./_callbacks.js": 4, - "./_caret": 5, - "./_caret.js": 5, - "./_content": 6, - "./_content.js": 6, - "./_destroyer": 7, - "./_destroyer.js": 7, - "./_listeners": 8, - "./_listeners.js": 8, - "./_notifications": 9, - "./_notifications.js": 9, - "./_parser": 10, - "./_parser.js": 10, - "./_paste": 11, - "./_paste.js": 11, - "./_renderer": 12, - "./_renderer.js": 12, - "./_sanitizer": 13, - "./_sanitizer.js": 13, - "./_saver": 14, - "./_saver.js": 14, - "./_transport": 15, - "./_transport.js": 15, - "./events": 16, - "./events.js": 16, - "./toolbar": 17, - "./toolbar.js": 17, - "./toolbar/inline": 0, - "./toolbar/inline.js": 0, - "./toolbar/settings": 1, - "./toolbar/settings.js": 1, - "./toolbar/toolbar": 19, - "./toolbar/toolbar.js": 19, - "./toolbar/toolbox": 2, - "./toolbar/toolbox.js": 2, - "./tools": 20, - "./tools.js": 20, - "./ui": 21, - "./ui.js": 21 -}; -function webpackContext(req) { - return __webpack_require__(webpackContextResolve(req)); -}; -function webpackContextResolve(req) { - var id = map[req]; - if(!(id + 1)) // check for number or string - throw new Error("Cannot find module '" + req + "'."); - return id; -}; -webpackContext.keys = function webpackContextKeys() { - return Object.keys(map); -}; -webpackContext.resolve = webpackContextResolve; -module.exports = webpackContext; -webpackContext.id = 23; - -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (root, factory) { - if (true) { - !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), - __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? - (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : - __WEBPACK_AMD_DEFINE_FACTORY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - } else if (typeof exports === 'object') { - module.exports = factory(); - } else { - root.HTMLJanitor = factory(); - } -}(this, function () { - - /** - * @param {Object} config.tags Dictionary of allowed tags. - * @param {boolean} config.keepNestedBlockElements Default false. - */ - function HTMLJanitor(config) { - - var tagDefinitions = config['tags']; - var tags = Object.keys(tagDefinitions); - - var validConfigValues = tags - .map(function(k) { return typeof tagDefinitions[k]; }) - .every(function(type) { return type === 'object' || type === 'boolean' || type === 'function'; }); - - if(!validConfigValues) { - throw new Error("The configuration was invalid"); - } - - this.config = config; - } - - // TODO: not exhaustive? - var blockElementNames = ['P', 'LI', 'TD', 'TH', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'PRE']; - function isBlockElement(node) { - return blockElementNames.indexOf(node.nodeName) !== -1; - } - - var inlineElementNames = ['A', 'B', 'STRONG', 'I', 'EM', 'SUB', 'SUP', 'U', 'STRIKE']; - function isInlineElement(node) { - return inlineElementNames.indexOf(node.nodeName) !== -1; - } - - HTMLJanitor.prototype.clean = function (html) { - var sandbox = document.createElement('div'); - sandbox.innerHTML = html; - - this._sanitize(sandbox); - - return sandbox.innerHTML; - }; - - HTMLJanitor.prototype._sanitize = function (parentNode) { - var treeWalker = createTreeWalker(parentNode); - var node = treeWalker.firstChild(); - if (!node) { return; } - - do { - // Ignore nodes that have already been sanitized - if (node._sanitized) { - continue; - } - - if (node.nodeType === Node.TEXT_NODE) { - // If this text node is just whitespace and the previous or next element - // sibling is a block element, remove it - // N.B.: This heuristic could change. Very specific to a bug with - // `contenteditable` in Firefox: http://jsbin.com/EyuKase/1/edit?js,output - // FIXME: make this an option? - if (node.data.trim() === '' - && ((node.previousElementSibling && isBlockElement(node.previousElementSibling)) - || (node.nextElementSibling && isBlockElement(node.nextElementSibling)))) { - parentNode.removeChild(node); - this._sanitize(parentNode); - break; - } else { - continue; - } - } - - // Remove all comments - if (node.nodeType === Node.COMMENT_NODE) { - parentNode.removeChild(node); - this._sanitize(parentNode); - break; - } - - var isInline = isInlineElement(node); - var containsBlockElement; - if (isInline) { - containsBlockElement = Array.prototype.some.call(node.childNodes, isBlockElement); - } - - // Block elements should not be nested (e.g.
  • ...); if - // they are, we want to unwrap the inner block element. - var isNotTopContainer = !! parentNode.parentNode; - var isNestedBlockElement = - isBlockElement(parentNode) && - isBlockElement(node) && - isNotTopContainer; - - var nodeName = node.nodeName.toLowerCase(); - - var allowedAttrs = getAllowedAttrs(this.config, nodeName, node); - - var isInvalid = isInline && containsBlockElement; - - // Drop tag entirely according to the whitelist *and* if the markup - // is invalid. - if (isInvalid || shouldRejectNode(node, allowedAttrs) - || (!this.config.keepNestedBlockElements && isNestedBlockElement)) { - // Do not keep the inner text of SCRIPT/STYLE elements. - if (! (node.nodeName === 'SCRIPT' || node.nodeName === 'STYLE')) { - while (node.childNodes.length > 0) { - parentNode.insertBefore(node.childNodes[0], node); - } - } - parentNode.removeChild(node); - - this._sanitize(parentNode); - break; - } - - // Sanitize attributes - for (var a = 0; a < node.attributes.length; a += 1) { - var attr = node.attributes[a]; - - if (shouldRejectAttr(attr, allowedAttrs, node)) { - node.removeAttribute(attr.name); - // Shift the array to continue looping. - a = a - 1; - } - } - - // Sanitize children - this._sanitize(node); - - // Mark node as sanitized so it's ignored in future runs - node._sanitized = true; - } while ((node = treeWalker.nextSibling())); - }; - - function createTreeWalker(node) { - return document.createTreeWalker(node, - NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT, - null, false); - } - - function getAllowedAttrs(config, nodeName, node){ - if (typeof config.tags[nodeName] === 'function') { - return config.tags[nodeName](node); - } else { - return config.tags[nodeName]; - } - } - - function shouldRejectNode(node, allowedAttrs){ - if (typeof allowedAttrs === 'undefined') { - return true; - } else if (typeof allowedAttrs === 'boolean') { - return !allowedAttrs; - } - - return false; - } - - function shouldRejectAttr(attr, allowedAttrs, node){ - var attrName = attr.name.toLowerCase(); - - if (allowedAttrs === true){ - return false; - } else if (typeof allowedAttrs[attrName] === 'function'){ - return !allowedAttrs[attrName](attr.value, node); - } else if (typeof allowedAttrs[attrName] === 'undefined'){ - return true; - } else if (allowedAttrs[attrName] === false) { - return true; - } else if (typeof allowedAttrs[attrName] === 'string') { - return (allowedAttrs[attrName] !== attr.value); - } - - return false; - } - - return HTMLJanitor; - -})); - - -/***/ }), -/* 25 */ -/***/ (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; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * Codex Editor Util - */ -module.exports = function () { - function Util() { - _classCallCheck(this, Util); - } - - _createClass(Util, null, [{ - key: "sequence", - - - /** - * @typedef {Object} ChainData - * @property {Object} data - data that will be passed to the success or fallback - * @property {Function} function - function's that must be called asynchronically - */ - - /** - * Fires a promise sequence asyncronically - * - * @param {Object[]} chains - list or ChainData's - * @param {Function} success - success callback - * @param {Function} fallback - callback that fires in case of errors - * - * @return {Promise} - */ - value: function sequence(chains, success, fallback) { - - return new Promise(function (resolve, reject) { - - /** - * pluck each element from queue - * First, send resolved Promise as previous value - * Each plugins "prepare" method returns a Promise, that's why - * reduce current element will not be able to continue while can't get - * a resolved Promise - */ - chains.reduce(function (previousValue, currentValue, iteration) { - - return previousValue.then(function () { - return waitNextBlock(currentValue, success, fallback); - }).then(function () { - - // finished - if (iteration == chains.length - 1) { - - resolve(); - } - }); - }, Promise.resolve()); - }); - - /** - * Decorator - * - * @param {ChainData} chainData - * - * @param {Function} success - * @param {Function} fallback - * - * @return {Promise} - */ - function waitNextBlock(chainData, success, fallback) { - - return new Promise(function (resolve, reject) { - - chainData.function().then(function () { - - success(chainData.data); - }).then(resolve).catch(function () { - - fallback(chainData.data); - - // anyway, go ahead even it falls - resolve(); - }); - }); - } - } - }]); - - return Util; -}(); - -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { - -exports = module.exports = __webpack_require__(27)(undefined); +exports = module.exports = __webpack_require__(10)(undefined); // imports @@ -6301,7 +1750,7 @@ exports.push([module.i, ":root {\n\n /**\n * Toolbar buttons\n */\n\n /***/ }), -/* 27 */ +/* 10 */ /***/ (function(module, exports) { /* diff --git a/build/codex-editor.js.map b/build/codex-editor.js.map index 61c8ddff..45187f52 100644 --- a/build/codex-editor.js.map +++ b/build/codex-editor.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap a82850b89a1ba6b2c30f","webpack:///./src/components/modules/toolbar/inline.js","webpack:///./src/components/modules/toolbar/settings.js","webpack:///./src/components/modules/toolbar/toolbox.js","webpack:///./src/components/modules/_anchors.js","webpack:///./src/components/modules/_callbacks.js","webpack:///./src/components/modules/_caret.js","webpack:///./src/components/modules/_content.js","webpack:///./src/components/modules/_destroyer.js","webpack:///./src/components/modules/_listeners.js","webpack:///./src/components/modules/_notifications.js","webpack:///./src/components/modules/_parser.js","webpack:///./src/components/modules/_paste.js","webpack:///./src/components/modules/_renderer.js","webpack:///./src/components/modules/_sanitizer.js","webpack:///./src/components/modules/_saver.js","webpack:///./src/components/modules/_transport.js","webpack:///./src/components/modules/events.js","webpack:///./src/components/modules/toolbar.js","webpack:///./src/components/dom.js","webpack:///./src/components/modules/toolbar/toolbar.js","webpack:///./src/components/modules/tools.js","webpack:///./src/components/modules/ui.js","webpack:///./src/codex.js","webpack:///./src/components/modules ^\\.\\/.*$","webpack:///./node_modules/html-janitor/src/html-janitor.js","webpack:///./src/components/util.js","webpack:///./src/styles/main.css","webpack:///./node_modules/css-loader/lib/css-base.js"],"names":["module","exports","inline","editor","codex","buttonsOpened","actionsOpened","wrappersOffset","storedSelection","show","currentNode","content","tool","dataset","plugin","tools","showInlineToolbar","selectedText","getSelectionText","toolbar","nodes","inlineToolbar","wrapper","length","move","classList","add","showButtons","close","remove","getWrappersOffset","coords","getSelectionCoords","defaultOffset","newCoordinateX","newCoordinateY","offsetHeight","x","left","y","window","scrollY","top","style","transform","Math","floor","closeButtons","closeAction","toolClicked","event","type","createLinkAction","defaultToolAction","buttons","childNodes","forEach","hightlight","offset","getOffset","el","_x","_y","isNaN","offsetLeft","offsetTop","clientLeft","clientTop","offsetParent","sel","document","selection","range","createRange","collapse","boundingLeft","boundingTop","getSelection","rangeCount","getRangeAt","cloneRange","getClientRects","rect","toString","showActions","action","actions","innerHTML","inlineToolbarAnchorInputKeydown_","keyCode","core","keys","ENTER","editable","restoreSelection","setAnchor","value","preventDefault","stopImmediatePropagation","clearRange","isActive","isLinkActive","saveSelection","draw","inputForLink","appendChild","focus","listeners","dataType","contains","execCommand","url","containerEl","preSelectionRange","start","selectNodeContents","setEnd","startContainer","startOffset","end","savedSel","charIndex","setStart","nodeStack","node","foundStart","stop","nextCharIndex","pop","nodeType","i","push","removeAllRanges","addRange","queryCommandState","setButtonHighlighted","removeButtonsHighLight","tag","anchorNode","parentNode","tagName","button","icon","settings","opened","setting","open","toolType","makeSettings","settingsBlock","pluginSettings","blockSettings","toggle","makeRemoveBlockButton","removeBlockWrapper","settingButton","actionWrapper","confirmAction","textContent","cancelAction","removeButtonClicked","confirmRemovingRequest","cancelRemovingRequest","hideRemoveActions","showRemoveActions","toolbox","currentBlock","firstLevelBlocksCount","redactor","ui","addInitialBlock","saveInputs","openedOnBlock","plusButton","current","leaf","currentTool","Object","barButtons","toolbarButtons","nextToolIndex","toolToSelect","visibleTool","displayInToolbox","indexOf","UNREPLACEBLE_TOOLS","workingNode","currentInputIndex","caret","inputIndex","newBlockContent","appendCallback","blockData","render","block","stretched","trim","switchBlock","insertBlock","call","setTimeout","setToBlock","workingNodeChanged","anchors","input","settingsOpened","anchor","anchorChanged","e","newAnchor","target","rusToTranslit","className","BLOCK_WITH_ANCHOR","keyDownOnAnchorInput","stopPropagation","blur","keyUpOnAnchorInput","LEFT","DOWN","string","ru","en","split","join","toLowerCase","replace","callbacks","globalKeydown","enterKeyPressed_","redactorKeyDown","TAB","tabKeyPressedOnRedactorsZone_","enterKeyPressedOnRedactorsZone_","ESC","escapeKeyPressedOnRedactorsZone_","defaultKeyPressedOnRedactorsZone_","globalKeyup","UP","RIGHT","arrowKeyPressed_","isBlockEmpty","editorAreaHightlighted","enterPressedOnBlock_","NEW_BLOCK_TYPE","initialBlockPlugin","contentEditable","saveCurrentInputIndex","getCurrentInputIndex","isEnterPressedOnToolbar","state","inputs","enableLineBreaks","shiftKey","currentSelection","currentSelectedNode","caretAtTheEndOfText","position","atTheEnd","isTextNodeHasParentBetweenContenteditable","callback","enterPressedOnBlock","nodeTypes","TEXT","log","splitBlock","showPlusButton","islastNode","isLastNode","clearMark","redactorClicked","detectWhenClickedOnFirstLevelBlockArea_","firstLevelBlock","indexOfLastInput","getFirstLevelBlock","setToNextBlock","inputIsEmpty","currentNodeType","isInitialType","hidePlusButton","markBlock","flag","isDomNode","body","toolbarButtonClicked","plusButtonClicked","blockKeydown","blockRightOrDownArrowPressed_","BACKSPACE","backspacePressed_","blockLeftOrUpArrowPressed_","focusedNode","focusedNodeHolder","editableElementIndex","caretInLastChild","lastChild","deepestTextnode","getDeepestTextNodeFromPosition","anchorOffset","caretInFirstChild","caretAtTheBeginning","firstChild","setToPreviousBlock","selectionLength","isNativeInput","getRange","endOffset","atStart","mergeBlocks","showSettingsButtonClicked","currentToolType","focusedNodeIndex","set","index","childs","nodeToSet","nextInput","emptyTextElement","createTextNode","targetInput","previousInput","lastChildNode","lengthOfLastChildNode","pluginsRender","isFirstNode","isOffsetZero","insertNode","lastNode","DOCUMENT_FRAGMENT","deleteContents","setStartAfter","sync","html","BLOCK_HIGHLIGHTED","BLOCK_CLASSNAME","targetNode","replaceBlock","targetBlock","newBlock","replaceChild","addBlockHandlers","needPlaceCaret","workingBlock","blockType","isStretched","composeNewBlock_","insertAfter","editableElement","querySelector","emptyText","blockToReplace","newBlockComposed","blockChilds","text","removeChild","lookingFromStart","TAG","blockContent","BLOCK_CONTENT","BLOCK_STRETCHED","anchorNodeText","caretOffset","textBeforeCaret","textNodeBeforeCaret","textAfterCaret","textNodeAfterCaret","substring","previousChilds","nextChilds","reachedCurrent","child","previousChildsLength","nextChildsLength","newNode","createElement","targetInputIndex","currentInputContent","allChecked","allSiblingsEmpty_","sibling","nextSibling","wrapTextWithParagraphs","htmlData","plainData","wrapPlainTextWithParagraphs","newWrapper","paragraph","firstLevelBlocks","blockTyped","cloneNode","plainText","getEditableParent","clear","all","blocks","items","load","articleData","currentContent","assign","concat","renderer","makeBlocksFromData","destroyer","removeNodes","notifications","destroyPlugins","destroy","destroyScripts","scripts","getElementsByTagName","id","scriptPrefix","removeAll","plugins","allListeners","search","byElement","element","context","listenersOnElement","listener","byType","eventType","listenersWithType","byHandler","handler","listenersWithHandler","one","result","isCapture","addEventListener","data","alreadyAddedListener","removeEventListener","existingListeners","splice","map","get","queue","addToQueue","createHolder","holder","errorThrown","errorMsg","notification","message","constructorSettings","cancel","confirm","inputField","confirmHandler","cancelHandler","create","time","okBtn","cancelBtn","okMsg","cancelMsg","send","parser","insertPastedContent","isFirstLevelBlock","paste","patterns","prepare","renderOnPastePatterns","Array","isArray","pattern","Promise","resolve","pasted","clipBoardData","clipboardData","getData","analize","execArray","regex","exec","match","pasteToNewBlock_","blockPasteCallback","needsToHandlePasteEvent","paragraphs","cleanData","wrappedData","sanitizer","clean","emulateUserAgentBehaviour","insertPastedParagraphs","editableParent","childElementCount","createDocumentFragment","isEmpty","then","appendBlocks","catch","error","nodeSequence","appendNodeAtIndex","getNodeAsync","createBlockFromData","blocksList","toolData","pluginName","Error","available","unavailableBlock","loadingMessage","inputPosition","janitor","require","Config","CUSTOM","BASIC","tags","p","a","href","rel","init_","userCustomConfig","configuration","dirtyString","customConfig","janitorInstance","saver","save","jsonOutput","saveBlocks","getBlockData","makeOutput","saveBlockData","validateBlockData","pluginsContent","validate","savedData","filter","Date","version","transport","currentRequest","arguments","fileSelected","clearInput","files","formData","FormData","multiple","append","name","ajax","beforeSend","success","progress","selectAndUpload","args","setAttribute","accept","click","abort","Events","Editor","subscribers","eventName","reduce","previousData","currentHandler","newData","Toolbar","settingsToggler","removeBlockButton","defaultSettings","CSS","make","makeBlockSettingsPanel","UI","Dom","classNames","attributes","attrName","parent","elements","selector","querySelectorAll","defaultToolbarHeight","hideToolbar","showSettingsButton","newYCoordinate","util","Tools","toolsAvailable","toolsUnavailable","iconClassName","config","toolClasses","self","hasOwnProperty","reject","toolName","sequenceData","getListOfPrepareFunctions","sequence","fallback","toolPreparationList","toolClass","function","toolInstances","editorWrapper","editorZone","getElementById","holderId","loadStyles","console","styles","head","modules","editorModules","moduleInstances","init","constructModules","configureModules","Module","displayName","getModulesDiff","diff","moduleName","prepareDecorator","placeholder","b","toolsConfig","chains","previousValue","currentValue","iteration","waitNextBlock","chainData"],"mappings":"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AL,CAAWsa,MAAX,CAAkBjV,WAAlB,CAA8B,MAAKrF,KAAL,CAAWE,OAAzC;;AAEA;;;AAGA,cAAK6hB,MAAL,CAAYO,OAAZ,CAAoBK,IAApB;;AAEA;;;AAGA,cAAKsC,UAAL;;AAEA9I;AAEH,OApCM;;AAsCP;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAnDO,OAqDF0B,KArDE,CAqDI,aAAK;;AAERqH,gBAAQpH,KAAR,CAAclS,CAAd;;AAEJ;AAEC,OA3DE,CAAP;AA6DH;;;iCAEY;;AAET;;;AAGA,UAAIuZ,SAAS,mBAAAvG,CAAQ,EAAR,CAAb;;AAEA;;;AAGA,UAAIvX,MAAM,cAAEsb,IAAF,CAAO,OAAP,EAAgB,IAAhB,EAAsB;AAC5Bja,qBAAayc,OAAOphB,QAAP;AADe,OAAtB,CAAV;;AAIA;;;AAGA,oBAAEmd,MAAF,CAAShe,SAASkiB,IAAlB,EAAwB/d,GAAxB;AAEH;;;sBA/FS0a,M,EAAQ;;AAEd,WAAKA,MAAL,GAAcA,MAAd;AAEH;;;;;;;;;AA+FLnjB,OAAOC,OAAP,GAAiBgkB,EAAjB;;AAGA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;;;;;;AC/bA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA;;;;AAIA;;;;;;AAMA;;AAEA;;;AAGA;;;;;;AACA,IAAIwC,UAAU,6CAAAC,CAAcrL,GAAd,CAAmB,kBAAU;;AAEvC,WAAO,4BAAQ,GAA0Brb,MAAlC,CAAP;AAEH,CAJa,CAAd;;AAMA;;;;;;;;;;AAUAA,OAAOC,OAAP;AAAA;AAAA;;;AAEI;AAFJ,4BAGyB;;AAEjB,mBAAO,OAAP;AAEH;;AAED;;;;;AATJ;;AAaI,yBAAYklB,MAAZ,EAAoB;AAAA;;AAAA;;AAEhB;;;AAGA,aAAKA,MAAL,GAAc,EAAd;;AAEA;;;AAGA,aAAKwB,eAAL,GAAuB,EAAvB;;AAEArJ,gBAAQC,OAAR,GACKwB,IADL,CACU,YAAM;;AAER,kBAAK4B,aAAL,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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,U;;;;;;ACrXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uB;;;;;;AC1DA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;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;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,gBAAgB,QAAQ;;AAExB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,+DAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,qBAAqB,4BAA4B;AACjD;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;;AAEA;AACA;;AAEA;;AAEA,CAAC;;;;;;;;;;;;;;ACxLD;;;AAGAnlB,OAAOC,OAAP;AAAA;AAAA;AAAA;;AAAA;AAAA;;;AAEI;;;;;;AAMA;;;;;;;;;AARJ,iCAiBoBunB,MAjBpB,EAiB4B9E,OAjB5B,EAiBqCkD,QAjBrC,EAiB+C;;AAEvC,mBAAO,IAAItI,OAAJ,CAAY,UAAUC,OAAV,EAAmBgI,MAAnB,EAA2B;;AAE1C;;;;;;;AAOAiC,uBAAOlE,MAAP,CAAc,UAAUmE,aAAV,EAAyBC,YAAzB,EAAuCC,SAAvC,EAAkD;;AAE5D,2BAAOF,cACF1I,IADE,CACG;AAAA,+BAAM6I,cAAcF,YAAd,EAA4BhF,OAA5B,EAAqCkD,QAArC,CAAN;AAAA,qBADH,EAEF7G,IAFE,CAEG,YAAM;;AAER;AACA,4BAAI4I,aAAaH,OAAOjmB,MAAP,GAAgB,CAAjC,EAAoC;;AAEhCgc;AAEH;AAEJ,qBAXE,CAAP;AAaH,iBAfD,EAeGD,QAAQC,OAAR,EAfH;AAiBH,aA1BM,CAAP;;AA4BA;;;;;;;;;;AAUA,qBAASqK,aAAT,CAAuBC,SAAvB,EAAkCnF,OAAlC,EAA2CkD,QAA3C,EAAqD;;AAEjD,uBAAO,IAAItI,OAAJ,CAAY,UAAUC,OAAV,EAAmBgI,MAAnB,EAA2B;;AAE1CsC,8BAAU9B,QAAV,GACKhH,IADL,CACU,YAAM;;AAER2D,gCAAQmF,UAAU7M,IAAlB;AAEH,qBALL,EAMK+D,IANL,CAMUxB,OANV,EAOK0B,KAPL,CAOW,YAAY;;AAEf2G,iCAASiC,UAAU7M,IAAnB;;AAEA;AACAuC;AAEH,qBAdL;AAgBH,iBAlBM,CAAP;AAoBH;AAEJ;AAjFL;;AAAA;AAAA,I;;;;;;ACHA;AACA;;;AAGA;AACA,gCAAiC,iDAAiD,2CAA2C,yBAAyB,6BAA6B,oBAAoB,GAAG,uBAAuB,wBAAwB,OAAO;;AAEhQ;;;;;;;ACPA;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","file":"codex-editor.js","sourcesContent":[" \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, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\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 \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 22);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap a82850b89a1ba6b2c30f","/**\n * Inline toolbar\n *\n * Contains from tools:\n * Bold, Italic, Underline and Anchor\n *\n * @author Codex Team\n * @version 1.0\n */\n\nmodule.exports = (function (inline) {\n\n let editor = codex.editor;\n\n inline.buttonsOpened = null;\n inline.actionsOpened = null;\n inline.wrappersOffset = null;\n\n /**\n * saving selection that need for execCommand for styling\n *\n */\n inline.storedSelection = null;\n\n /**\n * @protected\n *\n * Open inline toobar\n */\n inline.show = function () {\n\n var currentNode = editor.content.currentNode,\n tool = currentNode.dataset.tool,\n plugin;\n\n /**\n * tool allowed to open inline toolbar\n */\n plugin = editor.tools[tool];\n\n if (!plugin.showInlineToolbar)\n return;\n\n var selectedText = inline.getSelectionText(),\n toolbar = editor.nodes.inlineToolbar.wrapper;\n\n if (selectedText.length > 0) {\n\n /** Move toolbar and open */\n editor.toolbar.inline.move();\n\n /** Open inline toolbar */\n toolbar.classList.add('opened');\n\n /** show buttons of inline toolbar */\n editor.toolbar.inline.showButtons();\n\n }\n\n };\n\n /**\n * @protected\n *\n * Closes inline toolbar\n */\n inline.close = function () {\n\n var toolbar = editor.nodes.inlineToolbar.wrapper;\n\n toolbar.classList.remove('opened');\n\n };\n\n /**\n * @private\n *\n * Moving toolbar\n */\n inline.move = function () {\n\n if (!this.wrappersOffset) {\n\n this.wrappersOffset = this.getWrappersOffset();\n\n }\n\n var coords = this.getSelectionCoords(),\n defaultOffset = 0,\n toolbar = editor.nodes.inlineToolbar.wrapper,\n newCoordinateX,\n newCoordinateY;\n\n if (toolbar.offsetHeight === 0) {\n\n defaultOffset = 40;\n\n }\n\n newCoordinateX = coords.x - this.wrappersOffset.left;\n newCoordinateY = coords.y + window.scrollY - this.wrappersOffset.top - defaultOffset - toolbar.offsetHeight;\n\n toolbar.style.transform = `translate3D(${Math.floor(newCoordinateX)}px, ${Math.floor(newCoordinateY)}px, 0)`;\n\n /** Close everything */\n editor.toolbar.inline.closeButtons();\n editor.toolbar.inline.closeAction();\n\n };\n\n /**\n * @private\n *\n * Tool Clicked\n */\n\n inline.toolClicked = function (event, type) {\n\n /**\n * For simple tools we use default browser function\n * For more complicated tools, we should write our own behavior\n */\n switch (type) {\n\n case 'createLink' : editor.toolbar.inline.createLinkAction(event, type); break;\n default : editor.toolbar.inline.defaultToolAction(type); break;\n\n }\n\n /**\n * highlight buttons\n * after making some action\n */\n editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight);\n\n };\n\n /**\n * @private\n *\n * Saving wrappers offset in DOM\n */\n inline.getWrappersOffset = function () {\n\n var wrapper = editor.nodes.wrapper,\n offset = this.getOffset(wrapper);\n\n this.wrappersOffset = offset;\n return offset;\n\n };\n\n /**\n * @private\n *\n * Calculates offset of DOM element\n *\n * @param el\n * @returns {{top: number, left: number}}\n */\n inline.getOffset = function ( el ) {\n\n var _x = 0;\n var _y = 0;\n\n while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {\n\n _x += (el.offsetLeft + el.clientLeft);\n _y += (el.offsetTop + el.clientTop);\n el = el.offsetParent;\n\n }\n return { top: _y, left: _x };\n\n };\n\n /**\n * @private\n *\n * Calculates position of selected text\n * @returns {{x: number, y: number}}\n */\n inline.getSelectionCoords = function () {\n\n var sel = document.selection, range;\n var x = 0, y = 0;\n\n if (sel) {\n\n if (sel.type != 'Control') {\n\n range = sel.createRange();\n range.collapse(true);\n x = range.boundingLeft;\n y = range.boundingTop;\n\n }\n\n } else if (window.getSelection) {\n\n sel = window.getSelection();\n\n if (sel.rangeCount) {\n\n range = sel.getRangeAt(0).cloneRange();\n if (range.getClientRects) {\n\n range.collapse(true);\n var rect = range.getClientRects()[0];\n\n if (!rect) {\n\n return;\n\n }\n\n x = rect.left;\n y = rect.top;\n\n }\n\n }\n\n }\n return { x: x, y: y };\n\n };\n\n /**\n * @private\n *\n * Returns selected text as String\n * @returns {string}\n */\n inline.getSelectionText = function () {\n\n var selectedText = '';\n\n // all modern browsers and IE9+\n if (window.getSelection) {\n\n selectedText = window.getSelection().toString();\n\n }\n\n return selectedText;\n\n };\n\n /** Opens buttons block */\n inline.showButtons = function () {\n\n var buttons = editor.nodes.inlineToolbar.buttons;\n\n buttons.classList.add('opened');\n\n editor.toolbar.inline.buttonsOpened = true;\n\n /** highlight buttons */\n editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight);\n\n };\n\n /** Makes buttons disappear */\n inline.closeButtons = function () {\n\n var buttons = editor.nodes.inlineToolbar.buttons;\n\n buttons.classList.remove('opened');\n\n editor.toolbar.inline.buttonsOpened = false;\n\n };\n\n /** Open buttons defined action if exist */\n inline.showActions = function () {\n\n var action = editor.nodes.inlineToolbar.actions;\n\n action.classList.add('opened');\n\n editor.toolbar.inline.actionsOpened = true;\n\n };\n\n /** Close actions block */\n inline.closeAction = function () {\n\n var action = editor.nodes.inlineToolbar.actions;\n\n action.innerHTML = '';\n action.classList.remove('opened');\n editor.toolbar.inline.actionsOpened = false;\n\n };\n\n\n /**\n * Callback for keydowns in inline toolbar \"Insert link...\" input\n */\n let inlineToolbarAnchorInputKeydown_ = function (event) {\n\n if (event.keyCode != editor.core.keys.ENTER) {\n\n return;\n\n }\n\n let editable = editor.content.currentNode,\n storedSelection = editor.toolbar.inline.storedSelection;\n\n editor.toolbar.inline.restoreSelection(editable, storedSelection);\n editor.toolbar.inline.setAnchor(this.value);\n\n /**\n * Preventing events that will be able to happen\n */\n event.preventDefault();\n event.stopImmediatePropagation();\n\n editor.toolbar.inline.clearRange();\n\n };\n\n /** Action for link creation or for setting anchor */\n inline.createLinkAction = function (event) {\n\n var isActive = this.isLinkActive();\n\n var editable = editor.content.currentNode,\n storedSelection = editor.toolbar.inline.saveSelection(editable);\n\n /** Save globally selection */\n editor.toolbar.inline.storedSelection = storedSelection;\n\n if (isActive) {\n\n\n /**\n * Changing stored selection. if we want to remove anchor from word\n * we should remove anchor from whole word, not only selected part.\n * The solution is than we get the length of current link\n * Change start position to - end of selection minus length of anchor\n */\n editor.toolbar.inline.restoreSelection(editable, storedSelection);\n\n editor.toolbar.inline.defaultToolAction('unlink');\n\n } else {\n\n /** Create input and close buttons */\n var action = editor.draw.inputForLink();\n\n editor.nodes.inlineToolbar.actions.appendChild(action);\n\n editor.toolbar.inline.closeButtons();\n editor.toolbar.inline.showActions();\n\n /**\n * focus to input\n * Solution: https://developer.mozilla.org/ru/docs/Web/API/HTMLElement/focus\n * Prevents event after showing input and when we need to focus an input which is in unexisted form\n */\n action.focus();\n event.preventDefault();\n\n /** Callback to link action */\n editor.listeners.add(action, 'keydown', inlineToolbarAnchorInputKeydown_, false);\n\n }\n\n };\n\n inline.isLinkActive = function () {\n\n var isActive = false;\n\n editor.nodes.inlineToolbar.buttons.childNodes.forEach(function (tool) {\n\n var dataType = tool.dataset.type;\n\n if (dataType == 'link' && tool.classList.contains('hightlighted')) {\n\n isActive = true;\n\n }\n\n });\n\n return isActive;\n\n };\n\n /** default action behavior of tool */\n inline.defaultToolAction = function (type) {\n\n document.execCommand(type, false, null);\n\n };\n\n /**\n * @private\n *\n * Sets URL\n *\n * @param {String} url - URL\n */\n inline.setAnchor = function (url) {\n\n document.execCommand('createLink', false, url);\n\n /** Close after URL inserting */\n editor.toolbar.inline.closeAction();\n\n };\n\n /**\n * @private\n *\n * Saves selection\n */\n inline.saveSelection = function (containerEl) {\n\n var range = window.getSelection().getRangeAt(0),\n preSelectionRange = range.cloneRange(),\n start;\n\n preSelectionRange.selectNodeContents(containerEl);\n preSelectionRange.setEnd(range.startContainer, range.startOffset);\n\n start = preSelectionRange.toString().length;\n\n return {\n start: start,\n end: start + range.toString().length\n };\n\n };\n\n /**\n * @private\n *\n * Sets to previous selection (Range)\n *\n * @param {Element} containerEl - editable element where we restore range\n * @param {Object} savedSel - range basic information to restore\n */\n inline.restoreSelection = function (containerEl, savedSel) {\n\n var range = document.createRange(),\n charIndex = 0;\n\n range.setStart(containerEl, 0);\n range.collapse(true);\n\n var nodeStack = [ containerEl ],\n node,\n foundStart = false,\n stop = false,\n nextCharIndex;\n\n while (!stop && (node = nodeStack.pop())) {\n\n if (node.nodeType == 3) {\n\n nextCharIndex = charIndex + node.length;\n\n if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {\n\n range.setStart(node, savedSel.start - charIndex);\n foundStart = true;\n\n }\n if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {\n\n range.setEnd(node, savedSel.end - charIndex);\n stop = true;\n\n }\n charIndex = nextCharIndex;\n\n } else {\n\n var i = node.childNodes.length;\n\n while (i--) {\n\n nodeStack.push(node.childNodes[i]);\n\n }\n\n }\n\n }\n\n var sel = window.getSelection();\n\n sel.removeAllRanges();\n sel.addRange(range);\n\n };\n\n /**\n * @private\n *\n * Removes all ranges from window selection\n */\n inline.clearRange = function () {\n\n var selection = window.getSelection();\n\n selection.removeAllRanges();\n\n };\n\n /**\n * @private\n *\n * sets or removes hightlight\n */\n inline.hightlight = function (tool) {\n\n var dataType = tool.dataset.type;\n\n if (document.queryCommandState(dataType)) {\n\n editor.toolbar.inline.setButtonHighlighted(tool);\n\n } else {\n\n editor.toolbar.inline.removeButtonsHighLight(tool);\n\n }\n\n /**\n *\n * hightlight for anchors\n */\n var selection = window.getSelection(),\n tag = selection.anchorNode.parentNode;\n\n if (tag.tagName == 'A' && dataType == 'link') {\n\n editor.toolbar.inline.setButtonHighlighted(tool);\n\n }\n\n };\n\n /**\n * @private\n *\n * Mark button if text is already executed\n */\n inline.setButtonHighlighted = function (button) {\n\n button.classList.add('hightlighted');\n\n /** At link tool we also change icon */\n if (button.dataset.type == 'link') {\n\n var icon = button.childNodes[0];\n\n icon.classList.remove('ce-icon-link');\n icon.classList.add('ce-icon-unlink');\n\n }\n\n };\n\n /**\n * @private\n *\n * Removes hightlight\n */\n inline.removeButtonsHighLight = function (button) {\n\n button.classList.remove('hightlighted');\n\n /** At link tool we also change icon */\n if (button.dataset.type == 'link') {\n\n var icon = button.childNodes[0];\n\n icon.classList.remove('ce-icon-unlink');\n icon.classList.add('ce-icon-link');\n\n }\n\n };\n\n\n return inline;\n\n})({});\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/toolbar/inline.js","/**\n * Toolbar settings\n *\n * @version 1.0.5\n */\n\nmodule.exports = (function (settings) {\n\n let editor = codex.editor;\n\n settings.opened = false;\n\n settings.setting = null;\n settings.actions = null;\n\n /**\n * Append and open settings\n */\n settings.open = function (toolType) {\n\n /**\n * Append settings content\n * It's stored in tool.settings\n */\n if ( !editor.tools[toolType] || !editor.tools[toolType].makeSettings ) {\n\n return;\n\n }\n\n /**\n * Draw settings block\n */\n var settingsBlock = editor.tools[toolType].makeSettings();\n\n editor.nodes.pluginSettings.appendChild(settingsBlock);\n\n\n /** Open settings block */\n editor.nodes.blockSettings.classList.add('opened');\n this.opened = true;\n\n };\n\n /**\n * Close and clear settings\n */\n settings.close = function () {\n\n editor.nodes.blockSettings.classList.remove('opened');\n editor.nodes.pluginSettings.innerHTML = '';\n\n this.opened = false;\n\n };\n\n /**\n * @param {string} toolType - plugin type\n */\n settings.toggle = function ( toolType ) {\n\n if ( !this.opened ) {\n\n this.open(toolType);\n\n } else {\n\n this.close();\n\n }\n\n };\n\n /**\n * Here we will draw buttons and add listeners to components\n */\n settings.makeRemoveBlockButton = function () {\n\n var removeBlockWrapper = editor.draw.node('SPAN', 'ce-toolbar__remove-btn', {}),\n settingButton = editor.draw.node('SPAN', 'ce-toolbar__remove-setting', { innerHTML : '' }),\n actionWrapper = editor.draw.node('DIV', 'ce-toolbar__remove-confirmation', {}),\n confirmAction = editor.draw.node('DIV', 'ce-toolbar__remove-confirm', { textContent : 'Удалить блок' }),\n cancelAction = editor.draw.node('DIV', 'ce-toolbar__remove-cancel', { textContent : 'Отмена' });\n\n editor.listeners.add(settingButton, 'click', editor.toolbar.settings.removeButtonClicked, false);\n\n editor.listeners.add(confirmAction, 'click', editor.toolbar.settings.confirmRemovingRequest, false);\n\n editor.listeners.add(cancelAction, 'click', editor.toolbar.settings.cancelRemovingRequest, false);\n\n actionWrapper.appendChild(confirmAction);\n actionWrapper.appendChild(cancelAction);\n\n removeBlockWrapper.appendChild(settingButton);\n removeBlockWrapper.appendChild(actionWrapper);\n\n /** Save setting */\n editor.toolbar.settings.setting = settingButton;\n editor.toolbar.settings.actions = actionWrapper;\n\n return removeBlockWrapper;\n\n };\n\n settings.removeButtonClicked = function () {\n\n var action = editor.toolbar.settings.actions;\n\n if (action.classList.contains('opened')) {\n\n editor.toolbar.settings.hideRemoveActions();\n\n } else {\n\n editor.toolbar.settings.showRemoveActions();\n\n }\n\n editor.toolbar.toolbox.close();\n editor.toolbar.settings.close();\n\n };\n\n settings.cancelRemovingRequest = function () {\n\n editor.toolbar.settings.actions.classList.remove('opened');\n\n };\n\n settings.confirmRemovingRequest = function () {\n\n var currentBlock = editor.content.currentNode,\n firstLevelBlocksCount;\n\n currentBlock.remove();\n\n firstLevelBlocksCount = editor.nodes.redactor.childNodes.length;\n\n /**\n * If all blocks are removed\n */\n if (firstLevelBlocksCount === 0) {\n\n /** update currentNode variable */\n editor.content.currentNode = null;\n\n /** Inserting new empty initial block */\n editor.ui.addInitialBlock();\n\n }\n\n editor.ui.saveInputs();\n\n editor.toolbar.close();\n\n };\n\n settings.showRemoveActions = function () {\n\n editor.toolbar.settings.actions.classList.add('opened');\n\n };\n\n settings.hideRemoveActions = function () {\n\n editor.toolbar.settings.actions.classList.remove('opened');\n\n };\n\n return settings;\n\n})({});\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/toolbar/settings.js","/**\n * Codex Editor toolbox\n *\n * All tools be able to appended here\n *\n * @author Codex Team\n * @version 1.0\n */\n\nmodule.exports = (function (toolbox) {\n\n let editor = codex.editor;\n\n toolbox.opened = false;\n toolbox.openedOnBlock = null;\n\n /** Shows toolbox */\n toolbox.open = function () {\n\n /** Close setting if toolbox is opened */\n if (editor.toolbar.settings.opened) {\n\n editor.toolbar.settings.close();\n\n }\n\n /** Add 'toolbar-opened' class for current block **/\n toolbox.openedOnBlock = editor.content.currentNode;\n toolbox.openedOnBlock.classList.add('toolbar-opened');\n\n /** display toolbox */\n editor.nodes.toolbox.classList.add('opened');\n\n /** Animate plus button */\n editor.nodes.plusButton.classList.add('clicked');\n\n /** toolbox state */\n editor.toolbar.toolbox.opened = true;\n\n };\n\n /** Closes toolbox */\n toolbox.close = function () {\n\n /** Remove 'toolbar-opened' class from current block **/\n if (toolbox.openedOnBlock) toolbox.openedOnBlock.classList.remove('toolbar-opened');\n toolbox.openedOnBlock = null;\n\n /** Makes toolbox disappear */\n editor.nodes.toolbox.classList.remove('opened');\n\n /** Rotate plus button */\n editor.nodes.plusButton.classList.remove('clicked');\n\n /** toolbox state */\n editor.toolbar.toolbox.opened = false;\n\n editor.toolbar.current = null;\n\n };\n\n toolbox.leaf = function () {\n\n let currentTool = editor.toolbar.current,\n tools = Object.keys(editor.tools),\n barButtons = editor.nodes.toolbarButtons,\n nextToolIndex = 0,\n toolToSelect,\n visibleTool,\n tool;\n\n if ( !currentTool ) {\n\n /** Get first tool from object*/\n for(tool in editor.tools) {\n\n if (editor.tools[tool].displayInToolbox) {\n\n break;\n\n }\n\n nextToolIndex ++;\n\n }\n\n } else {\n\n nextToolIndex = (tools.indexOf(currentTool) + 1) % tools.length;\n visibleTool = tools[nextToolIndex];\n\n while (!editor.tools[visibleTool].displayInToolbox) {\n\n nextToolIndex = (nextToolIndex + 1) % tools.length;\n visibleTool = tools[nextToolIndex];\n\n }\n\n }\n\n toolToSelect = tools[nextToolIndex];\n\n for ( var button in barButtons ) {\n\n barButtons[button].classList.remove('selected');\n\n }\n\n barButtons[toolToSelect].classList.add('selected');\n editor.toolbar.current = toolToSelect;\n\n };\n\n /**\n * Transforming selected node type into selected toolbar element type\n * @param {event} event\n */\n toolbox.toolClicked = function (event) {\n\n /**\n * UNREPLACEBLE_TOOLS this types of tools are forbidden to replace even they are empty\n */\n var UNREPLACEBLE_TOOLS = ['image', 'link', 'list', 'instagram', 'twitter', 'embed'],\n tool = editor.tools[editor.toolbar.current],\n workingNode = editor.content.currentNode,\n currentInputIndex = editor.caret.inputIndex,\n newBlockContent,\n appendCallback,\n blockData;\n\n /** Make block from plugin */\n newBlockContent = tool.render();\n\n /** information about block */\n blockData = {\n block : newBlockContent,\n type : tool.type,\n stretched : false\n };\n\n if (\n workingNode &&\n UNREPLACEBLE_TOOLS.indexOf(workingNode.dataset.tool) === -1 &&\n workingNode.textContent.trim() === ''\n ) {\n\n /** Replace current block */\n editor.content.switchBlock(workingNode, newBlockContent, tool.type);\n\n } else {\n\n /** Insert new Block from plugin */\n editor.content.insertBlock(blockData);\n\n /** increase input index */\n currentInputIndex++;\n\n }\n\n /** Fire tool append callback */\n appendCallback = tool.appendCallback;\n\n if (appendCallback && typeof appendCallback == 'function') {\n\n appendCallback.call(event);\n\n }\n\n window.setTimeout(function () {\n\n /** Set caret to current block */\n editor.caret.setToBlock(currentInputIndex);\n\n }, 10);\n\n\n /**\n * Changing current Node\n */\n editor.content.workingNodeChanged();\n\n /**\n * Move toolbar when node is changed\n */\n editor.toolbar.move();\n\n };\n\n return toolbox;\n\n})({});\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/toolbar/toolbox.js","/**\n * Codex Editor Anchors module\n *\n * @author Codex Team\n * @version 1.0\n */\n\nmodule.exports = function (anchors) {\n\n let editor = codex.editor;\n\n anchors.input = null;\n anchors.currentNode = null;\n\n anchors.settingsOpened = function (currentBlock) {\n\n anchors.currentNode = currentBlock;\n anchors.input.value = anchors.currentNode.dataset.anchor || '';\n\n };\n\n anchors.anchorChanged = function (e) {\n\n var newAnchor = e.target.value = anchors.rusToTranslit(e.target.value);\n\n anchors.currentNode.dataset.anchor = newAnchor;\n\n if (newAnchor.trim() !== '') {\n\n anchors.currentNode.classList.add(editor.ui.className.BLOCK_WITH_ANCHOR);\n\n } else {\n\n anchors.currentNode.classList.remove(editor.ui.className.BLOCK_WITH_ANCHOR);\n\n }\n\n };\n\n anchors.keyDownOnAnchorInput = function (e) {\n\n if (e.keyCode == editor.core.keys.ENTER) {\n\n e.preventDefault();\n e.stopPropagation();\n\n e.target.blur();\n editor.toolbar.settings.close();\n\n }\n\n };\n\n anchors.keyUpOnAnchorInput = function (e) {\n\n if (e.keyCode >= editor.core.keys.LEFT && e.keyCode <= editor.core.keys.DOWN) {\n\n e.stopPropagation();\n\n }\n\n };\n\n anchors.rusToTranslit = function (string) {\n\n var ru = [\n 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й',\n 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф',\n 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ь', 'Ы', 'Ь', 'Э', 'Ю', 'Я'\n ],\n en = [\n 'A', 'B', 'V', 'G', 'D', 'E', 'E', 'Zh', 'Z', 'I', 'Y',\n 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F',\n 'H', 'C', 'Ch', 'Sh', 'Sch', '', 'Y', '', 'E', 'Yu', 'Ya'\n ];\n\n for (var i = 0; i < ru.length; i++) {\n\n string = string.split(ru[i]).join(en[i]);\n string = string.split(ru[i].toLowerCase()).join(en[i].toLowerCase());\n\n }\n\n string = string.replace(/[^0-9a-zA-Z_]+/g, '-');\n\n return string;\n\n };\n\n return anchors;\n\n}({});\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/_anchors.js","/**\n * @module Codex Editor Callbacks module\n * @description Module works with editor added Elements\n *\n * @author Codex Team\n * @version 1.4.0\n */\n\nmodule.exports = (function (callbacks) {\n\n let editor = codex.editor;\n\n /**\n * used by UI module\n * @description Routes all keydowns on document\n * @param {Object} event\n */\n callbacks.globalKeydown = function (event) {\n\n switch (event.keyCode) {\n\n case editor.core.keys.ENTER : enterKeyPressed_(event); break;\n\n }\n\n };\n\n /**\n * used by UI module\n * @description Routes all keydowns on redactors area\n * @param {Object} event\n */\n callbacks.redactorKeyDown = function (event) {\n\n switch (event.keyCode) {\n\n case editor.core.keys.TAB : tabKeyPressedOnRedactorsZone_(event); break;\n case editor.core.keys.ENTER : enterKeyPressedOnRedactorsZone_(event); break;\n case editor.core.keys.ESC : escapeKeyPressedOnRedactorsZone_(event); break;\n default : defaultKeyPressedOnRedactorsZone_(event); break;\n\n }\n\n };\n\n /**\n * used by UI module\n * @description Routes all keyup events\n * @param {Object} event\n */\n callbacks.globalKeyup = function (event) {\n\n switch (event.keyCode) {\n\n case editor.core.keys.UP :\n case editor.core.keys.LEFT :\n case editor.core.keys.RIGHT :\n case editor.core.keys.DOWN : arrowKeyPressed_(event); break;\n\n }\n\n };\n\n /**\n * @param {Object} event\n * @private\n *\n * Handles behaviour when tab pressed\n * @description if Content is empty show toolbox (if it is closed) or leaf tools\n * uses Toolbars toolbox module to handle the situation\n */\n var tabKeyPressedOnRedactorsZone_ = function (event) {\n\n /**\n * Wait for solution. Would like to know the behaviour\n * @todo Add spaces\n */\n event.preventDefault();\n\n\n if (!editor.core.isBlockEmpty(editor.content.currentNode)) {\n\n return;\n\n }\n\n if ( !editor.toolbar.opened ) {\n\n editor.toolbar.open();\n\n }\n\n if (editor.toolbar.opened && !editor.toolbar.toolbox.opened) {\n\n editor.toolbar.toolbox.open();\n\n } else {\n\n editor.toolbar.toolbox.leaf();\n\n }\n\n };\n\n /**\n * Handles global EnterKey Press\n * @see enterPressedOnBlock_\n * @param {Object} event\n */\n var enterKeyPressed_ = function () {\n\n if (editor.content.editorAreaHightlighted) {\n\n /**\n * it means that we lose input index, saved index before is not correct\n * therefore we need to set caret when we insert new block\n */\n editor.caret.inputIndex = -1;\n\n enterPressedOnBlock_();\n\n }\n\n };\n\n /**\n * Callback for enter key pressing in first-level block area\n *\n * @param {Event} event\n * @private\n *\n * @description Inserts new block with initial type from settings\n */\n var enterPressedOnBlock_ = function () {\n\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 }, true );\n\n editor.toolbar.move();\n editor.toolbar.open();\n\n };\n\n\n /**\n * ENTER key handler\n *\n * @param {Object} event\n * @private\n *\n * @description Makes new block with initial type from settings\n */\n var enterKeyPressedOnRedactorsZone_ = function (event) {\n\n if (event.target.contentEditable == 'true') {\n\n /** Update input index */\n editor.caret.saveCurrentInputIndex();\n\n }\n\n var currentInputIndex = editor.caret.getCurrentInputIndex() || 0,\n workingNode = editor.content.currentNode,\n tool = workingNode.dataset.tool,\n isEnterPressedOnToolbar = editor.toolbar.opened &&\n editor.toolbar.current &&\n event.target == editor.state.inputs[currentInputIndex];\n\n /** The list of tools which needs the default browser behaviour */\n var enableLineBreaks = editor.tools[tool].enableLineBreaks;\n\n /** This type of block creates when enter is pressed */\n var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;\n\n /**\n * When toolbar is opened, select tool instead of making new paragraph\n */\n if ( isEnterPressedOnToolbar ) {\n\n event.preventDefault();\n\n editor.toolbar.toolbox.toolClicked(event);\n\n editor.toolbar.close();\n\n /**\n * Stop other listeners callback executions\n */\n event.stopPropagation();\n event.stopImmediatePropagation();\n\n return;\n\n }\n\n /**\n * Allow paragraph lineBreaks with shift enter\n * Or if shiftkey pressed and enter and enabledLineBreaks, the let new block creation\n */\n if ( event.shiftKey || enableLineBreaks ) {\n\n event.stopPropagation();\n event.stopImmediatePropagation();\n return;\n\n }\n\n var currentSelection = window.getSelection(),\n currentSelectedNode = currentSelection.anchorNode,\n caretAtTheEndOfText = editor.caret.position.atTheEnd(),\n isTextNodeHasParentBetweenContenteditable = false;\n\n /**\n * Allow making new

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

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

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

    ') + '

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

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

    ) whit content, that should be inserted\n */\n var insertPastedParagraphs = function (paragraphs) {\n\n var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin,\n currentNode = editor.content.currentNode;\n\n\n paragraphs.forEach(function (paragraph) {\n\n /** Don't allow empty paragraphs */\n if (editor.core.isBlockEmpty(paragraph)) {\n\n return;\n\n }\n\n editor.content.insertBlock({\n type : NEW_BLOCK_TYPE,\n block : editor.tools[NEW_BLOCK_TYPE].render({\n text : paragraph.innerHTML\n })\n });\n\n editor.caret.inputIndex++;\n\n });\n\n editor.caret.setToPreviousBlock(editor.caret.getCurrentInputIndex() + 1);\n\n\n /**\n * If there was no data in working node, remove it\n */\n if (editor.core.isBlockEmpty(currentNode)) {\n\n currentNode.remove();\n editor.ui.saveInputs();\n\n }\n\n\n };\n\n /**\n * Inserts node content at the caret position\n *\n * @param {Node} node - DOM node (could be DocumentFragment), that should be inserted at the caret location\n */\n var emulateUserAgentBehaviour = function (node) {\n\n var newNode;\n\n if (node.childElementCount) {\n\n newNode = document.createDocumentFragment();\n\n node.childNodes.forEach(function (current) {\n\n if (!editor.core.isDomNode(current) && current.data.trim() === '') {\n\n return;\n\n }\n\n newNode.appendChild(current.cloneNode(true));\n\n });\n\n } else {\n\n newNode = document.createTextNode(node.textContent);\n\n }\n\n editor.caret.insertNode(newNode);\n\n };\n\n\n return paste;\n\n}({});\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/_paste.js","/**\n * Codex Editor Renderer Module\n *\n * @author Codex Team\n * @version 1.0\n */\n\nmodule.exports = (function (renderer) {\n\n let editor = codex.editor;\n\n /**\n * Asyncronously parses input JSON to redactor blocks\n */\n renderer.makeBlocksFromData = function () {\n\n /**\n * If redactor is empty, add first paragraph to start writing\n */\n if (editor.core.isEmpty(editor.state.blocks) || !editor.state.blocks.items.length) {\n\n editor.ui.addInitialBlock();\n return;\n\n }\n\n Promise.resolve()\n\n /** First, get JSON from state */\n .then(function () {\n\n return editor.state.blocks;\n\n })\n\n /** Then, start to iterate they */\n .then(editor.renderer.appendBlocks)\n\n /** Write log if something goes wrong */\n .catch(function (error) {\n\n editor.core.log('Error while parsing JSON: %o', 'error', error);\n\n });\n\n };\n\n /**\n * Parses JSON to blocks\n * @param {object} data\n * @return Primise -> nodeList\n */\n renderer.appendBlocks = function (data) {\n\n var blocks = data.items;\n\n /**\n * Sequence of one-by-one blocks appending\n * Uses to save blocks order after async-handler\n */\n var nodeSequence = Promise.resolve();\n\n for (var index = 0; index < blocks.length ; index++ ) {\n\n /** Add node to sequence at specified index */\n editor.renderer.appendNodeAtIndex(nodeSequence, blocks, index);\n\n }\n\n };\n\n /**\n * Append node at specified index\n */\n renderer.appendNodeAtIndex = function (nodeSequence, blocks, index) {\n\n /** We need to append node to sequence */\n nodeSequence\n\n /** first, get node async-aware */\n .then(function () {\n\n return editor.renderer.getNodeAsync(blocks, index);\n\n })\n\n /**\n * second, compose editor-block from JSON object\n */\n .then(editor.renderer.createBlockFromData)\n\n /**\n * now insert block to redactor\n */\n .then(function (blockData) {\n\n /**\n * blockData has 'block', 'type' and 'stretched' information\n */\n editor.content.insertBlock(blockData);\n\n /** Pass created block to next step */\n return blockData.block;\n\n })\n\n /** Log if something wrong with node */\n .catch(function (error) {\n\n editor.core.log('Node skipped while parsing because %o', 'error', error);\n\n });\n\n };\n\n /**\n * Asynchronously returns block data from blocksList by index\n * @return Promise to node\n */\n renderer.getNodeAsync = function (blocksList, index) {\n\n return Promise.resolve().then(function () {\n\n return {\n tool : blocksList[index],\n position : index\n };\n\n });\n\n };\n\n /**\n * Creates editor block by JSON-data\n *\n * @uses render method of each plugin\n *\n * @param {Object} toolData.tool\n * { header : {\n * text: '',\n * type: 'H3', ...\n * }\n * }\n * @param {Number} toolData.position - index in input-blocks array\n * @return {Object} with type and Element\n */\n renderer.createBlockFromData = function ( toolData ) {\n\n /** New parser */\n var block,\n tool = toolData.tool,\n pluginName = tool.type;\n\n /** Get first key of object that stores plugin name */\n // for (var pluginName in blockData) break;\n\n /** Check for plugin existance */\n if (!editor.tools[pluginName]) {\n\n throw Error(`Plugin «${pluginName}» not found`);\n\n }\n\n /** Check for plugin having render method */\n if (typeof editor.tools[pluginName].render != 'function') {\n\n throw Error(`Plugin «${pluginName}» must have «render» method`);\n\n }\n\n if ( editor.tools[pluginName].available === false ) {\n\n block = editor.draw.unavailableBlock();\n\n block.innerHTML = editor.tools[pluginName].loadingMessage;\n\n /**\n * Saver will extract data from initial block data by position in array\n */\n block.dataset.inputPosition = toolData.position;\n\n } else {\n\n /** New Parser */\n block = editor.tools[pluginName].render(tool.data);\n\n }\n\n /** is first-level block stretched */\n var stretched = editor.tools[pluginName].isStretched || false;\n\n /** Retrun type and block */\n return {\n type : pluginName,\n block : block,\n stretched : stretched\n };\n\n };\n\n return renderer;\n\n})({});\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/_renderer.js","/**\n * Codex Sanitizer\n */\n\nmodule.exports = (function (sanitizer) {\n\n /** HTML Janitor library */\n let janitor = require('html-janitor');\n\n /** Codex Editor */\n let editor = codex.editor;\n\n sanitizer.prepare = function () {\n\n if (editor.settings.sanitizer && !editor.core.isEmpty(editor.settings.sanitizer)) {\n\n Config.CUSTOM = editor.settings.sanitizer;\n\n }\n\n };\n\n /**\n * Basic config\n */\n var Config = {\n\n /** User configuration */\n CUSTOM : null,\n\n BASIC : {\n\n tags: {\n p: {},\n a: {\n href: true,\n target: '_blank',\n rel: 'nofollow'\n }\n }\n }\n };\n\n sanitizer.Config = Config;\n\n /**\n *\n * @param userCustomConfig\n * @returns {*}\n * @private\n *\n * @description If developer uses editor's API, then he can customize sane restrictions.\n * Or, sane 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 BASIC Default configation\n */\n let init_ = function (userCustomConfig) {\n\n let configuration = userCustomConfig || Config.CUSTOM || Config.BASIC;\n\n return new janitor(configuration);\n\n };\n\n /**\n * Cleans string from unwanted tags\n * @protected\n * @param {String} dirtyString - taint string\n * @param {Object} customConfig - allowed tags\n */\n sanitizer.clean = function (dirtyString, customConfig) {\n\n let janitorInstance = init_(customConfig);\n\n return janitorInstance.clean(dirtyString);\n\n };\n\n return sanitizer;\n\n})({});\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/_sanitizer.js","/**\n * Codex Editor Saver\n *\n * @author Codex Team\n * @version 1.1.0\n */\n\nmodule.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\n\n// WEBPACK FOOTER //\n// ./src/components/modules/_saver.js","/**\n *\n * Codex.Editor Transport Module\n *\n * @copyright 2017 Codex-Team\n * @version 1.2.0\n */\n\nmodule.exports = (function (transport) {\n\n let editor = codex.editor;\n\n\n /**\n * @private {Object} current XmlHttpRequest instance\n */\n var currentRequest = null;\n\n\n /**\n * @type {null} | {DOMElement} input - keeps input element in memory\n */\n transport.input = null;\n\n /**\n * @property {Object} arguments - keep plugin settings and defined callbacks\n */\n transport.arguments = null;\n\n /**\n * Prepares input element where will be files\n */\n transport.prepare = function () {\n\n let input = editor.draw.node( 'INPUT', '', { type : 'file' } );\n\n editor.listeners.add(input, 'change', editor.transport.fileSelected);\n editor.transport.input = input;\n\n };\n\n /** Clear input when files is uploaded */\n transport.clearInput = function () {\n\n /** Remove old input */\n transport.input = null;\n\n /** Prepare new one */\n transport.prepare();\n\n };\n\n /**\n * Callback for file selection\n * @param {Event} event\n */\n transport.fileSelected = function () {\n\n var input = this,\n i,\n files = input.files,\n formData = new FormData();\n\n if (editor.transport.arguments.multiple === true) {\n\n for ( i = 0; i < files.length; i++) {\n\n formData.append('files[]', files[i], files[i].name);\n\n }\n\n } else {\n\n formData.append('files', files[0], files[0].name);\n\n }\n\n currentRequest = editor.core.ajax({\n type : 'POST',\n data : formData,\n url : editor.transport.arguments.url,\n beforeSend : editor.transport.arguments.beforeSend,\n success : editor.transport.arguments.success,\n error : editor.transport.arguments.error,\n progress : editor.transport.arguments.progress\n });\n\n /** Clear input */\n transport.clearInput();\n\n };\n\n /**\n * Use plugin callbacks\n * @protected\n *\n * @param {Object} args - can have :\n * @param {String} args.url - fetch URL\n * @param {Function} args.beforeSend - function calls before sending ajax\n * @param {Function} args.success - success callback\n * @param {Function} args.error - on error handler\n * @param {Function} args.progress - xhr onprogress handler\n * @param {Boolean} args.multiple - allow select several files\n * @param {String} args.accept - adds accept attribute\n */\n transport.selectAndUpload = function (args) {\n\n transport.arguments = args;\n\n if ( args.multiple === true) {\n\n transport.input.setAttribute('multiple', 'multiple');\n\n }\n\n if ( args.accept ) {\n\n transport.input.setAttribute('accept', args.accept);\n\n }\n\n transport.input.click();\n\n };\n\n transport.abort = function () {\n\n currentRequest.abort();\n\n currentRequest = null;\n\n };\n\n return transport;\n\n})({});\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/_transport.js","/**\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 *\n * @version 1.0.0\n */\nclass Events {\n\n /**\n * @param Editor\n * @param Editor.modules {@link CodexEditor#moduleInstances}\n * @param Editor.config {@link CodexEditor#configuration}\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * @constructor\n *\n * @property {Object} subscribers - all subscribers grouped by event name\n */\n constructor() {\n\n this.subscribers = {};\n this.Editor = null;\n\n }\n\n /**\n * @param {String} eventName - event name\n * @param {Function} callback - subscriber\n */\n on(eventName, callback) {\n\n if (!(eventName in this.subscribers)) {\n\n this.subscribers[eventName] = [];\n\n }\n\n // group by events\n this.subscribers[eventName].push(callback);\n\n }\n\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\n this.subscribers[eventName].reduce(function (previousData, currentHandler) {\n\n let newData = currentHandler(previousData);\n\n return newData ? newData : previousData;\n\n }, data);\n\n }\n\n /**\n * Destroyer\n */\n destroy() {\n\n this.Editor = null;\n this.subscribers = null;\n\n }\n\n}\n\nmodule.exports = Events;\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/events.js","/**\n * DOM manipulations\n */\nimport $ from '../dom';\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] [Remove Block] . |\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 * @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.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.removeBlockButton - Remove Block 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 */\nclass Toolbar {\n\n /**\n * @constructor\n */\n constructor() {\n\n this.Editor = null;\n\n this.nodes = {\n wrapper : null,\n content : null,\n actions : null,\n\n // Content Zone\n plusButton : null,\n toolbox : null,\n\n // Actions Zone\n settingsToggler : null,\n removeBlockButton: null,\n settings: null,\n\n // Settings Zone: Plugin Settings and Default Settings\n pluginSettings: null,\n defaultSettings: null,\n };\n\n this.CSS = {\n toolbar: 'ce-toolbar',\n content: 'ce-toolbar__content',\n actions: 'ce-toolbar__actions',\n\n // Content Zone\n toolbox: 'ce-toolbar__toolbox',\n plusButton: 'ce-toolbar__plus',\n\n // Actions Zone\n settingsToggler: 'ce-toolbar__settings-btn',\n removeBlockButton: 'ce-toolbar__remove-btn',\n\n // Settings Panel\n settings: 'ce-settings',\n defaultSettings: 'ce-settings_default',\n pluginSettings: 'ce-settings_plugin',\n };\n\n }\n\n /**\n * Editor modules setter\n * @param {object} Editor - available editor modules\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * Makes toolbar\n */\n make() {\n\n this.nodes.wrapper = $.make('div', this.CSS.toolbar);\n\n /**\n * Make Content Zone and Actions Zone\n */\n ['content', 'actions'].forEach( el => {\n\n this.nodes[el] = $.make('div', this.CSS[el]);\n $.append(this.nodes.wrapper, this.nodes[el]);\n\n });\n\n\n /**\n * Fill Content Zone:\n * - Plus Button\n * - Toolbox\n */\n ['plusButton', 'toolbox'].forEach( el => {\n\n this.nodes[el] = $.make('div', this.CSS[el]);\n $.append(this.nodes.content, this.nodes[el]);\n\n });\n\n /**\n * Fill Actions Zone:\n * - Settings Toggler\n * - Remove Block Button\n * - Settings Panel\n */\n this.nodes.settingsToggler = $.make('span', this.CSS.settingsToggler);\n this.nodes.removeBlockButton = this.makeRemoveBlockButton();\n\n $.append(this.nodes.actions, [this.nodes.settingsToggler, this.nodes.removeBlockButton]);\n\n /**\n * Make and append Settings Panel\n */\n this.makeBlockSettingsPanel();\n\n /**\n * Append toolbar to the Editor\n */\n $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\n\n }\n\n /**\n * Panel with block settings with 2 sections:\n *\n * @return {Element}\n */\n makeBlockSettingsPanel() {\n\n this.nodes.settings = $.make('div', this.CSS.settings);\n\n this.nodes.pluginSettings = $.make('div', this.CSS.pluginSettings);\n this.nodes.defaultSettings = $.make('div', this.CSS.defaultSettings);\n\n $.append(this.nodes.settings, [this.nodes.pluginSettings, this.nodes.defaultSettings]);\n $.append(this.nodes.actions, this.nodes.settings);\n\n }\n\n /**\n * Makes Remove Block button, and confirmation panel\n * @return {Element} wrapper with button and panel\n */\n makeRemoveBlockButton() {\n\n /**\n * @todo add confirmation panel and handlers\n * @see {@link settings#makeRemoveBlockButton}\n */\n return $.make('span', this.CSS.removeBlockButton);\n\n }\n\n}\n\nmodule.exports = Toolbar;\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/toolbar.js","/**\n * DOM manupulations helper\n */\nexport default class Dom {\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, attributes) {\n\n var el = document.createElement(tagName);\n\n if ( Array.isArray(classNames) ) {\n\n el.classList.add(...classNames);\n\n } else if( classNames ) {\n\n el.classList.add(classNames);\n\n }\n\n for (let attrName in attributes) {\n\n el[attrName] = attributes[attrName];\n\n }\n\n return el;\n\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\n if ( Array.isArray(elements) ) {\n\n elements.forEach( el => parent.appendChild(el) );\n\n } else {\n\n parent.appendChild(elements);\n\n }\n\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\n return el.querySelector(selector);\n\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\n return el.querySelectorAll(selector);\n\n }\n\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/dom.js","/**\n * Codex Editor toolbar module\n *\n * Contains:\n * - Inline toolbox\n * - Toolbox within plus button\n * - Settings section\n *\n * @author Codex Team\n * @version 1.0\n */\n\nmodule.exports = (function (toolbar) {\n\n let editor = codex.editor;\n\n toolbar.settings = require('./settings');\n toolbar.inline = require('./inline');\n toolbar.toolbox = require('./toolbox');\n\n /**\n * Margin between focused node and toolbar\n */\n toolbar.defaultToolbarHeight = 49;\n\n toolbar.defaultOffset = 34;\n\n toolbar.opened = false;\n\n toolbar.current = null;\n\n /**\n * @protected\n */\n toolbar.open = function () {\n\n if (editor.hideToolbar) {\n\n return;\n\n }\n\n let toolType = editor.content.currentNode.dataset.tool;\n\n if (!editor.tools[toolType] || !editor.tools[toolType].makeSettings ) {\n\n editor.nodes.showSettingsButton.classList.add('hide');\n\n } else {\n\n editor.nodes.showSettingsButton.classList.remove('hide');\n\n }\n\n editor.nodes.toolbar.classList.add('opened');\n this.opened = true;\n\n };\n\n /**\n * @protected\n */\n toolbar.close = function () {\n\n editor.nodes.toolbar.classList.remove('opened');\n\n toolbar.opened = false;\n toolbar.current = null;\n\n for (var button in editor.nodes.toolbarButtons) {\n\n editor.nodes.toolbarButtons[button].classList.remove('selected');\n\n }\n\n /** Close toolbox when toolbar is not displayed */\n editor.toolbar.toolbox.close();\n editor.toolbar.settings.close();\n\n };\n\n toolbar.toggle = function () {\n\n if ( !this.opened ) {\n\n this.open();\n\n } else {\n\n this.close();\n\n }\n\n };\n\n toolbar.hidePlusButton = function () {\n\n editor.nodes.plusButton.classList.add('hide');\n\n };\n\n toolbar.showPlusButton = function () {\n\n editor.nodes.plusButton.classList.remove('hide');\n\n };\n\n /**\n * Moving toolbar to the specified node\n */\n toolbar.move = function () {\n\n /** Close Toolbox when we move toolbar */\n editor.toolbar.toolbox.close();\n\n if (!editor.content.currentNode) {\n\n return;\n\n }\n\n var newYCoordinate = editor.content.currentNode.offsetTop - (editor.toolbar.defaultToolbarHeight / 2) + editor.toolbar.defaultOffset;\n\n editor.nodes.toolbar.style.transform = `translate3D(0, ${Math.floor(newYCoordinate)}px, 0)`;\n\n /** Close trash actions */\n editor.toolbar.settings.hideRemoveActions();\n\n };\n\n return toolbar;\n\n})({});\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/toolbar/toolbar.js","/**\n * @module Codex Editor Tools Submodule\n *\n * Creates Instances from Plugins and binds external config to the instances\n */\n\n/**\n * Load user defined tools\n * Tools must contain the following important objects:\n *\n * @typedef {Object} ToolsConfig\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 */\n\n/**\n * @typedef {Object} Tool\n * @property render\n * @property save\n * @property settings\n * @property validate\n */\n\n/**\n * Class properties:\n *\n * @property {String} name - name of this module\n * @property {Object[]} toolInstances - list of tool instances\n * @property {Tools[]} available - available Tools\n * @property {Tools[]} unavailable - unavailable Tools\n * @property {Object} toolsClasses - all classes\n * @property {EditorConfig} config - Editor config\n */\nlet util = require('../util');\n\nclass Tools {\n\n /**\n * Returns available Tools\n * @return {Tool[]}\n */\n get available() {\n\n return this.toolsAvailable;\n\n }\n\n /**\n * Returns unavailable Tools\n * @return {Tool[]}\n */\n get unavailable() {\n\n return this.toolsUnavailable;\n\n }\n\n /**\n * @param Editor\n * @param Editor.modules {@link CodexEditor#moduleInstances}\n * @param Editor.config {@link CodexEditor#configuration}\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * If config wasn't passed by user\n * @return {ToolsConfig}\n */\n get defaultConfig() {\n\n return {\n iconClassName : 'default-icon',\n displayInToolbox : false,\n enableLineBreaks : false\n };\n\n }\n\n /**\n * @constructor\n *\n * @param {ToolsConfig} config\n */\n constructor({ config }) {\n\n this.config = config;\n\n this.toolClasses = {};\n this.toolsAvailable = {};\n this.toolsUnavailable = {};\n\n }\n\n /**\n * Creates instances via passed or default configuration\n * @return {boolean}\n */\n prepare() {\n\n let self = this;\n\n if (!this.config.hasOwnProperty('tools')) {\n\n return Promise.reject(\"Can't start without tools\");\n\n }\n\n for(let toolName in this.config.tools) {\n\n this.toolClasses[toolName] = this.config.tools[toolName];\n\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\n return Promise.resolve();\n\n }\n\n /**\n * to see how it works {@link Util#sequence}\n */\n return util.sequence(sequenceData, (data) => {\n\n this.success(data);\n\n }, (data) => {\n\n this.fallback(data);\n\n });\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 sequently\n */\n getListOfPrepareFunctions() {\n\n let toolPreparationList = [];\n\n for(let toolName in this.toolClasses) {\n\n let toolClass = this.toolClasses[toolName];\n\n if (typeof toolClass.prepare === 'function') {\n\n toolPreparationList.push({\n function : toolClass.prepare,\n data : {\n toolName\n }\n });\n\n }\n\n }\n\n return toolPreparationList;\n\n }\n\n /**\n * @param {ChainData.data} data - append tool to available list\n */\n success(data) {\n\n this.toolsAvailable[data.toolName] = this.toolClasses[data.toolName];\n\n }\n\n /**\n * @param {ChainData.data} data - append tool to unavailable list\n */\n fallback(data) {\n\n this.toolsUnavailable[data.toolName] = this.toolClasses[data.toolName];\n\n }\n\n /**\n * Returns all tools\n * @return {Array}\n */\n getTools() {\n\n return this.toolInstances;\n\n }\n\n}\n\nmodule.exports = Tools;\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/tools.js","/**\n * Module UI\n *\n * @type {UI}\n */\n// let className = {\n\n/**\n * @const {string} BLOCK_CLASSNAME - redactor blocks name\n */\n// BLOCK_CLASSNAME : 'ce-block',\n\n/**\n * @const {String} wrapper for plugins content\n */\n// BLOCK_CONTENT : 'ce-block__content',\n\n/**\n * @const {String} BLOCK_STRETCHED - makes block stretched\n */\n// BLOCK_STRETCHED : 'ce-block--stretched',\n\n/**\n * @const {String} BLOCK_HIGHLIGHTED - adds background\n */\n// BLOCK_HIGHLIGHTED : 'ce-block--focused',\n\n/**\n * @const {String} - for all default settings\n */\n// SETTINGS_ITEM : 'ce-settings__item'\n// };\n\nlet CSS = {\n editorWrapper : 'codex-editor',\n editorZone : 'ce-redactor'\n};\n\n\nimport $ from '../dom';\n\n\n/**\n * @class\n *\n * @classdesc Makes CodeX Editor UI:\n * \n * \n * \n * \n * \n *\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.wrapper - element where we need to append redactor\n * @property {Element} nodes.wrapper - \n * @property {Element} nodes.redactor - \n */\nclass UI {\n\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor({ config }) {\n\n this.config = config;\n this.Editor = null;\n\n this.nodes = {\n holder: null,\n wrapper: null,\n redactor: null\n };\n\n }\n\n\n /**\n * Editor modules setter\n * @param {object} Editor - available editor modules\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * @protected\n *\n * Making main interface\n */\n prepare() {\n\n return new Promise( (resolve, reject) => {\n\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\n reject(Error(\"Holder wasn't found by ID: #\" + this.config.holderId));\n return;\n\n }\n\n /**\n * Create and save main UI elements\n */\n this.nodes.wrapper = $.make('div', CSS.editorWrapper);\n this.nodes.redactor = $.make('div', CSS.editorZone);\n\n this.nodes.wrapper.appendChild(this.nodes.redactor);\n this.nodes.holder.appendChild(this.nodes.wrapper);\n\n /**\n * Make toolbar\n */\n this.Editor.Toolbar.make();\n\n /**\n * Load and append CSS\n */\n this.loadStyles();\n\n resolve();\n\n })\n\n /** Add toolbox tools */\n // .then(addTools_)\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\n console.error(e);\n\n // editor.core.log(\"Can't draw editor interface\");\n\n });\n\n }\n\n loadStyles() {\n\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}\n\nmodule.exports = UI;\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// * @private\n// * Append tools passed in editor.tools\n// */\n// var addTools_ = function () {\n//\n// var tool,\n// toolName,\n// toolButton;\n//\n// for ( toolName in editor.settings.tools ) {\n//\n// tool = editor.settings.tools[toolName];\n//\n// editor.tools[toolName] = tool;\n//\n// if (!tool.iconClassname && tool.displayInToolbox) {\n//\n// editor.core.log('Toolbar icon classname missed. Tool %o skipped', 'warn', toolName);\n// continue;\n//\n// }\n//\n// if (typeof tool.render != 'function') {\n//\n// editor.core.log('render method missed. Tool %o skipped', 'warn', toolName);\n// continue;\n//\n// }\n//\n// if (!tool.displayInToolbox) {\n//\n// continue;\n//\n// } else {\n//\n// /** if tools is for toolbox */\n// toolButton = editor.draw.toolbarButton(toolName, tool.iconClassname);\n//\n// editor.nodes.toolbox.appendChild(toolButton);\n//\n// editor.nodes.toolbarButtons[toolName] = toolButton;\n//\n// }\n//\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\n\n// WEBPACK FOOTER //\n// ./src/components/modules/ui.js","/**\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 : 'paragraph',\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 * ...\n */\n\n'use strict';\n\n/**\n * Require Editor modules places in components/modules dir\n */\n// eslint-disable-next-line\nlet modules = editorModules.map( module => {\n\n return require('./components/modules/' + module );\n\n});\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 */\nmodule.exports = class CodexEditor {\n\n /** Editor version */\n static get version() {\n\n return VERSION;\n\n }\n\n /**\n * @param {EditorConfig} config - user configuration\n *\n */\n constructor(config) {\n\n /**\n * Configuration object\n */\n this.config = {};\n\n /**\n * Editor Components\n */\n this.moduleInstances = {};\n\n Promise.resolve()\n .then(() => {\n\n this.configuration = config;\n\n })\n .then(() => this.init())\n .then(() => this.start())\n .then(() => {\n\n console.log('CodeX Editor is ready');\n\n })\n .catch(error => {\n\n console.log('CodeX Editor does not ready beecause of %o', error);\n\n });\n\n }\n\n /**\n * Setting for configuration\n * @param {Object} config\n */\n set configuration(config = {}) {\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\n }\n\n /**\n * Returns private property\n * @returns {{}|*}\n */\n get configuration() {\n\n return this.config;\n\n }\n\n /**\n * Initializes modules:\n * - make and save instances\n * - configure\n */\n init() {\n\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 /**\n * Make modules instances and save it to the @property this.moduleInstances\n */\n constructModules() {\n\n modules.forEach( Module => {\n\n try {\n\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\n this.moduleInstances[Module.displayName] = new Module({\n config : this.configuration\n });\n\n } catch ( e ) {\n\n console.log('Module %o skipped because %o', Module, e);\n\n }\n\n });\n\n }\n\n /**\n * Modules instances configuration:\n * - pass other modules to the 'state' property\n * - ...\n */\n configureModules() {\n\n for(let name in this.moduleInstances) {\n\n /**\n * Module does not need self-instance\n */\n this.moduleInstances[name].state = this.getModulesDiff( name );\n\n }\n\n }\n\n /**\n * Return modules without passed name\n */\n getModulesDiff( name ) {\n\n let diff = {};\n\n for(let moduleName in this.moduleInstances) {\n\n /**\n * Skip module with passed name\n */\n if (moduleName === name) {\n\n continue;\n\n }\n diff[moduleName] = this.moduleInstances[moduleName];\n\n }\n\n return diff;\n\n }\n\n /**\n * Start Editor!\n *\n * @return {Promise}\n */\n start() {\n\n let prepareDecorator = module => module.prepare();\n\n return Promise.resolve()\n .then(prepareDecorator(this.moduleInstances.UI))\n .then(prepareDecorator(this.moduleInstances.Tools))\n\n .catch(function (error) {\n\n console.log('Error occured', error);\n\n });\n\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 : ['paragraph', 'header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'],\n// holderId : 'codex-editor',\n//\n// // Type of block showing on empty editor\n// initialBlockPlugin: 'paragraph'\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\n\n// WEBPACK FOOTER //\n// ./src/codex.js","var map = {\n\t\"./_anchors\": 3,\n\t\"./_anchors.js\": 3,\n\t\"./_callbacks\": 4,\n\t\"./_callbacks.js\": 4,\n\t\"./_caret\": 5,\n\t\"./_caret.js\": 5,\n\t\"./_content\": 6,\n\t\"./_content.js\": 6,\n\t\"./_destroyer\": 7,\n\t\"./_destroyer.js\": 7,\n\t\"./_listeners\": 8,\n\t\"./_listeners.js\": 8,\n\t\"./_notifications\": 9,\n\t\"./_notifications.js\": 9,\n\t\"./_parser\": 10,\n\t\"./_parser.js\": 10,\n\t\"./_paste\": 11,\n\t\"./_paste.js\": 11,\n\t\"./_renderer\": 12,\n\t\"./_renderer.js\": 12,\n\t\"./_sanitizer\": 13,\n\t\"./_sanitizer.js\": 13,\n\t\"./_saver\": 14,\n\t\"./_saver.js\": 14,\n\t\"./_transport\": 15,\n\t\"./_transport.js\": 15,\n\t\"./events\": 16,\n\t\"./events.js\": 16,\n\t\"./toolbar\": 17,\n\t\"./toolbar.js\": 17,\n\t\"./toolbar/inline\": 0,\n\t\"./toolbar/inline.js\": 0,\n\t\"./toolbar/settings\": 1,\n\t\"./toolbar/settings.js\": 1,\n\t\"./toolbar/toolbar\": 19,\n\t\"./toolbar/toolbar.js\": 19,\n\t\"./toolbar/toolbox\": 2,\n\t\"./toolbar/toolbox.js\": 2,\n\t\"./tools\": 20,\n\t\"./tools.js\": 20,\n\t\"./ui\": 21,\n\t\"./ui.js\": 21\n};\nfunction webpackContext(req) {\n\treturn __webpack_require__(webpackContextResolve(req));\n};\nfunction webpackContextResolve(req) {\n\tvar id = map[req];\n\tif(!(id + 1)) // check for number or string\n\t\tthrow new Error(\"Cannot find module '\" + req + \"'.\");\n\treturn id;\n};\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = 23;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/modules ^\\.\\/.*$\n// module id = 23\n// module chunks = 0","(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\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/html-janitor/src/html-janitor.js\n// module id = 24\n// module chunks = 0","/**\n * Codex Editor Util\n */\nmodule.exports = class Util {\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\n return new Promise(function (resolve, reject) {\n\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\n return previousValue\n .then(() => waitNextBlock(currentValue, success, fallback))\n .then(() => {\n\n // finished\n if (iteration == chains.length - 1) {\n\n resolve();\n\n }\n\n });\n\n }, Promise.resolve());\n\n });\n\n /**\n * Decorator\n *\n * @param {ChainData} chainData\n *\n * @param {Function} success\n * @param {Function} fallback\n *\n * @return {Promise}\n */\n function waitNextBlock(chainData, success, fallback) {\n\n return new Promise(function (resolve, reject) {\n\n chainData.function()\n .then(() => {\n\n success(chainData.data);\n\n })\n .then(resolve)\n .catch(function () {\n\n fallback(chainData.data);\n\n // anyway, go ahead even it falls\n resolve();\n\n });\n\n });\n\n }\n\n }\n\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/util.js","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \":root {\\n\\n /**\\n * Toolbar buttons\\n */\\n\\n}\\n/**\\n* Editor wrapper\\n*/\\n.codex-editor{\\n position: relative;\\n border: 1px solid #ccc;\\n padding: 10px;\\n}\\n.codex-editor .hide {\\n display: none;\\n }\\n\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/main.css\n// module id = 26\n// module chunks = 0","/*\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\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/css-loader/lib/css-base.js\n// module id = 27\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap 90f130a03cfb78ef2594","webpack:///./build/__tmp_babel_helpers.js","webpack:///./src/components/dom.js","webpack:///./src/codex.js","webpack:///./src/components/modules nonrecursive [^_](events.js|toolbar.js|tools.js|ui.js)$","webpack:///./src/components/modules/events.js","webpack:///./src/components/modules/toolbar.js","webpack:///./src/components/modules/tools.js","webpack:///./src/components/utils.js","webpack:///./src/components/modules/ui.js","webpack:///./src/styles/main.css","webpack:///./node_modules/css-loader/lib/css-base.js"],"names":["exports","createClass","defineProperties","target","props","i","length","descriptor","enumerable","configurable","writable","Object","defineProperty","key","Constructor","protoProps","staticProps","prototype","classCallCheck","instance","TypeError","module","tagName","classNames","attributes","el","document","createElement","Array","isArray","classList","add","attrName","parent","elements","forEach","appendChild","selector","querySelector","querySelectorAll","modules","editorModules","map","config","moduleInstances","Promise","resolve","then","configuration","init","start","console","log","catch","error","constructModules","configureModules","Module","displayName","e","name","state","getModulesDiff","diff","moduleName","prepareDecorator","prepare","UI","Tools","holderId","placeholder","sanitizer","p","b","a","hideToolbar","tools","toolsConfig","Events","Editor","subscribers","eventName","callback","push","data","reduce","previousData","currentHandler","newData","Toolbar","nodes","wrapper","content","actions","plusButton","toolbox","settingsToggler","removeBlockButton","settings","pluginSettings","defaultSettings","CSS","toolbar","$","make","append","makeRemoveBlockButton","makeBlockSettingsPanel","toolsAvailable","toolsUnavailable","iconClassName","displayInToolbox","enableLineBreaks","toolClasses","hasOwnProperty","reject","toolName","sequenceData","getListOfPrepareFunctions","_","sequence","success","fallback","toolPreparationList","toolClass","function","toolInstances","chains","previousValue","currentValue","iteration","waitNextBlock","chainData","successCallback","fallbackCallback","editorWrapper","editorZone","holder","redactor","getElementById","Error","loadStyles","styles","require","tag","textContent","toString","head"],"mappings":"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rDE,CAqDI,aAAK;;AAERF,gBAAQG,KAAR,CAAcK,CAAd;;AAEJ;AAEC,OA3DE,CAAP;AA6DH;;;iCAEY;;AAET;;;AAGA,UAAImF,SAAS,mBAAAC,CAAQ,CAAR,CAAb;;AAEA;;;AAGA,UAAIC,MAAMzC,EAAEC,IAAF,CAAO,OAAP,EAAgB,IAAhB,EAAsB;AAC5ByC,qBAAaH,OAAOI,QAAP;AADe,OAAtB,CAAV;;AAIA;;;AAGA3C,QAAEE,MAAF,CAAS/E,SAASyH,IAAlB,EAAwBH,GAAxB;AAEH;;;sBA/FSjE,M,EAAQ;;AAEd,WAAKA,MAAL,GAAcA,MAAd;AAEH;;;;;;;;;AA+FL1D,OAAOrB,OAAP,GAAiBmE,EAAjB;;AAGA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;;;;;;AC3bA;AACA;;;AAGA;AACA,gCAAiC,iDAAiD,2CAA2C,yBAAyB,6BAA6B,oBAAoB,GAAG,uBAAuB,wBAAwB,OAAO;;AAEhQ;;;;;;;ACPA;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","file":"codex-editor.js","sourcesContent":[" \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, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\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 \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 2);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 90f130a03cfb78ef2594","exports.createClass=function () {\n\n function defineProperties(target, props) {\n\n for(var i=0;i parent.appendChild(el) );\n\n } else {\n\n parent.appendChild(elements);\n\n }\n\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\n return el.querySelector(selector);\n\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\n return el.querySelectorAll(selector);\n\n }\n\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/dom.js","/**\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 : 'paragraph',\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 * ...\n */\n\n'use strict';\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 */\nmodule.exports = class CodexEditor {\n\n /** Editor version */\n static get version() {\n\n return VERSION;\n\n }\n\n /**\n * @param {EditorConfig} config - user configuration\n *\n */\n constructor(config) {\n\n /**\n * Configuration object\n */\n this.config = {};\n\n /**\n * Editor Components\n */\n this.moduleInstances = {};\n\n Promise.resolve()\n .then(() => {\n\n this.configuration = config;\n\n })\n .then(() => this.init())\n .then(() => this.start())\n .then(() => {\n\n console.log('CodeX Editor is ready');\n\n })\n .catch(error => {\n\n console.log('CodeX Editor does not ready beecause of %o', error);\n\n });\n\n }\n\n /**\n * Setting for configuration\n * @param {Object} config\n */\n set configuration(config = {}) {\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\n }\n\n /**\n * Returns private property\n * @returns {{}|*}\n */\n get configuration() {\n\n return this.config;\n\n }\n\n /**\n * Initializes modules:\n * - make and save instances\n * - configure\n */\n init() {\n\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 /**\n * Make modules instances and save it to the @property this.moduleInstances\n */\n constructModules() {\n\n modules.forEach( Module => {\n\n try {\n\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\n this.moduleInstances[Module.displayName] = new Module({\n config : this.configuration\n });\n\n } catch ( e ) {\n\n console.log('Module %o skipped because %o', Module, e);\n\n }\n\n });\n\n }\n\n /**\n * Modules instances configuration:\n * - pass other modules to the 'state' property\n * - ...\n */\n configureModules() {\n\n for(let name in this.moduleInstances) {\n\n /**\n * Module does not need self-instance\n */\n this.moduleInstances[name].state = this.getModulesDiff( name );\n\n }\n\n }\n\n /**\n * Return modules without passed name\n */\n getModulesDiff( name ) {\n\n let diff = {};\n\n for(let moduleName in this.moduleInstances) {\n\n /**\n * Skip module with passed name\n */\n if (moduleName === name) {\n\n continue;\n\n }\n diff[moduleName] = this.moduleInstances[moduleName];\n\n }\n\n return diff;\n\n }\n\n /**\n * Start Editor!\n *\n * @return {Promise}\n */\n start() {\n\n let prepareDecorator = module => module.prepare();\n\n return Promise.resolve()\n .then(prepareDecorator(this.moduleInstances.UI))\n .then(prepareDecorator(this.moduleInstances.Tools))\n\n .catch(function (error) {\n\n console.log('Error occured', error);\n\n });\n\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 : ['paragraph', 'header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'],\n// holderId : 'codex-editor',\n//\n// // Type of block showing on empty editor\n// initialBlockPlugin: 'paragraph'\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\n\n// WEBPACK FOOTER //\n// ./src/codex.js","var map = {\n\t\"./events.js\": 4,\n\t\"./toolbar.js\": 5,\n\t\"./tools.js\": 6,\n\t\"./ui.js\": 8\n};\nfunction webpackContext(req) {\n\treturn __webpack_require__(webpackContextResolve(req));\n};\nfunction webpackContextResolve(req) {\n\tvar id = map[req];\n\tif(!(id + 1)) // check for number or string\n\t\tthrow new Error(\"Cannot find module '\" + req + \"'.\");\n\treturn id;\n};\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = 3;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/modules nonrecursive [^_](events.js|toolbar.js|tools.js|ui.js)$\n// module id = 3\n// module chunks = 0","/**\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 *\n * @version 1.0.0\n */\nclass Events {\n\n /**\n * @param Editor\n * @param Editor.modules {@link CodexEditor#moduleInstances}\n * @param Editor.config {@link CodexEditor#configuration}\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * @constructor\n *\n * @property {Object} subscribers - all subscribers grouped by event name\n */\n constructor() {\n\n this.subscribers = {};\n this.Editor = null;\n\n }\n\n /**\n * @param {String} eventName - event name\n * @param {Function} callback - subscriber\n */\n on(eventName, callback) {\n\n if (!(eventName in this.subscribers)) {\n\n this.subscribers[eventName] = [];\n\n }\n\n // group by events\n this.subscribers[eventName].push(callback);\n\n }\n\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\n this.subscribers[eventName].reduce(function (previousData, currentHandler) {\n\n let newData = currentHandler(previousData);\n\n return newData ? newData : previousData;\n\n }, data);\n\n }\n\n /**\n * Destroyer\n */\n destroy() {\n\n this.Editor = null;\n this.subscribers = null;\n\n }\n\n}\n\nmodule.exports = Events;\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/events.js","/**\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] [Remove Block] . |\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 * @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.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.removeBlockButton - Remove Block 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 */\nclass Toolbar {\n\n /**\n * @constructor\n */\n constructor() {\n\n this.Editor = null;\n\n this.nodes = {\n wrapper : null,\n content : null,\n actions : null,\n\n // Content Zone\n plusButton : null,\n toolbox : null,\n\n // Actions Zone\n settingsToggler : null,\n removeBlockButton: null,\n settings: null,\n\n // Settings Zone: Plugin Settings and Default Settings\n pluginSettings: null,\n defaultSettings: null,\n };\n\n this.CSS = {\n toolbar: 'ce-toolbar',\n content: 'ce-toolbar__content',\n actions: 'ce-toolbar__actions',\n\n // Content Zone\n toolbox: 'ce-toolbar__toolbox',\n plusButton: 'ce-toolbar__plus',\n\n // Actions Zone\n settingsToggler: 'ce-toolbar__settings-btn',\n removeBlockButton: 'ce-toolbar__remove-btn',\n\n // Settings Panel\n settings: 'ce-settings',\n defaultSettings: 'ce-settings_default',\n pluginSettings: 'ce-settings_plugin',\n };\n\n }\n\n /**\n * Editor modules setter\n * @param {object} Editor - available editor modules\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * Makes toolbar\n */\n make() {\n\n this.nodes.wrapper = $.make('div', this.CSS.toolbar);\n\n /**\n * Make Content Zone and Actions Zone\n */\n ['content', 'actions'].forEach( el => {\n\n this.nodes[el] = $.make('div', this.CSS[el]);\n $.append(this.nodes.wrapper, this.nodes[el]);\n\n });\n\n\n /**\n * Fill Content Zone:\n * - Plus Button\n * - Toolbox\n */\n ['plusButton', 'toolbox'].forEach( el => {\n\n this.nodes[el] = $.make('div', this.CSS[el]);\n $.append(this.nodes.content, this.nodes[el]);\n\n });\n\n /**\n * Fill Actions Zone:\n * - Settings Toggler\n * - Remove Block Button\n * - Settings Panel\n */\n this.nodes.settingsToggler = $.make('span', this.CSS.settingsToggler);\n this.nodes.removeBlockButton = this.makeRemoveBlockButton();\n\n $.append(this.nodes.actions, [this.nodes.settingsToggler, this.nodes.removeBlockButton]);\n\n /**\n * Make and append Settings Panel\n */\n this.makeBlockSettingsPanel();\n\n /**\n * Append toolbar to the Editor\n */\n $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\n\n }\n\n /**\n * Panel with block settings with 2 sections:\n *\n * @return {Element}\n */\n makeBlockSettingsPanel() {\n\n this.nodes.settings = $.make('div', this.CSS.settings);\n\n this.nodes.pluginSettings = $.make('div', this.CSS.pluginSettings);\n this.nodes.defaultSettings = $.make('div', this.CSS.defaultSettings);\n\n $.append(this.nodes.settings, [this.nodes.pluginSettings, this.nodes.defaultSettings]);\n $.append(this.nodes.actions, this.nodes.settings);\n\n }\n\n /**\n * Makes Remove Block button, and confirmation panel\n * @return {Element} wrapper with button and panel\n */\n makeRemoveBlockButton() {\n\n /**\n * @todo add confirmation panel and handlers\n * @see {@link settings#makeRemoveBlockButton}\n */\n return $.make('span', this.CSS.removeBlockButton);\n\n }\n\n}\n\nmodule.exports = Toolbar;\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/toolbar.js","/**\n * @module Codex Editor Tools Submodule\n *\n * Creates Instances from Plugins and binds external config to the instances\n */\n\n/**\n * Load user defined tools\n * Tools must contain the following important objects:\n *\n * @typedef {Object} ToolsConfig\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 */\n\n/**\n * @typedef {Object} Tool\n * @property render\n * @property save\n * @property settings\n * @property validate\n */\n\n/**\n * Class properties:\n *\n * @property {String} name - name of this module\n * @property {Object[]} toolInstances - list of tool instances\n * @property {Tools[]} available - available Tools\n * @property {Tools[]} unavailable - unavailable Tools\n * @property {Object} toolsClasses - all classes\n * @property {EditorConfig} config - Editor config\n */\n\nclass Tools {\n\n /**\n * Returns available Tools\n * @return {Tool[]}\n */\n get available() {\n\n return this.toolsAvailable;\n\n }\n\n /**\n * Returns unavailable Tools\n * @return {Tool[]}\n */\n get unavailable() {\n\n return this.toolsUnavailable;\n\n }\n\n /**\n * @param Editor\n * @param Editor.modules {@link CodexEditor#moduleInstances}\n * @param Editor.config {@link CodexEditor#configuration}\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * If config wasn't passed by user\n * @return {ToolsConfig}\n */\n get defaultConfig() {\n\n return {\n iconClassName : 'default-icon',\n displayInToolbox : false,\n enableLineBreaks : false\n };\n\n }\n\n /**\n * @constructor\n *\n * @param {ToolsConfig} config\n */\n constructor({ config }) {\n\n this.config = config;\n\n this.toolClasses = {};\n this.toolsAvailable = {};\n this.toolsUnavailable = {};\n\n }\n\n /**\n * Creates instances via passed or default configuration\n * @return {boolean}\n */\n prepare() {\n\n if (!this.config.hasOwnProperty('tools')) {\n\n return Promise.reject(\"Can't start without tools\");\n\n }\n\n for(let toolName in this.config.tools) {\n\n this.toolClasses[toolName] = this.config.tools[toolName];\n\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\n return Promise.resolve();\n\n }\n\n /**\n * to see how it works {@link Util#sequence}\n */\n return _.sequence(sequenceData, (data) => {\n\n this.success(data);\n\n }, (data) => {\n\n this.fallback(data);\n\n });\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 sequently\n */\n getListOfPrepareFunctions() {\n\n let toolPreparationList = [];\n\n for(let toolName in this.toolClasses) {\n\n let toolClass = this.toolClasses[toolName];\n\n if (typeof toolClass.prepare === 'function') {\n\n toolPreparationList.push({\n function : toolClass.prepare,\n data : {\n toolName\n }\n });\n\n }\n\n }\n\n return toolPreparationList;\n\n }\n\n /**\n * @param {ChainData.data} data - append tool to available list\n */\n success(data) {\n\n this.toolsAvailable[data.toolName] = this.toolClasses[data.toolName];\n\n }\n\n /**\n * @param {ChainData.data} data - append tool to unavailable list\n */\n fallback(data) {\n\n this.toolsUnavailable[data.toolName] = this.toolClasses[data.toolName];\n\n }\n\n /**\n * Returns all tools\n * @return {Array}\n */\n getTools() {\n\n return this.toolInstances;\n\n }\n\n}\n\nmodule.exports = Tools;\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/tools.js","/**\n * Codex Editor Util\n */\nmodule.exports = class Util {\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\n return new Promise(function (resolve) {\n\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\n return previousValue\n .then(() => waitNextBlock(currentValue, success, fallback))\n .then(() => {\n\n // finished\n if (iteration === chains.length - 1) {\n\n resolve();\n\n }\n\n });\n\n }, Promise.resolve());\n\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\n return new Promise(function (resolve) {\n\n chainData.function()\n .then(() => {\n\n successCallback(chainData.data);\n\n })\n .then(resolve)\n .catch(function () {\n\n fallbackCallback(chainData.data);\n\n // anyway, go ahead even it falls\n resolve();\n\n });\n\n });\n\n }\n\n }\n\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/utils.js","/**\n * Module UI\n *\n * @type {UI}\n */\n// let className = {\n\n/**\n * @const {string} BLOCK_CLASSNAME - redactor blocks name\n */\n// BLOCK_CLASSNAME : 'ce-block',\n\n/**\n * @const {String} wrapper for plugins content\n */\n// BLOCK_CONTENT : 'ce-block__content',\n\n/**\n * @const {String} BLOCK_STRETCHED - makes block stretched\n */\n// BLOCK_STRETCHED : 'ce-block--stretched',\n\n/**\n * @const {String} BLOCK_HIGHLIGHTED - adds background\n */\n// BLOCK_HIGHLIGHTED : 'ce-block--focused',\n\n/**\n * @const {String} - for all default settings\n */\n// SETTINGS_ITEM : 'ce-settings__item'\n// };\n\nlet CSS = {\n editorWrapper : 'codex-editor',\n editorZone : 'ce-redactor'\n};\n\n/**\n * @class\n *\n * @classdesc Makes CodeX Editor UI:\n * \n * \n * \n * \n * \n *\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.wrapper - element where we need to append redactor\n * @property {Element} nodes.wrapper - \n * @property {Element} nodes.redactor - \n */\nclass UI {\n\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor({ config }) {\n\n this.config = config;\n this.Editor = null;\n\n this.nodes = {\n holder: null,\n wrapper: null,\n redactor: null\n };\n\n }\n\n\n /**\n * Editor modules setter\n * @param {object} Editor - available editor modules\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * @protected\n *\n * Making main interface\n */\n prepare() {\n\n return new Promise( (resolve, reject) => {\n\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\n reject(Error(\"Holder wasn't found by ID: #\" + this.config.holderId));\n return;\n\n }\n\n /**\n * Create and save main UI elements\n */\n this.nodes.wrapper = $.make('div', CSS.editorWrapper);\n this.nodes.redactor = $.make('div', CSS.editorZone);\n\n this.nodes.wrapper.appendChild(this.nodes.redactor);\n this.nodes.holder.appendChild(this.nodes.wrapper);\n\n /**\n * Make toolbar\n */\n this.Editor.Toolbar.make();\n\n /**\n * Load and append CSS\n */\n this.loadStyles();\n\n resolve();\n\n })\n\n /** Add toolbox tools */\n // .then(addTools_)\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\n console.error(e);\n\n // editor.core.log(\"Can't draw editor interface\");\n\n });\n\n }\n\n loadStyles() {\n\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}\n\nmodule.exports = UI;\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// * @private\n// * Append tools passed in editor.tools\n// */\n// var addTools_ = function () {\n//\n// var tool,\n// toolName,\n// toolButton;\n//\n// for ( toolName in editor.settings.tools ) {\n//\n// tool = editor.settings.tools[toolName];\n//\n// editor.tools[toolName] = tool;\n//\n// if (!tool.iconClassname && tool.displayInToolbox) {\n//\n// editor.core.log('Toolbar icon classname missed. Tool %o skipped', 'warn', toolName);\n// continue;\n//\n// }\n//\n// if (typeof tool.render != 'function') {\n//\n// editor.core.log('render method missed. Tool %o skipped', 'warn', toolName);\n// continue;\n//\n// }\n//\n// if (!tool.displayInToolbox) {\n//\n// continue;\n//\n// } else {\n//\n// /** if tools is for toolbox */\n// toolButton = editor.draw.toolbarButton(toolName, tool.iconClassname);\n//\n// editor.nodes.toolbox.appendChild(toolButton);\n//\n// editor.nodes.toolbarButtons[toolName] = toolButton;\n//\n// }\n//\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\n\n// WEBPACK FOOTER //\n// ./src/components/modules/ui.js","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(undefined);\n// imports\n\n\n// module\nexports.push([module.id, \":root {\\n\\n /**\\n * Toolbar buttons\\n */\\n\\n}\\n/**\\n* Editor wrapper\\n*/\\n.codex-editor{\\n position: relative;\\n border: 1px solid #ccc;\\n padding: 10px;\\n}\\n.codex-editor .hide {\\n display: none;\\n }\\n\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/main.css\n// module id = 9\n// module chunks = 0","/*\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\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/css-loader/lib/css-base.js\n// module id = 10\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file diff --git a/example/example.html b/example/example.html index 6c7fc294..e01f5ad6 100644 --- a/example/example.html +++ b/example/example.html @@ -54,7 +54,6 @@ -